complete rewrite

This commit is contained in:
Timon Ringwald 2022-08-25 10:18:22 +02:00
parent 45660f4ff6
commit a476080474
5 changed files with 209 additions and 254 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.env

89
converters.go Normal file
View File

@ -0,0 +1,89 @@
package envvars
import (
"errors"
"strconv"
"unicode/utf8"
)
func ConvertString(s string) (string, error) {
return s, nil
}
func ConvertRune(s string) (rune, error) {
rn, _ := utf8.DecodeRuneInString(s)
if rn == utf8.RuneError {
return 0, errors.New("rune decoding failed")
}
return rn, nil
}
func ConvertInt64(s string) (int64, error) {
return strconv.ParseInt(s, 10, 64)
}
func ConvertInt32(s string) (int32, error) {
v, err := strconv.ParseInt(s, 10, 32)
return int32(v), err
}
func ConvertInt16(s string) (int16, error) {
v, err := strconv.ParseInt(s, 10, 16)
return int16(v), err
}
func ConvertInt8(s string) (int8, error) {
v, err := strconv.ParseInt(s, 10, 8)
return int8(v), err
}
func ConvertInt(s string) (int, error) {
v, err := strconv.ParseInt(s, 10, 64)
return int(v), err
}
func ConvertUint64(s string) (uint64, error) {
return strconv.ParseUint(s, 10, 64)
}
func ConvertUint32(s string) (uint32, error) {
v, err := strconv.ParseUint(s, 10, 32)
return uint32(v), err
}
func ConvertUint16(s string) (uint16, error) {
v, err := strconv.ParseUint(s, 10, 16)
return uint16(v), err
}
func ConvertUint8(s string) (uint8, error) {
v, err := strconv.ParseUint(s, 10, 8)
return uint8(v), err
}
func ConvertUint(s string) (uint, error) {
v, err := strconv.ParseUint(s, 10, 64)
return uint(v), err
}
func ConvertFloat64(s string) (float64, error) {
return strconv.ParseFloat(s, 64)
}
func ConvertFloat32(s string) (float32, error) {
v, err := strconv.ParseFloat(s, 32)
return float32(v), err
}
func ConvertComplex128(s string) (complex128, error) {
return strconv.ParseComplex(s, 128)
}
func ConvertComplex64(s string) (complex64, error) {
v, err := strconv.ParseComplex(s, 64)
return complex64(v), err
}
func ConvertBool(s string) (bool, error) {
return strconv.ParseBool(s)
}

34
object.go Normal file
View File

@ -0,0 +1,34 @@
package envvars
import (
"os"
"strings"
)
func Object[T any](key string, defaultValue T, converter func(string) (T, error)) T {
if v, ok := os.LookupEnv(key); ok {
if v2, err := converter(v); err == nil {
return v2
}
}
return defaultValue
}
func ObjectSlice[T any](key, sep string, defaultValue []T, converter func(string) (T, error)) []T {
return Object(key, defaultValue, func(s string) ([]T, error) {
if s == "" {
return []T{}, nil
}
splits := strings.Split(s, sep)
values := make([]T, 0, len(splits))
for _, s := range splits {
v, err := converter(s)
if err != nil {
return values, err
}
values = append(values, v)
}
return values, nil
})
}

173
slices.go
View File

