Generic dig for map key using typed parameters

Generic dig for map key using typed parameters Hello! I was fiddling with a way of getting out values from a map that is of format map[string]any. But I wanted my type safety as well. This was coming from digging out keys from a Metadata field. The metadata was in a JSON format. This is what I came up with: / FetchValueFromMetadata fetches a key from a metadata if it exists. It will recursively look in // embedded values as well. Must be a unique key, otherwise it will just return the first // occurrence. func FetchValueFromMetadata[T any](key string, data *apiextensionsv1.JSON, def T) (t T, _ error) { if data == nil { return def, nil } m := map[string]any{} if err := json.Unmarshal(data.Raw, &m); err != nil { return t, fmt.Errorf("failed to parse JSON raw data: %w", err) } v, err := dig[T](key, m) if err != nil { if errors.Is(err, errKeyNotFound) { return def, nil } } return v, nil } func dig[T any](key string, data map[string]any) (t T, _ error) { if v, ok := data[key]; ok { c, k := v.(T) if !k { return t, fmt.Errorf("failed to convert value to the desired type; was: %T", v) } return c, nil } for _, v := range data { if ty, ok := v.(map[string]any); ok { return dig[T](key, ty) } } return t, errKeyNotFound } The interesting part is the dig method and the type assert to the desired part. Calling this with something like: ...

February 27, 2024 · 2 min · hannibal