package sprig // get retrieves a value from a map by its key. // If the key exists, returns the corresponding value. // If the key doesn't exist, returns an empty string. // // Parameters: // - d: The map to retrieve the value from // - key: The key to look up // // Returns: // - any: The value associated with the key, or an empty string if not found func get(d map[string]any, key string) any { if val, ok := d[key]; ok { return val } return "" } // set adds or updates a key-value pair in a map. // Modifies the map in place and returns the modified map. // // Parameters: // - d: The map to modify // - key: The key to set // - value: The value to associate with the key // // Returns: // - map[string]any: The modified map (same instance as the input map) func set(d map[string]any, key string, value any) map[string]any { d[key] = value return d } // unset removes a key-value pair from a map. // If the key doesn't exist, the map remains unchanged. // Modifies the map in place and returns the modified map. // // Parameters: // - d: The map to modify // - key: The key to remove // // Returns: // - map[string]any: The modified map (same instance as the input map) func unset(d map[string]any, key string) map[string]any { delete(d, key) return d } // hasKey checks if a key exists in a map. // // Parameters: // - d: The map to check // - key: The key to look for // // Returns: // - bool: True if the key exists in the map, false otherwise func hasKey(d map[string]any, key string) bool { _, ok := d[key] return ok } // pluck extracts values for a specific key from multiple maps. // Only includes values from maps where the key exists. // // Parameters: // - key: The key to extract values for // - d: A variadic list of maps to extract values from // // Returns: // - []any: A slice containing all values associated with the key across all maps func pluck(key string, d ...map[string]any) []any { var res []any for _, dict := range d { if val, ok := dict[key]; ok { res = append(res, val) } } return res } // keys collects all keys from one or more maps. // The returned slice may contain duplicate keys if multiple maps contain the same key. // // Parameters: // - dicts: A variadic list of maps to collect keys from // // Returns: // - []string: A slice containing all keys from all provided maps func keys(dicts ...map[string]any) []string { var k []string for _, dict := range dicts { for key := range dict { k = append(k, key) } } return k } // pick creates a new map containing only the specified keys from the original map. // If a key doesn't exist in the original map, it won't be included in the result. // // Parameters: // - dict: The source map // - keys: A variadic list of keys to include in the result // // Returns: // - map[string]any: A new map containing only the specified keys and their values func pick(dict map[string]any, keys ...string) map[string]any { res := map[string]any{} for _, k := range keys { if v, ok := dict[k]; ok { res[k] = v } } return res } // omit creates a new map excluding the specified keys from the original map. // The original map remains unchanged. // // Parameters: // - dict: The source map // - keys: A variadic list of keys to exclude from the result // // Returns: // - map[string]any: A new map containing all key-value pairs except those specified func omit(dict map[string]any, keys ...string) map[string]any { res := map[string]any{} omit := make(map[string]bool, len(keys)) for _, k := range keys { omit[k] = true } for k, v := range dict { if _, ok := omit[k]; !ok { res[k] = v } } return res } // dict creates a new map from a list of key-value pairs. // The arguments are treated as key-value pairs, where even-indexed arguments are keys // and odd-indexed arguments are values. // If there's an odd number of arguments, the last key will be assigned an empty string value. // // Parameters: // - v: A variadic list of alternating keys and values // // Returns: // - map[string]any: A new map containing the specified key-value pairs func dict(v ...any) map[string]any { dict := map[string]any{} lenv := len(v) for i := 0; i < lenv; i += 2 { key := strval(v[i]) if i+1 >= lenv { dict[key] = "" continue } dict[key] = v[i+1] } return dict } // values collects all values from a map into a slice. // The order of values in the resulting slice is not guaranteed. // // Parameters: // - dict: The map to collect values from // // Returns: // - []any: A slice containing all values from the map func values(dict map[string]any) []any { var values []any for _, value := range dict { values = append(values, value) } return values } // dig safely accesses nested values in maps using a sequence of keys. // If any key in the path doesn't exist, it returns the default value. // The function expects at least 3 arguments: one or more keys, a default value, and a map. // // Parameters: // - ps: A variadic list where: // - The first N-2 arguments are string keys forming the path // - The second-to-last argument is the default value to return if the path doesn't exist // - The last argument is the map to traverse // // Returns: // - any: The value found at the specified path, or the default value if not found // - error: Any error that occurred during traversal // // Panics: // - If fewer than 3 arguments are provided func dig(ps ...any) (any, error) { if len(ps) < 3 { panic("dig needs at least three arguments") } dict := ps[len(ps)-1].(map[string]any) def := ps[len(ps)-2] ks := make([]string, len(ps)-2) for i := 0; i < len(ks); i++ { ks[i] = ps[i].(string) } return digFromDict(dict, def, ks) } // digFromDict is a helper function for dig that recursively traverses a map using a sequence of keys. // If any key in the path doesn't exist, it returns the default value. // // Parameters: // - dict: The map to traverse // - d: The default value to return if the path doesn't exist // - ks: A slice of string keys forming the path to traverse // // Returns: // - any: The value found at the specified path, or the default value if not found // - error: Any error that occurred during traversal func digFromDict(dict map[string]any, d any, ks []string) (any, error) { k, ns := ks[0], ks[1:] step, has := dict[k] if !has { return d, nil } if len(ns) == 0 { return step, nil } return digFromDict(step.(map[string]any), d, ns) }