// Package utils contains utility functions for the parser package. package utils import ( "maps" "strings" ) // SetPathValue sets value at a dot-separated path in obj, creating maps as needed. // If the path is only dots (e.g., "." or ".."): // - when obj == nil -> returns value directly (e.g., "flour") // - when obj is a map -> if value is a map[string]any, merge into obj; otherwise obj is unchanged. // - otherwise -> returns obj unchanged. func SetPathValue(path string, value any, obj any) any { // Split and drop empty segments (so ".", "..", "" become no keys) raw := strings.Split(path, ".") keys := raw[:0] for _, k := range raw { if k != "" { keys = append(keys, k) } } // Root case: no keys after trimming dots if len(keys) == 0 { if obj == nil { return value } if m, ok := obj.(map[string]any); ok { if mv, ok := value.(map[string]any); ok { maps.Copy(m, mv) } return m } return obj } // Ensure root is a map var root map[string]any if obj == nil { root = map[string]any{} } else if m, ok := obj.(map[string]any); ok { root = m } else { // if obj is not a map, just overwrite it with a new map root = map[string]any{} } // Descend/construct maps curr := root for i, k := range keys { if i == len(keys)-1 { curr[k] = value break } if next, ok := curr[k].(map[string]any); ok { curr = next continue } n := map[string]any{} curr[k] = n curr = n } return root }