/
var.go
127 lines (118 loc) · 2.86 KB
/
var.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package agents
import (
"errors"
"fmt"
"github.com/TeaWeb/code/teautils"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"github.com/robertkrimen/otto"
"strings"
)
// 使用某个参数执行数值运算,使用Javascript语法
func EvalParam(param string, value interface{}, old interface{}, varMapping maps.Map, supportsMath bool) (string, error) {
if old == nil {
old = value
}
var resultErr error = nil
paramValue := thresholdRegexpParamNamedVariable.ReplaceAllStringFunc(param, func(s string) string {
varName := s[2 : len(s)-1]
// 从varMapping中查找
if varMapping != nil {
index := strings.Index(varName, ".")
var firstKey = varName
if index > 0 {
firstKey = varName[:index]
}
firstKey = strings.TrimSpace(firstKey)
if varMapping.Has(firstKey) {
keys := strings.Split(varName, ".")
for index, key := range keys {
keys[index] = strings.TrimSpace(key)
}
result := teautils.Get(varMapping, keys)
if result == nil {
return ""
}
return types.String(result)
}
}
if value == nil {
return ""
}
// 支持${OLD}和${OLD.xxx}
if varName == "OLD" {
result, err := EvalParam("${0}", old, nil, nil, supportsMath)
if err != nil {
resultErr = err
}
return result
} else if strings.HasPrefix(varName, "OLD.") {
result, err := EvalParam("${"+varName[4:]+"}", old, nil, nil, supportsMath)
if err != nil {
resultErr = err
}
return result
}
switch v := value.(type) {
case string:
if varName == "0" {
return v
}
return ""
case int8, int16, int, int32, int64, uint8, uint16, uint, uint32, uint64:
if varName == "0" {
return fmt.Sprintf("%d", v)
}
return "0"
case float32, float64:
if varName == "0" {
return fmt.Sprintf("%f", v)
}
return "0"
case bool:
if varName == "0" {
if v {
return "1"
}
return "0"
}
return "0"
default:
if types.IsSlice(value) || types.IsMap(value) {
keys := strings.Split(varName, ".")
for index, key := range keys {
keys[index] = strings.TrimSpace(key)
}
result := teautils.Get(v, keys)
if result == nil {
return ""
}
return types.String(result)
}
}
return s
})
// 支持加、减、乘、除、余
if len(paramValue) > 0 {
if supportsMath && strings.ContainsAny(param, "+-*/%") {
vm := otto.New()
v, err := vm.Run(paramValue)
if err != nil {
return "", errors.New("\"" + param + "\": eval \"" + paramValue + "\":" + err.Error())
} else {
paramValue = v.String()
}
}
// javascript
if strings.HasPrefix(paramValue, "javascript:") {
vm := otto.New()
v, err := vm.Run(paramValue[len("javascript:"):])
if err != nil {
return "", errors.New("\"" + param + "\": eval \"" + paramValue + "\":" + err.Error())
} else {
paramValue = v.String()
}
}
}
return paramValue, resultErr
}