package interpolation import ( "errors" "fmt" "slices" "strings" ) // LookupFunction returns the value to rewrite a path expression to. type LookupFunction func(path string, depends map[string]string) (string, error) // ErrSkipInterpolation can be used to fall through from [LookupFunction]. var ErrSkipInterpolation = errors.New("skip interpolation") // DefaultLookup looks up the specified path in the map. // It returns an error if it doesn't exist. func DefaultLookup(path string, lookup map[string]string) (string, error) { v, ok := lookup[path] if !ok { return "", fmt.Errorf("expected to find value for path: %s", path) } return v, nil } func pathPrefixMatches(prefix []string, path string) bool { parts := strings.Split(path, Delimiter) return len(parts) >= len(prefix) && slices.Compare(prefix, parts[0:len(prefix)]) == 0 } // ExcludeLookupsInPath is a lookup function that skips lookups for the specified path. func ExcludeLookupsInPath(exclude ...string) LookupFunction { return func(path string, lookup map[string]string) (string, error) { if pathPrefixMatches(exclude, path) { return "", ErrSkipInterpolation } return DefaultLookup(path, lookup) } } // IncludeLookupsInPath is a lookup function that limits lookups to the specified path. func IncludeLookupsInPath(include ...string) LookupFunction { return func(path string, lookup map[string]string) (string, error) { if !pathPrefixMatches(include, path) { return "", ErrSkipInterpolation } return DefaultLookup(path, lookup) } }