1 package funk
2
3 import (
4 "bytes"
5 "math/rand"
6 "reflect"
7 )
8
9 var numericZeros = []interface{}{
10 int(0),
11 int8(0),
12 int16(0),
13 int32(0),
14 int64(0),
15 uint(0),
16 uint8(0),
17 uint16(0),
18 uint32(0),
19 uint64(0),
20 float32(0),
21 float64(0),
22 }
23
24
25 func ToFloat64(x interface{}) (float64, bool) {
26 var xf float64
27 xok := true
28
29 switch xn := x.(type) {
30 case uint8:
31 xf = float64(xn)
32 case uint16:
33 xf = float64(xn)
34 case uint32:
35 xf = float64(xn)
36 case uint64:
37 xf = float64(xn)
38 case int:
39 xf = float64(xn)
40 case int8:
41 xf = float64(xn)
42 case int16:
43 xf = float64(xn)
44 case int32:
45 xf = float64(xn)
46 case int64:
47 xf = float64(xn)
48 case float32:
49 xf = float64(xn)
50 case float64:
51 xf = float64(xn)
52 default:
53 xok = false
54 }
55
56 return xf, xok
57 }
58
59
60 func PtrOf(itf interface{}) interface{} {
61 t := reflect.TypeOf(itf)
62
63 cp := reflect.New(t)
64 cp.Elem().Set(reflect.ValueOf(itf))
65
66
67 if t.Kind() == reflect.Ptr {
68 return cp.Elem().Interface()
69 }
70
71 return cp.Interface()
72 }
73
74
75 func IsFunction(in interface{}, num ...int) bool {
76 funcType := reflect.TypeOf(in)
77
78 result := funcType != nil && funcType.Kind() == reflect.Func
79
80 if len(num) >= 1 {
81 result = result && funcType.NumIn() == num[0]
82 }
83
84 if len(num) == 2 {
85 result = result && funcType.NumOut() == num[1]
86 }
87
88 return result
89 }
90
91
92 func IsPredicate(in interface{}, inTypes ...reflect.Type) bool {
93 if len(inTypes) == 0 {
94 inTypes = append(inTypes, nil)
95 }
96
97 funcType := reflect.TypeOf(in)
98
99 result := funcType != nil && funcType.Kind() == reflect.Func
100
101 result = result && funcType.NumOut() == 1 && funcType.Out(0).Kind() == reflect.Bool
102 result = result && funcType.NumIn() == len(inTypes)
103
104 for i := 0; result && i < len(inTypes); i++ {
105 inType := inTypes[i]
106 result = inType == nil || inType.ConvertibleTo(funcType.In(i))
107 }
108
109 return result
110 }
111
112
113 func IsEqual(expected interface{}, actual interface{}) bool {
114 if expected == nil || actual == nil {
115 return expected == actual
116 }
117
118 if exp, ok := expected.([]byte); ok {
119 act, ok := actual.([]byte)
120 if !ok {
121 return false
122 }
123
124 if exp == nil || act == nil {
125 return true
126 }
127
128 return bytes.Equal(exp, act)
129 }
130
131 return reflect.DeepEqual(expected, actual)
132
133 }
134
135
136 func IsType(expected interface{}, actual interface{}) bool {
137 return IsEqual(reflect.TypeOf(expected), reflect.TypeOf(actual))
138 }
139
140
141 func Equal(expected interface{}, actual interface{}) bool {
142 return IsEqual(expected, actual)
143 }
144
145
146 func NotEqual(expected interface{}, actual interface{}) bool {
147 return !IsEqual(expected, actual)
148 }
149
150
151 func IsIteratee(in interface{}) bool {
152 if in == nil {
153 return false
154 }
155 arrType := reflect.TypeOf(in)
156
157 kind := arrType.Kind()
158
159 return kind == reflect.Array || kind == reflect.Slice || kind == reflect.Map
160 }
161
162
163 func IsCollection(in interface{}) bool {
164 arrType := reflect.TypeOf(in)
165
166 kind := arrType.Kind()
167
168 return kind == reflect.Array || kind == reflect.Slice
169 }
170
171
172 func SliceOf(in interface{}) interface{} {
173 value := reflect.ValueOf(in)
174
175 sliceType := reflect.SliceOf(reflect.TypeOf(in))
176 slice := reflect.New(sliceType)
177 sliceValue := reflect.MakeSlice(sliceType, 0, 0)
178 sliceValue = reflect.Append(sliceValue, value)
179 slice.Elem().Set(sliceValue)
180
181 return slice.Elem().Interface()
182 }
183
184
185 func Any(objs ...interface{}) bool {
186 if len(objs) == 0 {
187 return false
188 }
189
190 for _, obj := range objs {
191 if !IsEmpty(obj) {
192 return true
193 }
194 }
195
196 return false
197 }
198
199
200 func All(objs ...interface{}) bool {
201 if len(objs) == 0 {
202 return true
203 }
204
205 for _, obj := range objs {
206 if IsEmpty(obj) {
207 return false
208 }
209 }
210
211 return true
212 }
213
214
215 func IsEmpty(obj interface{}) bool {
216 if obj == nil || obj == "" || obj == false {
217 return true
218 }
219
220 for _, v := range numericZeros {
221 if obj == v {
222 return true
223 }
224 }
225
226 objValue := reflect.ValueOf(obj)
227
228 switch objValue.Kind() {
229 case reflect.Map:
230 fallthrough
231 case reflect.Slice, reflect.Chan:
232 return objValue.Len() == 0
233 case reflect.Struct:
234 return reflect.DeepEqual(obj, ZeroOf(obj))
235 case reflect.Ptr:
236 if objValue.IsNil() {
237 return true
238 }
239
240 obj = redirectValue(objValue).Interface()
241
242 return reflect.DeepEqual(obj, ZeroOf(obj))
243 }
244
245 return false
246 }
247
248
249 func IsZero(obj interface{}) bool {
250 if obj == nil || obj == "" || obj == false {
251 return true
252 }
253
254 for _, v := range numericZeros {
255 if obj == v {
256 return true
257 }
258 }
259
260 return reflect.DeepEqual(obj, ZeroOf(obj))
261 }
262
263
264 func NotEmpty(obj interface{}) bool {
265 return !IsEmpty(obj)
266 }
267
268
269 func ZeroOf(in interface{}) interface{} {
270 if in == nil {
271 return nil
272 }
273
274 return reflect.Zero(reflect.TypeOf(in)).Interface()
275 }
276
277
278 func RandomInt(min, max int) int {
279 return min + rand.Intn(max-min)
280 }
281
282
283 func Shard(str string, width int, depth int, restOnly bool) []string {
284 var results []string
285
286 for i := 0; i < depth; i++ {
287 results = append(results, str[(width*i):(width*(i+1))])
288 }
289
290 if restOnly {
291 results = append(results, str[(width*depth):])
292 } else {
293 results = append(results, str)
294 }
295
296 return results
297 }
298
299 var defaultLetters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
300
301
302 func RandomString(n int, allowedChars ...[]rune) string {
303 var letters []rune
304
305 if len(allowedChars) == 0 {
306 letters = defaultLetters
307 } else {
308 letters = allowedChars[0]
309 }
310
311 b := make([]rune, n)
312 for i := range b {
313 b[i] = letters[rand.Intn(len(letters))]
314 }
315
316 return string(b)
317 }
318
View as plain text