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