Skip to content

Commit ed1e890

Browse files
committed
poc
0 parents  commit ed1e890

File tree

4 files changed

+493
-0
lines changed

4 files changed

+493
-0
lines changed

dsl.go

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
package dsl
2+
3+
import (
4+
"crypto/md5"
5+
"crypto/sha1"
6+
"crypto/sha256"
7+
"encoding/base64"
8+
"encoding/hex"
9+
"fmt"
10+
"html"
11+
"math"
12+
"math/rand"
13+
"net/url"
14+
"strings"
15+
"time"
16+
17+
"github.com/Knetic/govaluate"
18+
"github.com/spaolacci/murmur3"
19+
)
20+
21+
const (
22+
withCutSetArgsSize = 2
23+
withMaxRandArgsSize = withCutSetArgsSize
24+
withBaseRandArgsSize = 3
25+
)
26+
27+
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
28+
var numbers = "1234567890"
29+
30+
var DefaultHelperFunctions = HelperFunctions()
31+
32+
// HelperFunctions contains the dsl functions
33+
func HelperFunctions() (functions map[string]govaluate.ExpressionFunction) {
34+
functions = make(map[string]govaluate.ExpressionFunction)
35+
36+
// strings
37+
functions["len"] = func(args ...interface{}) (interface{}, error) {
38+
length := len(toString(args[0]))
39+
40+
return float64(length), nil
41+
}
42+
43+
functions["toupper"] = func(args ...interface{}) (interface{}, error) {
44+
return strings.ToUpper(toString(args[0])), nil
45+
}
46+
47+
functions["tolower"] = func(args ...interface{}) (interface{}, error) {
48+
return strings.ToLower(toString(args[0])), nil
49+
}
50+
51+
functions["replace"] = func(args ...interface{}) (interface{}, error) {
52+
return strings.ReplaceAll(toString(args[0]), toString(args[1]), toString(args[2])), nil
53+
}
54+
55+
functions["replace_regex"] = func(args ...interface{}) (interface{}, error) {
56+
compiled, err := Regex(toString(args[1]))
57+
if err != nil {
58+
return nil, err
59+
}
60+
return compiled.ReplaceAllString(toString(args[0]), toString(args[2])), nil
61+
}
62+
63+
functions["trim"] = func(args ...interface{}) (interface{}, error) {
64+
return strings.Trim(toString(args[0]), toString(args[2])), nil
65+
}
66+
67+
functions["trimleft"] = func(args ...interface{}) (interface{}, error) {
68+
return strings.TrimLeft(toString(args[0]), toString(args[1])), nil
69+
}
70+
71+
functions["trimright"] = func(args ...interface{}) (interface{}, error) {
72+
return strings.TrimRight(toString(args[0]), toString(args[1])), nil
73+
}
74+
75+
functions["trimspace"] = func(args ...interface{}) (interface{}, error) {
76+
return strings.TrimSpace(toString(args[0])), nil
77+
}
78+
79+
functions["trimprefix"] = func(args ...interface{}) (interface{}, error) {
80+
return strings.TrimPrefix(toString(args[0]), toString(args[1])), nil
81+
}
82+
83+
functions["trimsuffix"] = func(args ...interface{}) (interface{}, error) {
84+
return strings.TrimSuffix(toString(args[0]), toString(args[1])), nil
85+
}
86+
87+
functions["reverse"] = func(args ...interface{}) (interface{}, error) {
88+
return reverseString(toString(args[0])), nil
89+
}
90+
91+
// encoding
92+
functions["base64"] = func(args ...interface{}) (interface{}, error) {
93+
sEnc := base64.StdEncoding.EncodeToString([]byte(toString(args[0])))
94+
95+
return sEnc, nil
96+
}
97+
98+
// python encodes to base64 with lines of 76 bytes terminated by new line "\n"
99+
functions["base64_py"] = func(args ...interface{}) (interface{}, error) {
100+
sEnc := base64.StdEncoding.EncodeToString([]byte(toString(args[0])))
101+
102+
return insertInto(sEnc, 76, '\n'), nil
103+
}
104+
105+
functions["base64_decode"] = func(args ...interface{}) (interface{}, error) {
106+
return base64.StdEncoding.DecodeString(toString(args[0]))
107+
}
108+
109+
functions["url_encode"] = func(args ...interface{}) (interface{}, error) {
110+
return url.PathEscape(toString(args[0])), nil
111+
}
112+
113+
functions["url_decode"] = func(args ...interface{}) (interface{}, error) {
114+
return url.PathUnescape(toString(args[0]))
115+
}
116+
117+
functions["hex_encode"] = func(args ...interface{}) (interface{}, error) {
118+
return hex.EncodeToString([]byte(toString(args[0]))), nil
119+
}
120+
121+
functions["hex_decode"] = func(args ...interface{}) (interface{}, error) {
122+
hx, _ := hex.DecodeString(toString(args[0]))
123+
return string(hx), nil
124+
}
125+
126+
functions["html_escape"] = func(args ...interface{}) (interface{}, error) {
127+
return html.EscapeString(toString(args[0])), nil
128+
}
129+
130+
functions["html_unescape"] = func(args ...interface{}) (interface{}, error) {
131+
return html.UnescapeString(toString(args[0])), nil
132+
}
133+
134+
// hashing
135+
functions["md5"] = func(args ...interface{}) (interface{}, error) {
136+
hash := md5.Sum([]byte(toString(args[0])))
137+
138+
return hex.EncodeToString(hash[:]), nil
139+
}
140+
141+
functions["sha256"] = func(args ...interface{}) (interface{}, error) {
142+
h := sha256.New()
143+
_, err := h.Write([]byte(toString(args[0])))
144+
145+
if err != nil {
146+
return nil, err
147+
}
148+
149+
return hex.EncodeToString(h.Sum(nil)), nil
150+
}
151+
152+
functions["sha1"] = func(args ...interface{}) (interface{}, error) {
153+
h := sha1.New()
154+
_, err := h.Write([]byte(toString(args[0])))
155+
156+
if err != nil {
157+
return nil, err
158+
}
159+
160+
return hex.EncodeToString(h.Sum(nil)), nil
161+
}
162+
163+
functions["mmh3"] = func(args ...interface{}) (interface{}, error) {
164+
return fmt.Sprintf("%d", int32(murmur3.Sum32WithSeed([]byte(toString(args[0])), 0))), nil
165+
}
166+
167+
// search
168+
functions["contains"] = func(args ...interface{}) (interface{}, error) {
169+
return strings.Contains(toString(args[0]), toString(args[1])), nil
170+
}
171+
172+
functions["regex"] = func(args ...interface{}) (interface{}, error) {
173+
compiled, err := Regex(toString(args[0]))
174+
if err != nil {
175+
return nil, err
176+
}
177+
178+
return compiled.MatchString(toString(args[1])), nil
179+
}
180+
181+
functions["regex_all"] = func(args ...interface{}) (interface{}, error) {
182+
for _, arg := range toSlice(args[1]) {
183+
compiled, err := Regex(toString(arg))
184+
if err != nil {
185+
return nil, err
186+
}
187+
if !compiled.MatchString(toString(args[1])) {
188+
return false, nil
189+
}
190+
}
191+
return false, nil
192+
}
193+
194+
functions["regex_any"] = func(args ...interface{}) (interface{}, error) {
195+
for _, arg := range toSlice(args[1]) {
196+
compiled, err := Regex(toString(arg))
197+
if err != nil {
198+
return nil, err
199+
}
200+
if compiled.MatchString(toString(args[1])) {
201+
return true, nil
202+
}
203+
}
204+
return false, nil
205+
}
206+
207+
functions["equals_any"] = func(args ...interface{}) (interface{}, error) {
208+
for _, arg := range toSlice(args[1]) {
209+
if args[0] == arg {
210+
return true, nil
211+
}
212+
}
213+
return false, nil
214+
}
215+
216+
functions["contains_any"] = func(args ...interface{}) (interface{}, error) {
217+
218+
for _, arg := range toSlice(args[1]) {
219+
if strings.Contains(toString(args[0]), toString(arg)) {
220+
return true, nil
221+
}
222+
}
223+
return false, nil
224+
}
225+
226+
functions["contains_all"] = func(args ...interface{}) (interface{}, error) {
227+
for _, arg := range toSlice(args[1]) {
228+
if !strings.Contains(toString(args[0]), toString(arg)) {
229+
return false, nil
230+
}
231+
}
232+
return true, nil
233+
}
234+
235+
// random generators
236+
functions["rand_char"] = func(args ...interface{}) (interface{}, error) {
237+
chars := letters + numbers
238+
bad := ""
239+
if len(args) >= 1 {
240+
chars = toString(args[0])
241+
}
242+
if len(args) >= withCutSetArgsSize {
243+
bad = toString(args[1])
244+
}
245+
246+
chars = TrimAll(chars, bad)
247+
248+
return chars[rand.Intn(len(chars))], nil
249+
}
250+
251+
functions["rand_base"] = func(args ...interface{}) (interface{}, error) {
252+
l := 0
253+
bad := ""
254+
base := letters + numbers
255+
256+
if len(args) >= 1 {
257+
l = args[0].(int)
258+
}
259+
if len(args) >= withCutSetArgsSize {
260+
bad = toString(args[1])
261+
}
262+
if len(args) >= withBaseRandArgsSize {
263+
base = toString(args[2])
264+
}
265+
266+
base = TrimAll(base, bad)
267+
268+
return RandSeq(base, l), nil
269+
}
270+
271+
functions["rand_text_alphanumeric"] = func(args ...interface{}) (interface{}, error) {
272+
l := 0
273+
bad := ""
274+
chars := letters + numbers
275+
276+
if len(args) >= 1 {
277+
l = args[0].(int)
278+
}
279+
if len(args) >= withCutSetArgsSize {
280+
bad = toString(args[1])
281+
}
282+
283+
chars = TrimAll(chars, bad)
284+
285+
return RandSeq(chars, l), nil
286+
}
287+
288+
functions["rand_text_alpha"] = func(args ...interface{}) (interface{}, error) {
289+
l := 0
290+
bad := ""
291+
chars := letters
292+
293+
if len(args) >= 1 {
294+
l = args[0].(int)
295+
}
296+
if len(args) >= withCutSetArgsSize {
297+
bad = toString(args[1])
298+
}
299+
300+
chars = TrimAll(chars, bad)
301+
302+
return RandSeq(chars, l), nil
303+
}
304+
305+
functions["rand_text_numeric"] = func(args ...interface{}) (interface{}, error) {
306+
l := 0
307+
bad := ""
308+
chars := numbers
309+
310+
if len(args) >= 1 {
311+
l = args[0].(int)
312+
}
313+
if len(args) >= withCutSetArgsSize {
314+
bad = toString(args[1])
315+
}
316+
317+
chars = TrimAll(chars, bad)
318+
319+
return RandSeq(chars, l), nil
320+
}
321+
322+
functions["rand_int"] = func(args ...interface{}) (interface{}, error) {
323+
min := 0
324+
max := math.MaxInt32
325+
326+
if len(args) >= 1 {
327+
min = args[0].(int)
328+
}
329+
if len(args) >= withMaxRandArgsSize {
330+
max = args[1].(int)
331+
}
332+
333+
return rand.Intn(max-min) + min, nil
334+
}
335+
336+
// Time Functions
337+
functions["waitfor"] = func(args ...interface{}) (interface{}, error) {
338+
seconds := args[0].(float64)
339+
time.Sleep(time.Duration(seconds) * time.Second)
340+
return true, nil
341+
}
342+
343+
return functions
344+
}

0 commit comments

Comments
 (0)