1package yamlpatch 2 3import "reflect" 4 5// Node holds a YAML document that has not yet been processed into a NodeMap or 6// NodeSlice 7type Node struct { 8 raw *interface{} 9 container Container 10} 11 12// NewNode returns a new Node. It expects a pointer to an interface{} 13func NewNode(raw *interface{}) *Node { 14 return &Node{ 15 raw: raw, 16 } 17} 18 19// MarshalYAML implements yaml.Marshaler, and returns the correct interface{} 20// to be marshaled 21func (n *Node) MarshalYAML() (interface{}, error) { 22 if n.container != nil { 23 return n.container, nil 24 } 25 26 return *n.raw, nil 27} 28 29// UnmarshalYAML implements yaml.Unmarshaler 30func (n *Node) UnmarshalYAML(unmarshal func(interface{}) error) error { 31 var data interface{} 32 33 err := unmarshal(&data) 34 if err != nil { 35 return err 36 } 37 38 n.raw = &data 39 return nil 40} 41 42// Empty returns whether the raw value is nil 43func (n *Node) Empty() bool { 44 return *n.raw == nil 45} 46 47// Container returns the node as a Container 48func (n *Node) Container() Container { 49 if n.container != nil { 50 return n.container 51 } 52 53 switch rt := (*n.raw).(type) { 54 case []interface{}: 55 c := make(nodeSlice, len(rt)) 56 n.container = &c 57 58 for i := range rt { 59 c[i] = NewNode(&rt[i]) 60 } 61 case map[interface{}]interface{}: 62 c := make(nodeMap, len(rt)) 63 n.container = &c 64 65 for k := range rt { 66 v := rt[k] 67 c[k] = NewNode(&v) 68 } 69 } 70 71 return n.container 72} 73 74// Equal compares the values of the raw interfaces that the YAML was 75// unmarshaled into 76func (n *Node) Equal(other *Node) bool { 77 return reflect.DeepEqual(*n.raw, *other.raw) 78} 79 80// Value returns the raw value of the node 81func (n *Node) Value() interface{} { 82 return *n.raw 83} 84