diff options
Diffstat (limited to 'vendor/github.com/jmespath/go-jmespath/util.go')
-rw-r--r-- | vendor/github.com/jmespath/go-jmespath/util.go | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/vendor/github.com/jmespath/go-jmespath/util.go b/vendor/github.com/jmespath/go-jmespath/util.go new file mode 100644 index 0000000..ddc1b7d --- /dev/null +++ b/vendor/github.com/jmespath/go-jmespath/util.go | |||
@@ -0,0 +1,185 @@ | |||
1 | package jmespath | ||
2 | |||
3 | import ( | ||
4 | "errors" | ||
5 | "reflect" | ||
6 | ) | ||
7 | |||
8 | // IsFalse determines if an object is false based on the JMESPath spec. | ||
9 | // JMESPath defines false values to be any of: | ||
10 | // - An empty string array, or hash. | ||
11 | // - The boolean value false. | ||
12 | // - nil | ||
13 | func isFalse(value interface{}) bool { | ||
14 | switch v := value.(type) { | ||
15 | case bool: | ||
16 | return !v | ||
17 | case []interface{}: | ||
18 | return len(v) == 0 | ||
19 | case map[string]interface{}: | ||
20 | return len(v) == 0 | ||
21 | case string: | ||
22 | return len(v) == 0 | ||
23 | case nil: | ||
24 | return true | ||
25 | } | ||
26 | // Try the reflection cases before returning false. | ||
27 | rv := reflect.ValueOf(value) | ||
28 | switch rv.Kind() { | ||
29 | case reflect.Struct: | ||
30 | // A struct type will never be false, even if | ||
31 | // all of its values are the zero type. | ||
32 | return false | ||
33 | case reflect.Slice, reflect.Map: | ||
34 | return rv.Len() == 0 | ||
35 | case reflect.Ptr: | ||
36 | if rv.IsNil() { | ||
37 | return true | ||
38 | } | ||
39 | // If it's a pointer type, we'll try to deref the pointer | ||
40 | // and evaluate the pointer value for isFalse. | ||
41 | element := rv.Elem() | ||
42 | return isFalse(element.Interface()) | ||
43 | } | ||
44 | return false | ||
45 | } | ||
46 | |||
47 | // ObjsEqual is a generic object equality check. | ||
48 | // It will take two arbitrary objects and recursively determine | ||
49 | // if they are equal. | ||
50 | func objsEqual(left interface{}, right interface{}) bool { | ||
51 | return reflect.DeepEqual(left, right) | ||
52 | } | ||
53 | |||
54 | // SliceParam refers to a single part of a slice. | ||
55 | // A slice consists of a start, a stop, and a step, similar to | ||
56 | // python slices. | ||
57 | type sliceParam struct { | ||
58 | N int | ||
59 | Specified bool | ||
60 | } | ||
61 | |||
62 | // Slice supports [start:stop:step] style slicing that's supported in JMESPath. | ||
63 | func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) { | ||
64 | computed, err := computeSliceParams(len(slice), parts) | ||
65 | if err != nil { | ||
66 | return nil, err | ||
67 | } | ||
68 | start, stop, step := computed[0], computed[1], computed[2] | ||
69 | result := []interface{}{} | ||
70 | if step > 0 { | ||
71 | for i := start; i < stop; i += step { | ||
72 | result = append(result, slice[i]) | ||
73 | } | ||
74 | } else { | ||
75 | for i := start; i > stop; i += step { | ||
76 | result = append(result, slice[i]) | ||
77 | } | ||
78 | } | ||
79 | return result, nil | ||
80 | } | ||
81 | |||
82 | func computeSliceParams(length int, parts []sliceParam) ([]int, error) { | ||
83 | var start, stop, step int | ||
84 | if !parts[2].Specified { | ||
85 | step = 1 | ||
86 | } else if parts[2].N == 0 { | ||
87 | return nil, errors.New("Invalid slice, step cannot be 0") | ||
88 | } else { | ||
89 | step = parts[2].N | ||
90 | } | ||
91 | var stepValueNegative bool | ||
92 | if step < 0 { | ||
93 | stepValueNegative = true | ||
94 | } else { | ||
95 | stepValueNegative = false | ||
96 | } | ||
97 | |||
98 | if !parts[0].Specified { | ||
99 | if stepValueNegative { | ||
100 | start = length - 1 | ||
101 | } else { | ||
102 | start = 0 | ||
103 | } | ||
104 | } else { | ||
105 | start = capSlice(length, parts[0].N, step) | ||
106 | } | ||
107 | |||
108 | if !parts[1].Specified { | ||
109 | if stepValueNegative { | ||
110 | stop = -1 | ||
111 | } else { | ||
112 | stop = length | ||
113 | } | ||
114 | } else { | ||
115 | stop = capSlice(length, parts[1].N, step) | ||
116 | } | ||
117 | return []int{start, stop, step}, nil | ||
118 | } | ||
119 | |||
120 | func capSlice(length int, actual int, step int) int { | ||
121 | if actual < 0 { | ||
122 | actual += length | ||
123 | if actual < 0 { | ||
124 | if step < 0 { | ||
125 | actual = -1 | ||
126 | } else { | ||
127 | actual = 0 | ||
128 | } | ||
129 | } | ||
130 | } else if actual >= length { | ||
131 | if step < 0 { | ||
132 | actual = length - 1 | ||
133 | } else { | ||
134 | actual = length | ||
135 | } | ||
136 | } | ||
137 | return actual | ||
138 | } | ||
139 | |||
140 | // ToArrayNum converts an empty interface type to a slice of float64. | ||
141 | // If any element in the array cannot be converted, then nil is returned | ||
142 | // along with a second value of false. | ||
143 | func toArrayNum(data interface{}) ([]float64, bool) { | ||
144 | // Is there a better way to do this with reflect? | ||
145 | if d, ok := data.([]interface{}); ok { | ||
146 | result := make([]float64, len(d)) | ||
147 | for i, el := range d { | ||
148 | item, ok := el.(float64) | ||
149 | if !ok { | ||
150 | return nil, false | ||
151 | } | ||
152 | result[i] = item | ||
153 | } | ||
154 | return result, true | ||
155 | } | ||
156 | return nil, false | ||
157 | } | ||
158 | |||
159 | // ToArrayStr converts an empty interface type to a slice of strings. | ||
160 | // If any element in the array cannot be converted, then nil is returned | ||
161 | // along with a second value of false. If the input data could be entirely | ||
162 | // converted, then the converted data, along with a second value of true, | ||
163 | // will be returned. | ||
164 | func toArrayStr(data interface{}) ([]string, bool) { | ||
165 | // Is there a better way to do this with reflect? | ||
166 | if d, ok := data.([]interface{}); ok { | ||
167 | result := make([]string, len(d)) | ||
168 | for i, el := range d { | ||
169 | item, ok := el.(string) | ||
170 | if !ok { | ||
171 | return nil, false | ||
172 | } | ||
173 | result[i] = item | ||
174 | } | ||
175 | return result, true | ||
176 | } | ||
177 | return nil, false | ||
178 | } | ||
179 | |||
180 | func isSliceType(v interface{}) bool { | ||
181 | if v == nil { | ||
182 | return false | ||
183 | } | ||
184 | return reflect.TypeOf(v).Kind() == reflect.Slice | ||
185 | } | ||