-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathfunctions.go
More file actions
98 lines (89 loc) · 2.12 KB
/
functions.go
File metadata and controls
98 lines (89 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package mexpr
import "reflect"
func schemaForScalarType(t reflect.Type) (*schema, bool) {
switch t.Kind() {
case reflect.Bool:
return schemaBool, true
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return schemaNumber, true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return schemaNumber, true
case reflect.Float32, reflect.Float64:
return schemaNumber, true
case reflect.String:
return schemaString, true
}
return nil, false
}
func getFunctionSchema(v any) (*schema, bool) {
t := reflect.TypeOf(v)
if t == nil || t.Kind() != reflect.Func || t.IsVariadic() || t.NumOut() != 1 {
return nil, false
}
result, ok := schemaForScalarType(t.Out(0))
if !ok {
return nil, false
}
s := newSchema(typeFunction)
s.result = result
s.parameters = make([]*schema, t.NumIn())
for i := 0; i < t.NumIn(); i++ {
param, ok := schemaForScalarType(t.In(i))
if !ok {
return nil, false
}
s.parameters[i] = param
}
return s, true
}
func resolveLazyValue(v any) (any, bool) {
switch fn := v.(type) {
case nil:
return nil, false
case bool, string, []byte:
return nil, false
case int, int8, int16, int32, int64:
return nil, false
case uint, uint8, uint16, uint32, uint64:
return nil, false
case float32, float64:
return nil, false
case []any, []int, []float64, []string:
return nil, false
case map[string]any, map[any]any:
return nil, false
case func() bool:
return fn(), true
case func() int:
return fn(), true
case func() int8:
return fn(), true
case func() int16:
return fn(), true
case func() int32:
return fn(), true
case func() int64:
return fn(), true
case func() uint:
return fn(), true
case func() uint8:
return fn(), true
case func() uint16:
return fn(), true
case func() uint32:
return fn(), true
case func() uint64:
return fn(), true
case func() float32:
return fn(), true
case func() float64:
return fn(), true
case func() string:
return fn(), true
}
s, ok := getFunctionSchema(v)
if !ok || len(s.parameters) != 0 {
return nil, false
}
return reflect.ValueOf(v).Call(nil)[0].Interface(), true
}