-
Notifications
You must be signed in to change notification settings - Fork 0
/
executer.go
112 lines (93 loc) · 2.63 KB
/
executer.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package active_interaction
import (
"reflect"
"strings"
"github.com/go-playground/validator/v10"
)
func Execute[T any](interaction ActiveInteraction[T]) (T, *InteractionError) {
var validate *validator.Validate = validator.New()
var ptr reflect.Value
var value reflect.Value
ptr = reflect.New(reflect.TypeOf(interaction))
temp := ptr.Elem()
value = reflect.ValueOf(interaction)
temp.Set(value)
var t reflect.Type
if reflect.TypeOf(interaction).Kind() == reflect.Ptr {
t = reflect.TypeOf(interaction).Elem()
} else {
t = reflect.TypeOf(interaction)
}
validateHook, _ := t.FieldByName("ValidateHooks")
if value, ok := validateHook.Tag.Lookup("before"); ok {
for _, s := range strings.Split(value, "|") {
CallMethod(interaction, s)
}
}
err := validate.Struct(interaction)
if err != nil {
var result T
interactionError := interaction.AddValidatorError(err)
return result, &interactionError
}
if value, ok := validateHook.Tag.Lookup("after"); ok {
for _, s := range strings.Split(value, "|") {
CallMethod(interaction, s)
}
}
beforeExecuteHook, _ := t.FieldByName("ExecuteHooks")
if value, ok := beforeExecuteHook.Tag.Lookup("before"); ok {
for _, s := range strings.Split(value, "|") {
CallMethod(interaction, s)
}
}
val := interaction.Run()
afterExecuteHook, _ := t.FieldByName("ExecuteHooks")
if value, ok := afterExecuteHook.Tag.Lookup("after"); ok {
for _, s := range strings.Split(value, "|") {
CallMethod(interaction, s)
}
}
return val, interaction.GetError()
}
func Compose[E any, T any](
caller ActiveInteraction[E],
interaction ActiveInteraction[T],
) (T, *InteractionError) {
result, errors := Execute[T](interaction)
if errors != nil {
caller.GetError().Append(errors, reflect.TypeOf(interaction).Elem().Name())
}
return result, errors
}
func CallMethod(i interface{}, methodName string) interface{} {
var ptr reflect.Value
var value reflect.Value
var finalMethod reflect.Value
value = reflect.ValueOf(i)
// if we start with a pointer, we need to get value pointed to
// if we start with a value, we need to get a pointer to that value
if value.Type().Kind() == reflect.Ptr {
ptr = value
value = ptr.Elem()
} else {
ptr = reflect.New(reflect.TypeOf(i))
temp := ptr.Elem()
temp.Set(value)
}
// check for method on value
method := value.MethodByName(methodName)
if method.IsValid() {
finalMethod = method
}
// check for method on pointer
method = ptr.MethodByName(methodName)
if method.IsValid() {
finalMethod = method
}
if finalMethod.IsValid() {
return finalMethod.Call([]reflect.Value{})
}
// return or panic, method not found of either type
return ""
}