-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexecutor.go
More file actions
127 lines (107 loc) · 2.88 KB
/
executor.go
File metadata and controls
127 lines (107 loc) · 2.88 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package structprompt
import (
"fmt"
"reflect"
"strconv"
"strings"
"git.modulus.eu/go/common/types/uuid"
)
type executor struct {
i interface{}
}
func (e *executor) execute(s string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Failed to call method: ", r)
}
}()
currentValue := reflect.ValueOf(e.i)
currentPathField := ""
structArgument := false
var methodToCall reflect.Value
var methodToCallType reflect.Type
var arguments []reflect.Value
var currentArgumentType reflect.Type
var currentStructArgument reflect.Value
var currentStructArgumentType reflect.Type
var currentStructArgumentFieldType reflect.Type
var currentStructArgumentField string
var token Token
var tokenValue string
lexer := NewLexer(s)
for {
token = lexer.NextToken()
tokenValue = strings.TrimSpace(token.Value)
if token.Type == TOKEN_EOF {
break
}
switch token.Type {
case TOKEN_DOT:
currentValue = reflect.Indirect(currentValue.FieldByName(currentPathField))
case TOKEN_PATH_ELEMENT:
currentPathField = tokenValue
case TOKEN_METHOD:
methodToCall = currentValue.MethodByName(tokenValue)
methodToCallType = methodToCall.Type()
case TOKEN_METHOD_ARGUMENT:
if !structArgument {
currentArgumentType = methodToCallType.In(len(arguments))
arguments = append(arguments, convertArgument(currentArgumentType, tokenValue))
} else {
structArgument = false
}
case TOKEN_LEFT_CURLY_BRACKET:
currentStructArgumentType = methodToCallType.In(len(arguments))
currentStructArgument = reflect.New(currentStructArgumentType).Elem()
case TOKEN_FIELD:
currentStructArgumentField = tokenValue
currentStructArgumentFieldType = currentStructArgument.FieldByName(tokenValue).Type()
case TOKEN_FIELD_VALUE:
currentStructArgument.FieldByName(currentStructArgumentField).Set(
convertArgument(currentStructArgumentFieldType, tokenValue),
)
case TOKEN_RIGHT_CURLY_BRACKET:
structArgument = true
arguments = append(arguments, currentStructArgument)
}
}
fmt.Println(arguments, len(arguments))
callMethod(methodToCall, arguments)
}
func convertArgument(argument reflect.Type, s string) reflect.Value {
switch argument.Kind() {
case reflect.Int:
res, err := strconv.Atoi(s)
if err != nil {
panic("DSADS")
}
return reflect.ValueOf(res)
// ...
case reflect.Struct:
s = strings.Trim(s, "\"")
switch argument.Name() {
case "UUID":
return reflect.ValueOf(uuid.FromString(s))
default:
return reflect.ValueOf(s)
}
default:
return reflect.ValueOf(s)
}
}
func callMethod(methodToCall reflect.Value, arguments []reflect.Value) {
ret := methodToCall.Call(arguments)
for _, v := range ret {
switch v.Kind() {
case reflect.Slice:
fmt.Println("\t[")
for i := 0; i < v.Len(); i++ {
fmt.Printf("\t\t%+v\n", v.Index(i))
}
fmt.Println("\t]")
default:
fmt.Printf("\t%+v\n", v.Interface())
}
}
fmt.Println()
}