forked from project-flogo/core
/
template.go
106 lines (87 loc) · 1.91 KB
/
template.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
package expression
import (
"bytes"
"strings"
"github.com/qingcloudhx/core/data"
"github.com/qingcloudhx/core/data/coerce"
)
func IsTemplateExpr(exprStr string) bool {
//todo fix this
return strings.Contains(exprStr, "{{")
}
// NewTemplateExpr creates a new Template Expr, the template only supports
// non-nested double braces as embedded expression tokens {{ }}
func NewTemplateExpr(exprStr string, factory Factory) (Expr, error) {
exprs, err := parse(exprStr, factory)
if err != nil {
return nil, err
}
return &templateExpr{exprs: exprs}, nil
}
type templateExpr struct {
exprs []Expr
}
func (s *templateExpr) Eval(scope data.Scope) (interface{}, error) {
var buffer bytes.Buffer
for _, expr := range s.exprs {
v, err := expr.Eval(scope)
if err != nil {
return nil, err
}
str, err := coerce.ToString(v)
if err != nil {
return nil, err
}
buffer.WriteString(str)
}
return buffer.String(), nil
}
//stringExpr simple wrapper for a string
type stringExpr struct {
str string
}
func (s *stringExpr) Eval(scope data.Scope) (interface{}, error) {
return s.str, nil
}
func parse(s string, f Factory) ([]Expr, error) {
strLen := len(s)
var ss []Expr
start := 0
for i := 0; i < strLen; i++ {
if s[i] == '{' {
if s[i+1] == '{' {
j := i + 2
newStart := j
closed := false
for j < len(s) {
if s[j] == '}' {
if j+1 < strLen && s[j+1] == '}' {
if i > 0 {
ss = append(ss, &stringExpr{str: s[start:i]})
}
e, err := f.NewExpr(s[newStart:j])
if err != nil {
return nil, err
}
ss = append(ss, e)
i = j + 2
start = i
closed = true
break
}
}
j++
}
if !closed {
//todo should we throw an error?
ss = append(ss, &stringExpr{str: s[start:]})
start = len(s)
}
}
}
}
if start != len(s) {
ss = append(ss, &stringExpr{str: s[start:]})
}
return ss, nil
}