-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenvvariable.go
64 lines (49 loc) · 1.49 KB
/
envvariable.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package config
import (
"reflect"
"strconv"
"strings"
"encoding/json"
)
// envVariable represents an environment variable.
type EnvVariable[T any] string
// Get returns the value of the environment variable.
func (e EnvVariable[T]) Get() (result T) {
parse := func(raw string) (result T) {
if len(raw) == 0 {
return
}
target := reflect.ValueOf(&result).Elem()
switch target.Kind() {
case reflect.Bool:
v, _ := strconv.ParseBool(raw)
target.Set(reflect.ValueOf(v))
return target.Interface().(T)
case reflect.Float32, reflect.Float64:
v, _ := strconv.ParseFloat(raw, 64)
target.Set(reflect.ValueOf(v).Convert(target.Type()))
return target.Interface().(T)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
v, _ := strconv.ParseInt(raw, 10, 64)
target.Set(reflect.ValueOf(v).Convert(target.Type()))
return target.Interface().(T)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
v, _ := strconv.ParseUint(raw, 10, 64)
target.Set(reflect.ValueOf(v).Convert(target.Type()))
return target.Interface().(T)
case reflect.Map, reflect.Slice, reflect.Array, reflect.Struct:
_ = json.Unmarshal([]byte(raw), target.Addr().Interface())
return target.Interface().(T)
case reflect.String:
return any(raw).(T)
default:
return
}
}
key, fallback, _ := strings.Cut(string(e), ":")
raw := Getenv(key)
if len(raw) == 0 && len(fallback) > 0 {
return parse(fallback)
}
return parse(raw)
}