-
Notifications
You must be signed in to change notification settings - Fork 4
/
elist.go
164 lines (147 loc) · 3.3 KB
/
elist.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package denada
import (
"fmt"
"github.com/bitly/go-simplejson"
)
type ElementList []*Element
func (e ElementList) Definition(name string, children ...string) (*Element, error) {
for _, d := range e {
if d.IsDefinition() && d.Name == name {
if len(children) == 0 {
return d, nil
} else {
return d.Contents.Definition(children[0], children[1:]...)
}
}
}
return nil, fmt.Errorf("Unable to find definition for %s", name)
}
func (e ElementList) Definitions() ElementList {
ret := ElementList{}
for _, elem := range e {
if elem.IsDefinition() {
ret = append(ret, elem)
}
}
return ret
}
func (e ElementList) Declarations() ElementList {
ret := ElementList{}
for _, elem := range e {
if elem.IsDeclaration() {
ret = append(ret, elem)
}
}
return ret
}
func (e ElementList) FirstNamed(name string) *Element {
for _, elem := range e {
if elem.Name == name {
return elem
}
}
return nil
}
func (e ElementList) QualifiedWith(name ...string) ElementList {
ret := ElementList{}
for _, elem := range e {
if elem.HasQualifiers(name...) {
ret = append(ret, elem)
}
}
return ret
}
func (e ElementList) OfRule(name string, fqn bool) ElementList {
ret := ElementList{}
for _, elem := range e {
if fqn {
if elem.rulepath == name {
ret = append(ret, elem)
}
} else {
if elem.rule == name {
ret = append(ret, elem)
}
}
}
return ret
}
func (e ElementList) AllElements() ElementList {
ret := ElementList{}
for _, elem := range e {
ret = append(ret, elem)
if elem.IsDefinition() {
ret = append(ret, elem.Contents.AllElements()...)
}
}
return ret
}
func (e ElementList) PopHead() (*Element, ElementList, error) {
if len(e) == 0 {
return nil, e, fmt.Errorf("Cannot pop the head of an empty element list")
}
ret := e[0]
e = e[1:]
return ret, e, nil
}
func (e ElementList) Equals(o ElementList) error {
// Now make sure they have the same number of children
if len(e) != len(o) {
return fmt.Errorf("Mismatch in number of child elements: %d vs %d: %v vs %v",
len(e), len(o), e, o)
}
// And that each child is equal
for cn, child := range e {
err := child.Equals(*o[cn])
if err != nil {
return err
}
}
return nil
}
// GetValue tries to find an element that matches the **fully qualified** rule name
// provided. It returns nil if it cannot find a match (or it finds multiple matches),
// otherwise it returns the value associated with that declaration.
func (e ElementList) GetValue(rulename string) *simplejson.Json {
elems := e.AllElements().OfRule(rulename, true)
if len(elems) != 1 {
return nil
}
return elems[0].Value
}
func (e ElementList) GetStringValue(rulename string, defaultValue string) string {
v := e.GetValue(rulename)
if v == nil {
return defaultValue
}
ret := v.MustString()
if ret == "" {
return defaultValue
}
return ret
}
func (e ElementList) GetIntValue(rulename string, defaultValue int) int {
v := e.GetValue(rulename)
if v == nil {
return defaultValue
}
ret, err := v.Int()
if err != nil {
return defaultValue
}
return ret
}
func (e ElementList) GetBoolValue(rulename string, defaultValue bool) bool {
v := e.GetValue(rulename)
if v == nil {
return defaultValue
}
ret, err := v.Bool()
if err != nil {
return defaultValue
}
return ret
}
func MakeElementList() ElementList {
return ElementList{}
}