1package orderedmap
2
3import (
4 "fmt"
5
6 "gopkg.in/yaml.v3"
7)
8
9var (
10 _ yaml.Marshaler = &OrderedMap[int, any]{}
11 _ yaml.Unmarshaler = &OrderedMap[int, any]{}
12)
13
14// MarshalYAML implements the yaml.Marshaler interface.
15func (om *OrderedMap[K, V]) MarshalYAML() (interface{}, error) {
16 if om == nil {
17 return []byte("null"), nil
18 }
19
20 node := yaml.Node{
21 Kind: yaml.MappingNode,
22 }
23
24 for pair := om.Oldest(); pair != nil; pair = pair.Next() {
25 key, value := pair.Key, pair.Value
26
27 keyNode := &yaml.Node{}
28
29 // serialize key to yaml, then deserialize it back into the node
30 // this is a hack to get the correct tag for the key
31 if err := keyNode.Encode(key); err != nil {
32 return nil, err
33 }
34
35 valueNode := &yaml.Node{}
36 if err := valueNode.Encode(value); err != nil {
37 return nil, err
38 }
39
40 node.Content = append(node.Content, keyNode, valueNode)
41 }
42
43 return &node, nil
44}
45
46// UnmarshalYAML implements the yaml.Unmarshaler interface.
47func (om *OrderedMap[K, V]) UnmarshalYAML(value *yaml.Node) error {
48 if value.Kind != yaml.MappingNode {
49 return fmt.Errorf("pipeline must contain YAML mapping, has %v", value.Kind)
50 }
51
52 if om.list == nil {
53 om.initialize(0)
54 }
55
56 for index := 0; index < len(value.Content); index += 2 {
57 var key K
58 var val V
59
60 if err := value.Content[index].Decode(&key); err != nil {
61 return err
62 }
63 if err := value.Content[index+1].Decode(&val); err != nil {
64 return err
65 }
66
67 om.Set(key, val)
68 }
69
70 return nil
71}