-
Notifications
You must be signed in to change notification settings - Fork 106
/
Copy pathobjects.go
130 lines (108 loc) · 2.94 KB
/
objects.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
package jsluice
import (
"strings"
)
// Object is a wrapper about a N ode that contains a JS Object
// It has convenience methods to find properties of the object,
// convert it to other types etc.
type Object struct {
node *Node
source []byte
}
// NewObject returns a jsluice Object for the given Node
func NewObject(n *Node, source []byte) Object {
return Object{
node: n,
source: source,
}
}
// AsMap returns a Go map version of the object
func (o Object) AsMap() map[string]string {
out := make(map[string]string, 0)
if !o.HasValidNode() {
return out
}
for _, k := range o.GetKeys() {
out[k] = o.GetString(k, "")
}
return out
}
// HasValidNode returns true if the underlying node is
// a valid JavaScript object
func (o Object) HasValidNode() bool {
return o.node.IsValid() && o.node.Type() == "object"
}
// GetNodeFunc is a general-purpose method for finding object
// properties by their key. The provided function is called
// with each key in turn. The first time that function returns
// true the corresponding *Node for that key is returned.
func (o Object) GetNodeFunc(fn func(key string) bool) *Node {
if !o.HasValidNode() {
return &Node{}
}
count := int(o.node.NamedChildCount())
for i := 0; i < count; i++ {
pair := o.node.NamedChild(i)
if pair.Type() != "pair" {
continue
}
if !fn(pair.ChildByFieldName("key").RawString()) {
continue
}
return pair.ChildByFieldName("value")
}
return nil
}
// GetNode returns the matching *Node for a given key
func (o Object) GetNode(key string) *Node {
return o.GetNodeFunc(func(candidate string) bool {
return key == candidate
})
}
// GetNodeI is like GetNode, but case-insensitive
func (o Object) GetNodeI(key string) *Node {
key = strings.ToLower(key)
return o.GetNodeFunc(func(candidate string) bool {
return key == strings.ToLower(candidate)
})
}
// GetKeys returns a slice of all keys in an object
func (o Object) GetKeys() []string {
out := make([]string, 0)
if !o.HasValidNode() {
return out
}
count := int(o.node.NamedChildCount())
for i := 0; i < count; i++ {
pair := o.node.NamedChild(i)
if pair.Type() != "pair" {
continue
}
key := pair.ChildByFieldName("key").RawString()
out = append(out, key)
}
return out
}
// GetObject returns the property corresponding to the
// provided key as an Object
func (o Object) GetObject(key string) Object {
return NewObject(o.GetNode(key), o.source)
}
// GetString returns the property corresponding to the
// provided key as a string, or the defaultVal if the
// key is not found.
func (o Object) GetString(key, defaultVal string) string {
value := o.GetNode(key)
if value == nil || value.Type() != "string" {
return defaultVal
}
return value.RawString()
}
// GetStringI is like GetString, but the key is case-insensitive
func (o Object) GetStringI(key, defaultVal string) string {
value := o.GetNodeI(key)
if value == nil || value.Type() != "string" {
return defaultVal
}
return value.RawString()
}