...
1 package funk
2
3 import (
4 "fmt"
5 "reflect"
6 )
7
8 func equal(expectedOrPredicate interface{}, optionalIsMap ...bool) func(keyValueIfMap, actualValue reflect.Value) bool {
9 isMap := append(optionalIsMap, false)[0]
10
11 if IsFunction(expectedOrPredicate) {
12 inTypes := []reflect.Type{nil}; if isMap {
13 inTypes = append(inTypes, nil)
14 }
15
16 if !IsPredicate(expectedOrPredicate, inTypes...) {
17 panic(fmt.Sprintf("Predicate function must have %d parameter and must return boolean", len(inTypes)))
18 }
19
20 predicateValue := reflect.ValueOf(expectedOrPredicate)
21
22 return func(keyValueIfMap, actualValue reflect.Value) bool {
23
24 if isMap && !keyValueIfMap.Type().ConvertibleTo(predicateValue.Type().In(0)) {
25 panic("Given key is not compatible with type of parameter for the predicate.")
26 }
27
28 if (isMap && !actualValue.Type().ConvertibleTo(predicateValue.Type().In(1))) ||
29 (!isMap && !actualValue.Type().ConvertibleTo(predicateValue.Type().In(0))) {
30 panic("Given value is not compatible with type of parameter for the predicate.")
31 }
32
33 args := []reflect.Value{actualValue}
34 if isMap {
35 args = append([]reflect.Value{keyValueIfMap}, args...)
36 }
37
38 return predicateValue.Call(args)[0].Bool()
39 }
40 }
41
42 expected := expectedOrPredicate
43
44 return func(keyValueIfMap, actualValue reflect.Value) bool {
45 if isMap {
46 actualValue = keyValueIfMap
47 }
48
49 if expected == nil || actualValue.IsZero() {
50 return actualValue.Interface() == expected
51 }
52
53 return reflect.DeepEqual(actualValue.Interface(), expected)
54 }
55 }
56
57 func sliceElem(rtype reflect.Type) reflect.Type {
58 for {
59 if rtype.Kind() != reflect.Slice && rtype.Kind() != reflect.Array {
60 return rtype
61 }
62
63 rtype = rtype.Elem()
64 }
65 }
66
67 func redirectValue(value reflect.Value) reflect.Value {
68 for {
69 if !value.IsValid() || (value.Kind() != reflect.Ptr && value.Kind() != reflect.Interface) {
70 return value
71 }
72
73 res := value.Elem()
74
75
76 if res.Kind() == reflect.Ptr && value.Kind() == reflect.Ptr && value.Pointer() == res.Pointer() {
77 return value
78 }
79
80 if !res.IsValid() && value.Kind() == reflect.Ptr {
81 return reflect.Zero(value.Type().Elem())
82 }
83
84 value = res
85 }
86 }
87
88 func makeSlice(value reflect.Value, values ...int) reflect.Value {
89 sliceType := sliceElem(value.Type())
90
91 size := value.Len()
92 cap := size
93
94 if len(values) > 0 {
95 size = values[0]
96 }
97
98 if len(values) > 1 {
99 cap = values[1]
100 }
101
102 return reflect.MakeSlice(reflect.SliceOf(sliceType), size, cap)
103 }
104
View as plain text