|
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 refering 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 } |