-
Notifications
You must be signed in to change notification settings - Fork 9
/
formatter.go
118 lines (96 loc) · 3.23 KB
/
formatter.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
package utils
import (
"fmt"
"github.com/PxyUp/fitter/pkg/builder"
"github.com/PxyUp/fitter/pkg/references"
"github.com/tidwall/gjson"
"html"
"os"
"strings"
)
const (
jsonPathStart = "{{{"
jsonPathEnd = "}}}"
placeHolder = "{PL}"
indexPlaceHolder = "{INDEX}"
humanIndexPlaceHolder = "{HUMAN_INDEX}"
refNamePrefix = "RefName="
envNamePrefix = "FromEnv="
exprNamePrefix = "FromExp="
inputNamePrefix = "FromInput="
)
func Format(str string, value builder.Interfacable, index *uint32, input builder.Interfacable) string {
if len(str) == 0 {
return str
}
if strings.Contains(str, placeHolder) && value != nil && (value.ToJson() != builder.EmptyString && len(value.ToJson()) != 0) {
str = strings.ReplaceAll(str, placeHolder, html.UnescapeString(value.ToJson()))
}
if strings.Contains(str, indexPlaceHolder) && index != nil {
str = strings.ReplaceAll(str, indexPlaceHolder, fmt.Sprintf("%d", *index))
}
if strings.Contains(str, humanIndexPlaceHolder) && index != nil {
str = strings.ReplaceAll(str, humanIndexPlaceHolder, fmt.Sprintf("%d", *index+1))
}
return formatJsonPathString(str, value, index, input)
}
func processPrefix(prefix string, value builder.Interfacable, index *uint32, input builder.Interfacable) string {
if strings.HasPrefix(prefix, inputNamePrefix) {
path := strings.TrimPrefix(prefix, inputNamePrefix)
tmp := ""
if input != nil {
if path == "" || path == "." {
tmp = html.UnescapeString(gjson.Parse(input.ToJson()).String())
} else {
tmp = gjson.Parse(html.UnescapeString(input.ToJson())).Get(path).String()
}
}
return builder.PureString(tmp).ToJson()
}
if strings.HasPrefix(prefix, refNamePrefix) {
refValue := strings.Split(strings.TrimPrefix(prefix, refNamePrefix), " ")
tmp := ""
if len(refValue) > 1 {
tmp = gjson.Parse(html.UnescapeString(references.Get(refValue[0]).ToJson())).Get(refValue[1]).String()
}
if len(refValue) == 1 {
tmp = html.UnescapeString(references.Get(refValue[0]).ToJson())
}
return builder.PureString(tmp).ToJson()
}
if strings.HasPrefix(prefix, exprNamePrefix) {
raw, err := ProcessExpression(strings.TrimPrefix(prefix, exprNamePrefix), value, index, input)
if err != nil {
return builder.EMPTY.ToJson()
}
return builder.PureString(raw.ToJson()).ToJson()
}
if strings.HasPrefix(prefix, envNamePrefix) {
envValue := strings.TrimPrefix(prefix, envNamePrefix)
return builder.PureString(os.Getenv(envValue)).ToJson()
}
if value == nil {
return builder.EMPTY.ToJson()
}
return gjson.Parse(value.ToJson()).Get(prefix).String()
}
func formatJsonPathString(str string, value builder.Interfacable, index *uint32, input builder.Interfacable) string {
runes := []rune(str)
stack := []string{
"",
}
for i := 0; i < len(runes); i++ {
stack[len(stack)-1] += string(runes[i])
last := stack[len(stack)-1]
if len(stack) > 1 && strings.HasSuffix(last, jsonPathEnd) {
tmp := processPrefix(strings.TrimSuffix(last, jsonPathEnd), value, index, input)
stack = stack[:len(stack)-1]
stack[len(stack)-1] += tmp
}
if strings.HasSuffix(last, jsonPathStart) {
stack[len(stack)-1] = strings.TrimSuffix(last, jsonPathStart)
stack = append(stack, "")
}
}
return stack[0]
}