diff --git a/config.go b/config.go index fd71d2e..725d596 100644 --- a/config.go +++ b/config.go @@ -4,7 +4,6 @@ import ( "fmt" "io" "strconv" - "strings" ) // Config holds a single hierarchical structure like JSON and handles parsing @@ -53,36 +52,52 @@ func (c *Config) Get(key string) (any, error) { return c.data, nil } - if !strings.Contains(key, ".") { - if val, ok := c.data[key]; ok { - return val, nil + // Parse the dot-notation path manually + var start, i int + var current any = c.data + + for i = 0; i < len(key); i++ { + if key[i] == '.' || i == len(key)-1 { + end := i + if i == len(key)-1 && key[i] != '.' { + end = i + 1 + } + + part := key[start:end] + + // Handle current node based on its type + switch node := current.(type) { + case map[string]any: + val, ok := node[part] + if !ok { + return nil, fmt.Errorf("key %s not found", part) + } + current = val + + case []any: + index, err := strconv.Atoi(part) + if err != nil { + return nil, fmt.Errorf("invalid array index: %s", part) + } + if index < 0 || index >= len(node) { + return nil, fmt.Errorf("array index out of bounds: %d", index) + } + current = node[index] + + default: + return nil, fmt.Errorf("cannot access %s in non-container value", part) + } + + if i == len(key)-1 || (i < len(key)-1 && key[i] == '.' && end == i) { + if i == len(key)-1 { + return current, nil + } + } + + start = i + 1 } - return nil, fmt.Errorf("key %s not found", key) } - parts := strings.Split(key, ".") - current := any(c.data) - for _, part := range parts { - switch node := current.(type) { - case map[string]any: - var exists bool - current, exists = node[part] - if !exists { - return nil, fmt.Errorf("key %s not found", part) - } - case []any: - index, err := strconv.Atoi(part) - if err != nil { - return nil, fmt.Errorf("invalid array index: %s", part) - } - if index < 0 || index >= len(node) { - return nil, fmt.Errorf("array index out of bounds: %d", index) - } - current = node[index] - default: - return nil, fmt.Errorf("cannot access %s in non-container value", part) - } - } return current, nil }