goccy / go-yaml

YAML support for the Go language
MIT License
1.12k stars 129 forks source link

Support custom unmarshalling for mapping keys #452

Closed KSpaceer closed 2 months ago

KSpaceer commented 2 months ago

Is your feature request related to a problem? Please describe. Currently map decoding does not support using custom unmarshalling methods for keys, only for values. It means only maps with basic type keys (like strings, numbers etc) can be decoded. It would be nice to support custom unmarshalling for keys too, so structs and other types can be used.

Describe the solution you'd like Currently decoder converts key node into value (i.e. into string, integer or something basic like that), and then converts it into target key type (i.e. only basic types and types having basic types as underlying can be used).

I suggest next approach: check if key type supports any unmarshalling interface; if it does - use the unmarshalling method, otherwise - fallback to using node value and converting

Describe alternatives you've considered

Additional context

Example to use ```go type Enum string func (e Enum) IsValid() bool { return slices.Contains(validEnumValues, e) } func (e *Enum) UnmarshalYAML(b []byte) error { var s string if err := yaml.Unmarshal(b, &s); err != nil { return err } *e = Enum(s) if !e.IsValid() { return fmt.Errorf("invalid enum value %s", s) } return nil } var example = []byte(`a: 12`) func GetEnumMap() (map[Enum]string, error) { var m map[Enum]string if err := yaml.Unmarshal(example, &m); err != nil { return nil, err } return m, nil } ```