go_sysutils/funcs.go

209 lines
3.8 KiB
Go

package sysutils
import (
`os`
`runtime`
`strconv`
`strings`
)
/*
EnvMapper contains the environment variables as grouped by their basic type.
If a variable's type cannot be determined, it's placed in Strings.
If a variable's type is a list, it will be an []interface{} as each item may be a different variable type.
It essentially is the same as EnvMap except with the types split out for convenience.
*/
type EnvMapper struct {
Booleans map[string]bool `json:"bools"`
Numbers map[string]int `json:"nums"`
Strings map[string]string `json:"strings"`
Lists map[string][]interface{} `json:"lists"`
}
// GetEnvMapper returns a pointer to a populated EnvMapper.
func GetEnvMapper() (e *EnvMapper, err error) {
var em map[string]interface{}
var env EnvMapper
env = EnvMapper{
Booleans: nil,
Numbers: nil,
Strings: nil,
Lists: nil,
}
for k, v := range em {
switch t := v.(type) {
case bool:
if env.Booleans == nil {
env.Booleans = make(map[string]bool, 0)
}
env.Booleans[k] = t
continue
case int:
if env.Numbers == nil {
env.Numbers = make(map[string]int, 0)
}
env.Numbers[k] = t
continue
case []interface{}:
if env.Lists == nil {
env.Lists = make(map[string][]interface{}, 0)
}
env.Lists[k] = t
case string: // the "default" since everything could probably be typeswitched to a string otherwise.
if env.Strings == nil {
env.Strings = make(map[string]string, 0)
}
env.Strings[k] = t
}
}
*e = env
return
}
/*
EnvMap returns a map of environment variables.
The variable is an interface due to it attempting to use a variable's value to its "true" native type.
If a type cannot be determined, it will be treated a string.
*/
func EnvMap() (envs map[string]interface{}, err error) {
var ems map[string]string
if ems, err = EnvMapString(); err != nil {
return
}
for k, v := range ems {
// Is int?
if i, ok := getNum(v); ok {
envs[k] = i
continue
}
// Is bool?
if b, ok := getBool(v); ok {
envs[k] = b
continue
}
// Is array?
if a, ok := getArr(v); ok {
envs[k] = a
continue
}
// It's a string (probably).
envs[k] = v
}
return
}
// EnvMapString is like EnvMap, but all values are treated as strings.
func EnvMapString() (envs map[string]string, err error) {
var envArray []string
envs = make(map[string]string, 0)
envArray = os.Environ()
for _, e := range envArray {
var k, v string
var kv []string
kv = strings.SplitN(e, "=", 2)
k = kv[0]
if len(kv) == 2 {
v = kv[1]
} else {
v = ""
}
envs[k] = v
}
return
}
// UTILITY FUNCS
// getBool attempts to convert a string value to a boolean.
func getBool(s string) (b bool, ok bool) {
switch s2 := strings.ToLower(strings.TrimSpace(s)); s2 {
case "true", "yes", "y":
b = true
ok = true
case "false", "no", "n":
b = false
ok = true
}
return
}
// getNum attempts to convert a string value to an int.
func getNum(s string) (n int, ok bool) {
var err error
if n, err = strconv.Atoi(s); err == nil {
ok = true
}
return
}
// getArr attempts to convert a string value to an array of interface{}.
func getArr(s string) (a []interface{}, ok bool) {
var arrS []string
if arrS, ok = getArrStr(s); !ok {
return
}
a = make([]interface{}, len(arrS))
for idx, i := range arrS {
if b, ok := getBool(i); ok {
a[idx] = b
} else if n, ok := getNum(i); ok {
a[idx] = n
} else if l, ok := getArr(i); ok {
a[idx] = l
} else {
a[idx] = i
}
}
return
}
// getArrStr attempts to convert a string value to an array of strings.
func getArrStr(s string) (a []string, ok bool) {
var sep string = ":"
if runtime.GOOS == "windows" {
sep = ";"
}
a = strings.Split(s, sep)
l := len(s)
if l <= 1 {
return
}
ok = true
return
}