4
4
"fmt"
5
5
"math"
6
6
"reflect"
7
+ "regexp"
7
8
"strconv"
8
9
"strings"
9
10
"time"
@@ -23,17 +24,32 @@ func replaceTransient(
23
24
24
25
replaced := map [string ]any {}
25
26
for key , value := range original {
27
+ // Keep the original value.
26
28
replaced [key ] = value
29
+
30
+ // Check if the field is meant to be replaced. If not, continue.
31
+ // We also check for wildcard replacements that are meant to replace all
32
+ // fields in a slice.
27
33
replacement , isTransient := transientLookup [key ]
28
- if ! isTransient {
34
+ cleanedKey := replaceIndicesInKeys (key )
35
+ replacementCleaned , isTransientCleaned := transientLookup [cleanedKey ]
36
+ if ! isTransient && ! isTransientCleaned {
37
+ // No replacement defined, continue and keep the original value.
29
38
continue
30
39
}
40
+ if isTransientCleaned {
41
+ replacement = replacementCleaned
42
+ }
31
43
44
+ // Replace the value with the replacement value.
32
45
if replacement != nil {
33
46
replaced [key ] = replacement
34
47
continue
35
48
}
36
49
50
+ // No replacement defined, we fall back to default stable values here
51
+ // (based on type).
52
+
37
53
if stringValue , isString := value .(string ); isString {
38
54
if _ , err := time .Parse (time .RFC3339 , stringValue ); err == nil {
39
55
replaced [key ] = StableTime
@@ -82,21 +98,35 @@ func roundFields(
82
98
83
99
replaced := map [string ]any {}
84
100
for key , value := range original {
101
+ // Keep the original value.
85
102
replaced [key ] = value
103
+
104
+ // Check if the field is meant to be rounded. If not, continue.
105
+ // We also check for wildcard replacements that are meant to replace all
106
+ // fields in a slice.
107
+ cleanedKey := replaceIndicesInKeys (key )
86
108
replacement , isRounded := roundingLookup [key ]
87
- if ! isRounded {
109
+ replacementCleaned , isRoundedCleaned := roundingLookup [cleanedKey ]
110
+ if ! isRounded && ! isRoundedCleaned {
111
+ // No rounding defined, continue and keep the original value.
88
112
continue
89
113
}
114
+ if isRoundedCleaned {
115
+ replacement = replacementCleaned
116
+ }
90
117
118
+ // We don't deal with negative precision values.
91
119
if replacement < 0 {
92
120
continue
93
121
}
94
122
123
+ // Replace the value with the rounded value.
95
124
if _ , isFloat := value .(float64 ); isFloat {
96
125
replaced [key ] = round (value .(float64 ), replacement )
97
126
continue
98
127
}
99
128
129
+ // If the value was not a float, return an error.
100
130
return nil , fmt .Errorf ("field %s is not a float" , key )
101
131
}
102
132
@@ -109,6 +139,14 @@ func round(value float64, precision int) float64 {
109
139
return math .Round (value * shift ) / shift
110
140
}
111
141
142
+ var keyIndexMatcher = regexp .MustCompile (`\[\d+\]` )
143
+
144
+ // replaceIndicesInKeys replaces all the indices in a key with "[]" to make it
145
+ // easier to match them with configuration defined in jq-style.
146
+ func replaceIndicesInKeys (key string ) string {
147
+ return keyIndexMatcher .ReplaceAllString (key , "[]" )
148
+ }
149
+
112
150
/*
113
151
flatten takes a nested map and flattens it into a single level map. The
114
152
flattening roughly follows the [JSONPath] standard. Please see test function to
0 commit comments