From c502b0d5e069d822b6c450736a479ef68644b1e4 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 17 Mar 2025 17:05:07 -0400 Subject: [PATCH] Add a function to walk a config and return the requested value. --- config.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/config.go b/config.go index 297a1db..5efb1dc 100644 --- a/config.go +++ b/config.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "strings" + "reflect" "github.com/hjson/hjson-go/v4" ) @@ -13,6 +14,8 @@ import ( var ErrUndefined = errors.New("value not defined") var ErrFileNotFound = errors.New("file not found") var ErrParse = errors.New("file could not be parsed") +var ErrType = errors.New("invalid type") +var ErrKey = errors.New("key not found") // File and parsing errors type ParseError struct{ @@ -104,3 +107,30 @@ func (s ServiceConfig) GetHostPort() (string, error) { return ports[0], nil } + +// Walk a tree of nested structures or maps until the node is found. +// Node must be of type string or array. +func GetValue(i interface{}, path string) (interface{}, error) { + for _, p := range strings.Split(path, ".") { + switch reflect.ValueOf(i).Kind() { + case reflect.Struct: + v := reflect.ValueOf(i).FieldByName(p) + if v.IsValid() == false { return nil, ErrKey } + i = v.Interface() + case reflect.Map: + v := reflect.ValueOf(i) + if v.IsValid() == false { return nil, ErrKey } + i = v.MapIndex(reflect.ValueOf(p)).Interface() + case reflect.Array: + return i, nil + case reflect.String: + return i, nil + default: + fmt.Printf("%s is not a valid type\n", + reflect.TypeOf(i).Kind()) + return nil, ErrType + } + } + + return i, nil +}