40 lines
841 B
Go
40 lines
841 B
Go
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
|
|
}
|