@ -1,172 +1,79 @@
package envvars
import (
"os"
"strconv"
"strings"
)
import "time"
func StringSlice(key, sep string) []string {
if v, ok := os.LookupEnv(key); ok && strings.TrimSpace(v) != "" {
return strings.Split(v, sep)
}
return []string{}
func StringSlice(key, sep string, defaultValue []string) []string {
return ObjectSlice(key, sep, defaultValue, ConvertString)
}
func ByteSlice(key, sep string) []byte {
return []byte(String(key, ""))
func ByteSlice(key, sep string, defaultValue []byte) []byte {
return Uint8Slice(key, sep, defaultValue)
}
func RuneSlice(key, sep string) []rune {
return []rune(String(key, ""))
func RuneSlice(key, sep string, defaultValue []rune) []rune {
return ObjectSlice(key, sep, defaultValue, ConvertRune)
}
func IntSlice(key, sep string) []int {
res := make([]int, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseInt(s, 10, 64); err == nil {
res = append(res, int(v))
}
}
return res
func IntSlice(key, sep string, defaultValue []int) []int {
return ObjectSlice(key, sep, defaultValue, ConvertInt)
}
func Int8Slice(key, sep string) []int8 {
res := make([]int8, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseInt(s, 10, 64); err == nil {
res = append(res, int8(v))
}
}
return res
func Int8Slice(key, sep string, defaultValue []int8) []int8 {
return ObjectSlice(key, sep, defaultValue, ConvertInt8)
}
func Int16Slice(key, sep string) []int16 {
res := make([]int16, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseInt(s, 10, 64); err == nil {
res = append(res, int16(v))
}
}
return res
func Int16Slice(key, sep string, defaultValue []int16) []int16 {
return ObjectSlice(key, sep, defaultValue, ConvertInt16)
}
func Int32Slice(key, sep string) []int32 {
res := make([]int32, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseInt(s, 10, 64); err == nil {
res = append(res, int32(v))
}
}
return res
func Int32Slice(key, sep string, defaultValue []int32) []int32 {
return ObjectSlice(key, sep, defaultValue, ConvertInt32)
}
func Int64Slice(key, sep string) []int64 {
res := make([]int64, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseInt(s, 10, 64); err == nil {
res = append(res, v)
}
}
return res
func Int64Slice(key, sep string, defaultValue []int64) []int64 {
return ObjectSlice(key, sep, defaultValue, ConvertInt64)
}
func Uint8Slice(key, sep string) []uint8 {
res := make([]uint8, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseUint(s, 10, 64); err == nil {
res = append(res, uint8(v))
}
}
return res
func Uint8Slice(key, sep string, defaultValue []uint8) []uint8 {
return ObjectSlice(key, sep, defaultValue, ConvertUint8)
}
func Uint16Slice(key, sep string) []uint16 {
res := make([]uint16, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseUint(s, 10, 64); err == nil {
res = append(res, uint16(v))
}
}
return res
func Uint16Slice(key, sep string, defaultValue []uint16) []uint16 {
return ObjectSlice(key, sep, defaultValue, ConvertUint16)
}
func Uint32Slice(key, sep string) []uint32 {
res := make([]uint32, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseUint(s, 10, 64); err == nil {
res = append(res, uint32(v))
}
}
return res
func Uint32Slice(key, sep string, defaultValue []uint32) []uint32 {
return ObjectSlice(key, sep, defaultValue, ConvertUint32)
}
func Uint64Slice(key, sep string) []uint64 {
res := make([]uint64, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseUint(s, 10, 64); err == nil {
res = append(res, v)
}
}
return res
func Uint64Slice(key, sep string, defaultValue []uint64) []uint64 {
return ObjectSlice(key, sep, defaultValue, ConvertUint64)
}
func Float32Slice(key, sep string) []float32 {
res := make([]float32, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseFloat(s, 64); err == nil {
res = append(res, float32(v))
}
}
return res
func Float32Slice(key, sep string, defaultValue []float32) []float32 {
return ObjectSlice(key, sep, defaultValue, ConvertFloat32)
}
func Float64Slice(key, sep string) []float64 {
res := make([]float64, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseFloat(s, 64); err == nil {
res = append(res, v)
}
}
return res
func Float64Slice(key, sep string, defaultValue []float64) []float64 {
return ObjectSlice(key, sep, defaultValue, ConvertFloat64)
}
func Complex64Slice(key, sep string) []complex64 {
res := make([]complex64, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseComplex(s, 64); err == nil {
res = append(res, complex64(v))
}
}
return res
func Complex64Slice(key, sep string, defaultValue []complex64) []complex64 {
return ObjectSlice(key, sep, defaultValue, ConvertComplex64)
}
func Complex128Slice(key, sep string) []complex128 {
res := make([]complex128, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseComplex(s, 64); err == nil {
res = append(res, v)
}
}
return res
func Complex128Slice(key, sep string, defaultValue []complex128) []complex128 {
return ObjectSlice(key, sep, defaultValue, ConvertComplex128)
}
func BoolSlice(key, sep string) []bool {
res := make([]bool, 0)
for _, s := range StringSlice(key, sep) {
if v, err := strconv.ParseBool(s); err == nil {
res = append(res, v)
}
}
return res
func BoolSlice(key, sep string, defaultValue []bool) []bool {
return ObjectSlice(key, sep, defaultValue, ConvertBool)
}
func ObjectSlice[T any](key, sep string, converter func(string) (T, error)) []T {
res := make([]T, 0)
for _, s := range StringSlice(key, sep) {
if v, err := converter(s); err == nil {
res = append(res, v)
func TimeSlice(key, sep string, defaultValue []time.Time, layout string) []time.Time {
return ObjectSlice(key, sep, defaultValue, func(s string) (time.Time, error) { return time.Parse(layout, s) })
}
}
return res
func DurationSlice(key, sep string, defaultValue []time.Duration) []time.Duration {
return ObjectSlice(key, sep, defaultValue, time.ParseDuration)
}

154
vars.go
View File

@ -1,15 +1,9 @@
package envvars
import (
"os"
"strconv"
)
import "time"
func String(key, defaultValue string) string {
if v, ok := os.LookupEnv(key); ok {
return v
}
return defaultValue
return Object(key, defaultValue, ConvertString)
}
func Byte(key string, defaultValue byte) byte {
@ -17,143 +11,73 @@ func Byte(key string, defaultValue byte) byte {
}
func Rune(key string, defaultValue rune) rune {
for _, rn := range String(key, string(defaultValue)) {
return rn
}
return defaultValue
}
func Int(key string, defaultValue int) int {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseInt(v, 10, 64); err == nil {
return int(v2)
}
}
return defaultValue
}
func Int8(key string, defaultValue int8) int8 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseInt(v, 10, 64); err == nil {
return int8(v2)
}
}
return defaultValue
}
func Int16(key string, defaultValue int16) int16 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseInt(v, 10, 64); err == nil {
return int16(v2)
}
}
return defaultValue
}
func Int32(key string, defaultValue int32) int32 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseInt(v, 10, 64); err == nil {
return int32(v2)
}
}
return defaultValue
return Object(key, defaultValue, ConvertRune)
}
func Int64(key string, defaultValue int64) int64 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseInt(v, 10, 64); err == nil {
return v2
}
}
return defaultValue
return Object(key, defaultValue, ConvertInt64)
}
func Uint8(key string, defaultValue uint8) uint8 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseUint(v, 10, 64); err == nil {
return uint8(v2)
}
}
return defaultValue
func Int32(key string, defaultValue int32) int32 {
return Object(key, defaultValue, ConvertInt32)
}
func Uint16(key string, defaultValue uint16) uint16 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseUint(v, 10, 64); err == nil {
return uint16(v2)
}
}
return defaultValue
func Int16(key string, defaultValue int16) int16 {
return Object(key, defaultValue, ConvertInt16)
}
func Uint32(key string, defaultValue uint32) uint32 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseUint(v, 10, 64); err == nil {
return uint32(v2)
func Int8(key string, defaultValue int8) int8 {
return Object(key, defaultValue, ConvertInt8)
}
}
return defaultValue
func Int(key string, defaultValue int) int {
return Object(key, defaultValue, ConvertInt)
}
func Uint64(key string, defaultValue uint64) uint64 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseUint(v, 10, 64); err == nil {
return v2
}
}
return defaultValue
return Object(key, defaultValue, ConvertUint64)
}
func Float32(key string, defaultValue float32) float32 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseFloat(v, 64); err == nil {
return float32(v2)
func Uint32(key string, defaultValue uint32) uint32 {
return Object(key, defaultValue, ConvertUint32)
}
func Uint16(key string, defaultValue uint16) uint16 {
return Object(key, defaultValue, ConvertUint16)
}
return defaultValue
func Uint8(key string, defaultValue uint8) uint8 {
return Object(key, defaultValue, ConvertUint8)
}
func Uint(key string, defaultValue uint) uint {
return Object(key, defaultValue, ConvertUint)
}
func Float64(key string, defaultValue float64) float64 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseFloat(v, 64); err == nil {
return v2
}
}
return defaultValue
return Object(key, defaultValue, ConvertFloat64)
}
func Complex64(key string, defaultValue complex64) complex64 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseComplex(v, 64); err == nil {
return complex64(v2)
}
}
return defaultValue
func Float32(key string, defaultValue float32) float32 {
return Object(key, defaultValue, ConvertFloat32)
}
func Complex128(key string, defaultValue complex128) complex128 {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseComplex(v, 64); err == nil {
return v2
return Object(key, defaultValue, ConvertComplex128)
}
}
return defaultValue
func Complex64(key string, defaultValue complex64) complex64 {
return Object(key, defaultValue, ConvertComplex64)
}
func Bool(key string, defaultValue bool) bool {
if v, ok := os.LookupEnv(key); ok {
if v2, err := strconv.ParseBool(v); err == nil {
return v2
}
}
return defaultValue
return Object(key, defaultValue, ConvertBool)
}
func Object[T any](key string, defaultValue T, converter func(string) (T, error)) T {
if v, ok := os.LookupEnv(key); ok {
if v2, err := converter(v); err == nil {
return v2
func Time(key string, defaultValue time.Time, layout string) time.Time {
return Object(key, defaultValue, func(s string) (time.Time, error) { return time.Parse(layout, s) })
}
}
return defaultValue
func Duration(key string, defaultValue time.Duration) time.Duration {
return Object(key, defaultValue, time.ParseDuration)
}