-
Notifications
You must be signed in to change notification settings - Fork 0
/
original_method.go
91 lines (74 loc) · 1.81 KB
/
original_method.go
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
package mm
import "reflect"
// OriginalMethod ...
type OriginalMethod struct {
name string
m reflect.Value
}
// OriginalMethodNew ...
func OriginalMethodNew(methodName string, method interface{}) (o *OriginalMethod, ok bool) {
if !IsMethod(method) {
ok = false
return
}
v := OriginalMethod{
name: methodName,
m: reflect.ValueOf(method),
}
o = &v
ok = true
return
}
// Apply ...
func (o *OriginalMethod) Apply(input []reflect.Value) (output []reflect.Value) {
fullKey := getFullKey(o.m.Interface())
respQueue := GetLocalRespQueue(fullKey)
element, ok := respQueue.Shift()
if !ok {
// fall back to original method if resp queue is empty
output = o.m.Call(input)
if currentLogger != nil {
outputElements := ValueSliceToInterfaceSlice(output)
currentLogger(o.name, false, outputElements)
}
} else if fakeFunc, yes := isTempImpl(element); yes {
f := reflect.ValueOf(fakeFunc.impl)
// call the fakefunc and reply
output = f.Call(input)
if currentLogger != nil {
outputElements := ValueSliceToInterfaceSlice(output)
currentLogger(o.name, true, outputElements)
}
} else {
// use first resp in the queue
t := o.m.Type()
output = make([]reflect.Value, len(element))
for i, v := range element {
if v == nil {
output[i] = reflect.Zero(t.Out(i))
} else {
output[i] = reflect.ValueOf(v).Convert(t.Out(i))
}
}
if currentLogger != nil {
outputElements := ValueSliceToInterfaceSlice(output)
currentLogger(o.name, true, outputElements)
}
}
return
}
func isTempImpl(element []interface{}) (f tempImpl, yes bool) {
if len(element) != 1 {
return
}
f, yes = element[0].(tempImpl)
if f.impl == nil {
yes = false
}
return
}
// MakeFunc ...
func (o *OriginalMethod) MakeFunc() (f reflect.Value) {
f = reflect.MakeFunc(o.m.Type(), o.Apply)
return
}