-
Notifications
You must be signed in to change notification settings - Fork 0
/
modifier.go
131 lines (106 loc) · 3.31 KB
/
modifier.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
128
129
130
131
package eyaml
import (
"fmt"
"github.com/goccy/go-yaml/token"
"strings"
"unicode"
"github.com/goccy/go-yaml/ast"
)
type modifyFunc func([]byte) ([]byte, error)
func modify(node ast.Node, modifier modifyFunc) {
switch stringyNode := node.(type) {
case *ast.LiteralNode:
modifyLiteral(stringyNode, modifier)
case *ast.StringNode:
modifyString(stringyNode, modifier)
}
// Both the Node.Value and Token.Origin/Value store the same string
// value separately. However, Token.Origin is used when node.String()
// is called; which will be done during printing the nodes back to the
// file after encryption
}
func modifyLiteral(node *ast.LiteralNode, modifier modifyFunc) {
stringNode := node.Value
//if secretbox.IsBoxedMessage([]byte(stringNode.Value)) {
// return
//}
newNodeValue, err := modifyAndReapplyWhitespace(stringNode.Value, modifier)
if err != nil {
fmt.Println("Unable to modify node value: ", err)
return
}
var newTokenOrigin string
if node.GetToken().Prev.Type == token.SequenceEntryType {
newTokenOrigin, err = modifyAndReapplyWhitespaceForSequenceEntry(stringNode.GetToken().Origin, modifier)
} else {
newTokenOrigin, err = modifyAndReapplyWhitespace(stringNode.GetToken().Origin, modifier)
}
if err != nil {
fmt.Println("Unable to modify token origin: ", err)
return
}
newTokenValue, err := modifyAndReapplyWhitespace(stringNode.GetToken().Value, modifier)
if err != nil {
fmt.Println("Unable to modify token value: ", err)
return
}
stringNode.Value = newNodeValue
stringNode.GetToken().Origin = newTokenOrigin
stringNode.GetToken().Value = newTokenValue
}
func modifyString(node *ast.StringNode, modifier modifyFunc) {
//if secretbox.IsBoxedMessage([]byte(node.Value)) {
// return
//}
newNodeValue, err := modifyAndReapplyWhitespace(node.Value, modifier)
if err != nil {
fmt.Println("Unable to modify node value: ", err)
return
}
newTokenOrigin, err := modifyAndReapplyWhitespace(node.GetToken().Origin, modifier)
if err != nil {
fmt.Println("Unable to modify token origin: ", err)
return
}
newTokenValue, err := modifyAndReapplyWhitespace(node.GetToken().Value, modifier)
if err != nil {
fmt.Println("Unable to modify token value: ", err)
return
}
node.Value = newNodeValue
node.GetToken().Origin = newTokenOrigin
node.GetToken().Value = newTokenValue
}
func grabWhiteSpace(origin string) string {
nonWhitespaceSeeker := func(char rune) bool {
return !unicode.IsSpace(char)
}
i := strings.IndexFunc(origin, nonWhitespaceSeeker)
return strings.Repeat(" ", i)
}
func modifyAndReapplyWhitespace(message string, modify modifyFunc) (string, error) {
spaces := grabWhiteSpace(message)
modifiedBytes, err := modify(
[]byte(strings.TrimSpace(message)),
)
if err != nil {
return "", err
}
return fmt.Sprintf("%s%s", spaces, string(modifiedBytes)), nil
}
func modifyAndReapplyWhitespaceForSequenceEntry(message string, modify modifyFunc) (string, error) {
splitLines := strings.Split(message, "\n")
// drop an empty string that gets left behind no the split
splitLines = splitLines[:len(splitLines)-1]
for i, line := range splitLines {
splitLines[i] = strings.TrimSpace(line)
}
scrubedMessage := strings.Join(splitLines, "\n")
modifiedBytes, err := modify(
[]byte(scrubedMessage),
)
if err != nil {
return "", err
}
return string(modifiedBytes), nil
}