podman

Форк
0
464 строки · 8.8 Кб
1
package sprig
2

3
import (
4
	"fmt"
5
	"math"
6
	"reflect"
7
	"sort"
8
)
9

10
// Reflection is used in these functions so that slices and arrays of strings,
11
// ints, and other types not implementing []interface{} can be worked with.
12
// For example, this is useful if you need to work on the output of regexs.
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
	//return append([]interface{}{v}, list...)
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
		// We do not sort in place because the incoming array should not be altered.
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
// $list := [1, 2, 3, 4, 5]
409
// slice $list     -> list[0:5] = list[:]
410
// slice $list 0 3 -> list[0:3] = list[:3]
411
// slice $list 3 5 -> list[3:5]
412
// slice $list 3   -> list[3:5] = list[3:]
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.