podman
228 строк · 4.1 Кб
1package sprig
2
3import (
4"fmt"
5"math"
6"reflect"
7"strconv"
8"strings"
9)
10
11// toFloat64 converts 64-bit floats
12func toFloat64(v interface{}) float64 {
13if str, ok := v.(string); ok {
14iv, err := strconv.ParseFloat(str, 64)
15if err != nil {
16return 0
17}
18return iv
19}
20
21val := reflect.Indirect(reflect.ValueOf(v))
22switch val.Kind() {
23case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
24return float64(val.Int())
25case reflect.Uint8, reflect.Uint16, reflect.Uint32:
26return float64(val.Uint())
27case reflect.Uint, reflect.Uint64:
28return float64(val.Uint())
29case reflect.Float32, reflect.Float64:
30return val.Float()
31case reflect.Bool:
32if val.Bool() {
33return 1
34}
35return 0
36default:
37return 0
38}
39}
40
41func toInt(v interface{}) int {
42//It's not optimal. Bud I don't want duplicate toInt64 code.
43return int(toInt64(v))
44}
45
46// toInt64 converts integer types to 64-bit integers
47func toInt64(v interface{}) int64 {
48if str, ok := v.(string); ok {
49iv, err := strconv.ParseInt(str, 10, 64)
50if err != nil {
51return 0
52}
53return iv
54}
55
56val := reflect.Indirect(reflect.ValueOf(v))
57switch val.Kind() {
58case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
59return val.Int()
60case reflect.Uint8, reflect.Uint16, reflect.Uint32:
61return int64(val.Uint())
62case reflect.Uint, reflect.Uint64:
63tv := val.Uint()
64if tv <= math.MaxInt64 {
65return int64(tv)
66}
67// TODO: What is the sensible thing to do here?
68return math.MaxInt64
69case reflect.Float32, reflect.Float64:
70return int64(val.Float())
71case reflect.Bool:
72if val.Bool() {
73return 1
74}
75return 0
76default:
77return 0
78}
79}
80
81func max(a interface{}, i ...interface{}) int64 {
82aa := toInt64(a)
83for _, b := range i {
84bb := toInt64(b)
85if bb > aa {
86aa = bb
87}
88}
89return aa
90}
91
92func maxf(a interface{}, i ...interface{}) float64 {
93aa := toFloat64(a)
94for _, b := range i {
95bb := toFloat64(b)
96aa = math.Max(aa, bb)
97}
98return aa
99}
100
101func min(a interface{}, i ...interface{}) int64 {
102aa := toInt64(a)
103for _, b := range i {
104bb := toInt64(b)
105if bb < aa {
106aa = bb
107}
108}
109return aa
110}
111
112func minf(a interface{}, i ...interface{}) float64 {
113aa := toFloat64(a)
114for _, b := range i {
115bb := toFloat64(b)
116aa = math.Min(aa, bb)
117}
118return aa
119}
120
121func until(count int) []int {
122step := 1
123if count < 0 {
124step = -1
125}
126return untilStep(0, count, step)
127}
128
129func untilStep(start, stop, step int) []int {
130v := []int{}
131
132if stop < start {
133if step >= 0 {
134return v
135}
136for i := start; i > stop; i += step {
137v = append(v, i)
138}
139return v
140}
141
142if step <= 0 {
143return v
144}
145for i := start; i < stop; i += step {
146v = append(v, i)
147}
148return v
149}
150
151func floor(a interface{}) float64 {
152aa := toFloat64(a)
153return math.Floor(aa)
154}
155
156func ceil(a interface{}) float64 {
157aa := toFloat64(a)
158return math.Ceil(aa)
159}
160
161func round(a interface{}, p int, rOpt ...float64) float64 {
162roundOn := .5
163if len(rOpt) > 0 {
164roundOn = rOpt[0]
165}
166val := toFloat64(a)
167places := toFloat64(p)
168
169var round float64
170pow := math.Pow(10, places)
171digit := pow * val
172_, div := math.Modf(digit)
173if div >= roundOn {
174round = math.Ceil(digit)
175} else {
176round = math.Floor(digit)
177}
178return round / pow
179}
180
181// converts unix octal to decimal
182func toDecimal(v interface{}) int64 {
183result, err := strconv.ParseInt(fmt.Sprint(v), 8, 64)
184if err != nil {
185return 0
186}
187return result
188}
189
190func seq(params ...int) string {
191increment := 1
192switch len(params) {
193case 0:
194return ""
195case 1:
196start := 1
197end := params[0]
198if end < start {
199increment = -1
200}
201return intArrayToString(untilStep(start, end+increment, increment), " ")
202case 3:
203start := params[0]
204end := params[2]
205step := params[1]
206if end < start {
207increment = -1
208if step > 0 {
209return ""
210}
211}
212return intArrayToString(untilStep(start, end+increment, step), " ")
213case 2:
214start := params[0]
215end := params[1]
216step := 1
217if end < start {
218step = -1
219}
220return intArrayToString(untilStep(start, end+step, step), " ")
221default:
222return ""
223}
224}
225
226func intArrayToString(slice []int, delimeter string) string {
227return strings.Trim(strings.Join(strings.Fields(fmt.Sprint(slice)), delimeter), "[]")
228}
229