isle/go/yamlutil/ordered_map.go

40 lines
841 B
Go
Raw Normal View History

package yamlutil
import (
"cmp"
"slices"
"gopkg.in/yaml.v3"
)
// OrderedMap is like a normal map, except that when it is marshaled to yaml it
// will do so with its keys in ascending order. This makes it useful when
// generating output which needs to be deterministic.
type OrderedMap[K comparable, V any] map[K]V
func (m OrderedMap[K, V]) MarshalYAML() (any, error) {
type wrapped map[K]V
var n yaml.Node
if err := n.Encode(wrapped(m)); err != nil {
return nil, err
}
pairs := make([][2]*yaml.Node, len(n.Content)/2)
for i := range pairs {
pairs[i][0] = n.Content[i*2]
pairs[i][1] = n.Content[i*2+1]
}
slices.SortFunc(pairs, func(a, b [2]*yaml.Node) int {
return cmp.Compare(a[0].Value, b[0].Value)
})
for i := range pairs {
n.Content[i*2] = pairs[i][0]
n.Content[i*2+1] = pairs[i][1]
}
return n, nil
}