Reflect environment values to config struct
go get github.com/hjhsamuel/goenvSupport type:
stringboolintint8int16int32int64uintuint8uint16uint32uint64float32float64complex64complex128pointerstructslicemap
Support tags:
requireddefaultinline-nameltandltegtandgte
The default config like:
type ServerConfig struct {
ID uint `env:"ID"`
Port int `env:"PORT;gte:1000;lte:60000"`
MultiServer bool `env:"MULTISERVER"`
Peers map[int]string `env:"PEERS"`
IDs []int `env:IDS`
}
type LogConfig struct {
Level string `env:"LEVEL;default:debug"`
Path *string `env:"PATH"`
}
type IPAddress struct {
IP string `env:"name:IP"`
Gateway string `env:"name:GATEWAY"`
}
type IPv4 struct {
IPAddress `env:inline`
}
type Config struct {
ProjectName string `env:"PROJNAME;required"`
ProjectID int64 `env:"PROJID;default:1"`
Server *ServerConfig `env:"SERVER"`
Log LogConfig `env:"LOG"`
Address IPv4 `env:"name:IPV4"`
}So, an environment value could be found like ENV_PROJNAME
Some function could be called to set the custom tag:
-
SetPrefixorWithPrefixthe default prefix is
ENV -
SetSplitCharorWithSplitCharthe default split char is
_ -
SetTagorWithTagthe default tag name is
env
We could parse config struct like:
ENV_PROJNAME=goenv
ENV_SERVER_PEERS="1:127.0.0.1:8000|2:127.0.0.1:8001"
ENV_SERVER_PORT=8000
ENV_SERVER_MULTISERVER=true
ENV_SERVER_IDS="1,2"c := &Config{ProjectName: "goenv"}
parser := NewEnvParser()
if err := parser.Start(&c); err != nil {
log.Fatal(err)
}You can use your own function to format fields by implement the UnmarshalText interface
type Node struct {
ID int
Addr net.Addr
}
func (n *Node) UnmarshalText(text []byte) error {
l := bytes.Split(text, []byte("="))
if len(l) != 2 {
return errors.New("invalid node format")
}
if id, err := strconv.Atoi(string(l[0])); err != nil {
return err
} else {
n.ID = id
}
if host, port, err := net.SplitHostPort(string(l[1])); err != nil {
return err
} else {
iport, err := strconv.Atoi(port)
if err != nil {
return err
}
n.Addr = &net.TCPAddr{IP: net.ParseIP(host), Port: iport}
}
return nil
}
type Config struct {
Node Node `env:"NODE"`
}ENV_NODE="1=127.0.0.1:8000"In environment variables, map and slice are treated as special values. Therefore, when a defined map or slice is nested within other complex data types (such as struct, map, or slice), it may fail to be parsed correctly. In such cases, you need to explicitly implement the UnmarshalText interface to handle the mapping yourself.