1 package sprig
2
3 import (
4 "fmt"
5 "math"
6 "reflect"
7 "sort"
8 )
9
10
11
12
13
14 func list(v ...interface{}) []interface{} {
15 return v
16 }
17
18 func push(list interface{}, v interface{}) []interface{} {
19 l, err := mustPush(list, v)
20 if err != nil {
21 panic(err)
22 }
23
24 return l
25 }
26
27 func mustPush(list interface{}, v interface{}) ([]interface{}, error) {
28 tp := reflect.TypeOf(list).Kind()
29 switch tp {
30 case reflect.Slice, reflect.Array:
31 l2 := reflect.ValueOf(list)
32
33 l := l2.Len()
34 nl := make([]interface{}, l)
35 for i := 0; i < l; i++ {
36 nl[i] = l2.Index(i).Interface()
37 }
38
39 return append(nl, v), nil
40
41 default:
42 return nil, fmt.Errorf("Cannot push on type %s", tp)
43 }
44 }
45
46 func prepend(list interface{}, v interface{}) []interface{} {
47 l, err := mustPrepend(list, v)
48 if err != nil {
49 panic(err)
50 }
51
52 return l
53 }
54
55 func mustPrepend(list interface{}, v interface{}) ([]interface{}, error) {
56
57
58 tp := reflect.TypeOf(list).Kind()
59 switch tp {
60 case reflect.Slice, reflect.Array:
61 l2 := reflect.ValueOf(list)
62
63 l := l2.Len()
64 nl := make([]interface{}, l)
65 for i := 0; i < l; i++ {
66 nl[i] = l2.Index(i).Interface()
67 }
68
69 return append([]interface{}{v}, nl...), nil
70
71 default:
72 return nil, fmt.Errorf("Cannot prepend on type %s", tp)
73 }
74 }
75
76 func chunk(size int, list interface{}) [][]interface{} {
77 l, err := mustChunk(size, list)
78 if err != nil {
79 panic(err)
80 }
81
82 return l
83 }
84
85 func mustChunk(size int, list interface{}) ([][]interface{}, error) {
86 tp := reflect.TypeOf(list).Kind()
87 switch tp {
88 case reflect.Slice, reflect.Array:
89 l2 := reflect.ValueOf(list)
90
91 l := l2.Len()
92
93 cs := int(math.Floor(float64(l-1)/float64(size)) + 1)
94 nl := make([][]interface{}, cs)
95
96 for i := 0; i < cs; i++ {
97 clen := size
98 if i == cs-1 {
99 clen = int(math.Floor(math.Mod(float64(l), float64(size))))
100 if clen == 0 {
101 clen = size
102 }
103 }
104
105 nl[i] = make([]interface{}, clen)
106
107 for j := 0; j < clen; j++ {
108 ix := i*size + j
109 nl[i][j] = l2.Index(ix).Interface()
110 }
111 }
112
113 return nl, nil
114
115 default:
116 return nil, fmt.Errorf("Cannot chunk type %s", tp)
117 }
118 }
119
120 func last(list interface{}) interface{} {
121 l, err := mustLast(list)
122 if err != nil {
123 panic(err)
124 }
125
126 return l
127 }
128
129 func mustLast(list interface{}) (interface{}, error) {
130 tp := reflect.TypeOf(list).Kind()
131 switch tp {
132 case reflect.Slice, reflect.Array:
133 l2 := reflect.ValueOf(list)
134
135 l := l2.Len()
136 if l == 0 {
137 return nil, nil
138 }
139
140 return l2.Index(l - 1).Interface(), nil
141 default:
142 return nil, fmt.Errorf("Cannot find last on type %s", tp)
143 }
144 }
145
146 func first(list interface{}) interface{} {
147 l, err := mustFirst(list)
148 if err != nil {
149 panic(err)
150 }
151
152 return l
153 }
154
155 func mustFirst(list interface{}) (interface{}, error) {
156 tp := reflect.TypeOf(list).Kind()
157 switch tp {
158 case reflect.Slice, reflect.Array:
159 l2 := reflect.ValueOf(list)
160
161 l := l2.Len()
162 if l == 0 {
163 return nil, nil
164 }
165
166 return l2.Index(0).Interface(), nil
167 default:
168 return nil, fmt.Errorf("Cannot find first on type %s", tp)
169 }
170 }
171
172 func rest(list interface{}) []interface{} {
173 l, err := mustRest(list)
174 if err != nil {
175 panic(err)
176 }
177
178 return l
179 }
180
181 func mustRest(list interface{}) ([]interface{}, error) {
182 tp := reflect.TypeOf(list).Kind()
183 switch tp {
184 case reflect.Slice, reflect.Array:
185 l2 := reflect.ValueOf(list)
186
187 l := l2.Len()
188 if l == 0 {
189 return nil, nil
190 }
191
192 nl := make([]interface{}, l-1)
193 for i := 1; i < l; i++ {
194 nl[i-1] = l2.Index(i).Interface()
195 }
196
197 return nl, nil
198 default:
199 return nil, fmt.Errorf("Cannot find rest on type %s", tp)
200 }
201 }
202
203 func initial(list interface{}) []interface{} {
204 l, err := mustInitial(list)
205 if err != nil {
206 panic(err)
207 }
208
209 return l
210 }
211
212 func mustInitial(list interface{}) ([]interface{}, error) {
213 tp := reflect.TypeOf(list).Kind()
214 switch tp {
215 case reflect.Slice, reflect.Array:
216 l2 := reflect.ValueOf(list)
217
218 l := l2.Len()
219 if l == 0 {
220 return nil, nil
221 }
222
223 nl := make([]interface{}, l-1)
224 for i := 0; i < l-1; i++ {
225 nl[i] = l2.Index(i).Interface()
226 }
227
228 return nl, nil
229 default:
230 return nil, fmt.Errorf("Cannot find initial on type %s", tp)
231 }
232 }
233
234 func sortAlpha(list interface{}) []string {
235 k := reflect.Indirect(reflect.ValueOf(list)).Kind()
236 switch k {
237 case reflect.Slice, reflect.Array:
238 a := strslice(list)
239 s := sort.StringSlice(a)
240 s.Sort()
241 return s
242 }
243 return []string{strval(list)}
244 }
245
246 func reverse(v interface{}) []interface{} {
247 l, err := mustReverse(v)
248 if err != nil {
249 panic(err)
250 }
251
252 return l
253 }
254
255 func mustReverse(v interface{}) ([]interface{}, error) {
256 tp := reflect.TypeOf(v).Kind()
257 switch tp {
258 case reflect.Slice, reflect.Array:
259 l2 := reflect.ValueOf(v)
260
261 l := l2.Len()
262
263 nl := make([]interface{}, l)
264 for i := 0; i < l; i++ {
265 nl[l-i-1] = l2.Index(i).Interface()
266 }
267
268 return nl, nil
269 default:
270 return nil, fmt.Errorf("Cannot find reverse on type %s", tp)
271 }
272 }
273
274 func compact(list interface{}) []interface{} {
275 l, err := mustCompact(list)
276 if err != nil {
277 panic(err)
278 }
279
280 return l
281 }
282
283 func mustCompact(list interface{}) ([]interface{}, error) {
284 tp := reflect.TypeOf(list).Kind()
285 switch tp {
286 case reflect.Slice, reflect.Array:
287 l2 := reflect.ValueOf(list)
288
289 l := l2.Len()
290 nl := []interface{}{}
291 var item interface{}
292 for i := 0; i < l; i++ {
293 item = l2.Index(i).Interface()
294 if !empty(item) {
295 nl = append(nl, item)
296 }
297 }
298
299 return nl, nil
300 default:
301 return nil, fmt.Errorf("Cannot compact on type %s", tp)
302 }
303 }
304
305 func uniq(list interface{}) []interface{} {
306 l, err := mustUniq(list)
307 if err != nil {
308 panic(err)
309 }
310
311 return l
312 }
313
314 func mustUniq(list interface{}) ([]interface{}, error) {
315 tp := reflect.TypeOf(list).Kind()
316 switch tp {
317 case reflect.Slice, reflect.Array:
318 l2 := reflect.ValueOf(list)
319
320 l := l2.Len()
321 dest := []interface{}{}
322 var item interface{}
323 for i := 0; i < l; i++ {
324 item = l2.Index(i).Interface()
325 if !inList(dest, item) {
326 dest = append(dest, item)
327 }
328 }
329
330 return dest, nil
331 default:
332 return nil, fmt.Errorf("Cannot find uniq on type %s", tp)
333 }
334 }
335
336 func inList(haystack []interface{}, needle interface{}) bool {
337 for _, h := range haystack {
338 if reflect.DeepEqual(needle, h) {
339 return true
340 }
341 }
342 return false
343 }
344
345 func without(list interface{}, omit ...interface{}) []interface{} {
346 l, err := mustWithout(list, omit...)
347 if err != nil {
348 panic(err)
349 }
350
351 return l
352 }
353
354 func mustWithout(list interface{}, omit ...interface{}) ([]interface{}, error) {
355 tp := reflect.TypeOf(list).Kind()
356 switch tp {
357 case reflect.Slice, reflect.Array:
358 l2 := reflect.ValueOf(list)
359
360 l := l2.Len()
361 res := []interface{}{}
362 var item interface{}
363 for i := 0; i < l; i++ {
364 item = l2.Index(i).Interface()
365 if !inList(omit, item) {
366 res = append(res, item)
367 }
368 }
369
370 return res, nil
371 default:
372 return nil, fmt.Errorf("Cannot find without on type %s", tp)
373 }
374 }
375
376 func has(needle interface{}, haystack interface{}) bool {
377 l, err := mustHas(needle, haystack)
378 if err != nil {
379 panic(err)
380 }
381
382 return l
383 }
384
385 func mustHas(needle interface{}, haystack interface{}) (bool, error) {
386 if haystack == nil {
387 return false, nil
388 }
389 tp := reflect.TypeOf(haystack).Kind()
390 switch tp {
391 case reflect.Slice, reflect.Array:
392 l2 := reflect.ValueOf(haystack)
393 var item interface{}
394 l := l2.Len()
395 for i := 0; i < l; i++ {
396 item = l2.Index(i).Interface()
397 if reflect.DeepEqual(needle, item) {
398 return true, nil
399 }
400 }
401
402 return false, nil
403 default:
404 return false, fmt.Errorf("Cannot find has on type %s", tp)
405 }
406 }
407
408
409
410
411
412
413 func slice(list interface{}, indices ...interface{}) interface{} {
414 l, err := mustSlice(list, indices...)
415 if err != nil {
416 panic(err)
417 }
418
419 return l
420 }
421
422 func mustSlice(list interface{}, indices ...interface{}) (interface{}, error) {
423 tp := reflect.TypeOf(list).Kind()
424 switch tp {
425 case reflect.Slice, reflect.Array:
426 l2 := reflect.ValueOf(list)
427
428 l := l2.Len()
429 if l == 0 {
430 return nil, nil
431 }
432
433 var start, end int
434 if len(indices) > 0 {
435 start = toInt(indices[0])
436 }
437 if len(indices) < 2 {
438 end = l
439 } else {
440 end = toInt(indices[1])
441 }
442
443 return l2.Slice(start, end).Interface(), nil
444 default:
445 return nil, fmt.Errorf("list should be type of slice or array but %s", tp)
446 }
447 }
448
449 func concat(lists ...interface{}) interface{} {
450 var res []interface{}
451 for _, list := range lists {
452 tp := reflect.TypeOf(list).Kind()
453 switch tp {
454 case reflect.Slice, reflect.Array:
455 l2 := reflect.ValueOf(list)
456 for i := 0; i < l2.Len(); i++ {
457 res = append(res, l2.Index(i).Interface())
458 }
459 default:
460 panic(fmt.Sprintf("Cannot concat type %s as list", tp))
461 }
462 }
463 return res
464 }
465
View as plain text