1 package unstable
2 3 import (
4 "fmt"
5 "unsafe"
6 7 "github.com/pelletier/go-toml/v2/internal/danger"
8 )
9 10 // Iterator over a sequence of nodes.
11 //
12 // Starts uninitialized, you need to call Next() first.
13 //
14 // For example:
15 //
16 // it := n.Children()
17 // for it.Next() {
18 // n := it.Node()
19 // // do something with n
20 // }
21 type Iterator struct {
22 started bool
23 node *Node
24 }
25 26 // Next moves the iterator forward and returns true if points to a
27 // node, false otherwise.
28 func (c *Iterator) Next() bool {
29 if !c.started {
30 c.started = true
31 } else if c.node.Valid() {
32 c.node = c.node.Next()
33 }
34 return c.node.Valid()
35 }
36 37 // IsLast returns true if the current node of the iterator is the last
38 // one. Subsequent calls to Next() will return false.
39 func (c *Iterator) IsLast() bool {
40 return c.node.next == 0
41 }
42 43 // Node returns a pointer to the node pointed at by the iterator.
44 func (c *Iterator) Node() *Node {
45 return c.node
46 }
47 48 // Node in a TOML expression AST.
49 //
50 // Depending on Kind, its sequence of children should be interpreted
51 // differently.
52 //
53 // - Array have one child per element in the array.
54 // - InlineTable have one child per key-value in the table (each of kind
55 // InlineTable).
56 // - KeyValue have at least two children. The first one is the value. The rest
57 // make a potentially dotted key.
58 // - Table and ArrayTable's children represent a dotted key (same as
59 // KeyValue, but without the first node being the value).
60 //
61 // When relevant, Raw describes the range of bytes this node is referring to in
62 // the input document. Use Parser.Raw() to retrieve the actual bytes.
63 type Node struct {
64 Kind Kind
65 Raw Range // Raw bytes from the input.
66 Data []byte // Node value (either allocated or referencing the input).
67 68 // References to other nodes, as offsets in the backing array
69 // from this node. References can go backward, so those can be
70 // negative.
71 next int // 0 if last element
72 child int // 0 if no child
73 }
74 75 // Range of bytes in the document.
76 type Range struct {
77 Offset uint32
78 Length uint32
79 }
80 81 // Next returns a pointer to the next node, or nil if there is no next node.
82 func (n *Node) Next() *Node {
83 if n.next == 0 {
84 return nil
85 }
86 ptr := unsafe.Pointer(n)
87 size := unsafe.Sizeof(Node{})
88 return (*Node)(danger.Stride(ptr, size, n.next))
89 }
90 91 // Child returns a pointer to the first child node of this node. Other children
92 // can be accessed calling Next on the first child. Returns an nil if this Node
93 // has no child.
94 func (n *Node) Child() *Node {
95 if n.child == 0 {
96 return nil
97 }
98 ptr := unsafe.Pointer(n)
99 size := unsafe.Sizeof(Node{})
100 return (*Node)(danger.Stride(ptr, size, n.child))
101 }
102 103 // Valid returns true if the node's kind is set (not to Invalid).
104 func (n *Node) Valid() bool {
105 return n != nil
106 }
107 108 // Key returns the children nodes making the Key on a supported node. Panics
109 // otherwise. They are guaranteed to be all be of the Kind Key. A simple key
110 // would return just one element.
111 func (n *Node) Key() Iterator {
112 switch n.Kind {
113 case KeyValue:
114 value := n.Child()
115 if !value.Valid() {
116 panic(fmt.Errorf("KeyValue should have at least two children"))
117 }
118 return Iterator{node: value.Next()}
119 case Table, ArrayTable:
120 return Iterator{node: n.Child()}
121 default:
122 panic(fmt.Errorf("Key() is not supported on a %s", n.Kind))
123 }
124 }
125 126 // Value returns a pointer to the value node of a KeyValue.
127 // Guaranteed to be non-nil. Panics if not called on a KeyValue node,
128 // or if the Children are malformed.
129 func (n *Node) Value() *Node {
130 return n.Child()
131 }
132 133 // Children returns an iterator over a node's children.
134 func (n *Node) Children() Iterator {
135 return Iterator{node: n.Child()}
136 }
137