-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfunc.go
72 lines (60 loc) · 1.74 KB
/
func.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
package dsl
import (
"fmt"
"strconv"
"strings"
"github.com/Knetic/govaluate"
)
type dslFunction struct {
IsCacheable bool
Name string
// if numberOfArgs is defined the signature is automatically generated
NumberOfArgs int
Signatures []string
ExpressionFunction govaluate.ExpressionFunction
}
func (d dslFunction) GetSignatures() []string {
// fixed number of args implies a static signature
if d.NumberOfArgs > 0 {
args := make([]string, 0, d.NumberOfArgs)
for i := 1; i <= d.NumberOfArgs; i++ {
args = append(args, "arg"+strconv.Itoa(i))
}
argsPart := fmt.Sprintf("(%s interface{}) interface{}", strings.Join(args, ", "))
signature := d.Name + argsPart
return []string{signature}
}
// multi signatures
var signatures []string
for _, signature := range d.Signatures {
signatures = append(signatures, d.Name+signature)
}
return signatures
}
func (d dslFunction) Exec(args ...interface{}) (interface{}, error) {
// fixed number of args implies the possibility to perform matching between the expected number of args and the ones provided
if d.NumberOfArgs > 0 {
if len(args) != d.NumberOfArgs {
signatures := d.GetSignatures()
if len(signatures) > 0 {
return nil, fmt.Errorf("%w. correct method signature %q", ErrInvalidDslFunction, signatures[0])
}
return nil, ErrInvalidDslFunction
}
}
if !d.IsCacheable {
return d.ExpressionFunction(args...)
}
functionHash := d.hash()
if result, err := resultCache.Get(functionHash); err == nil {
return result, nil
}
result, err := d.ExpressionFunction(args...)
if err == nil {
_ = resultCache.Set(functionHash, result)
}
return result, err
}
func (d dslFunction) hash(args ...interface{}) string {
return fmt.Sprintf(d.Name, args...)
}