@@ -52,7 +52,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
52
52
} ;
53
53
54
54
55
- function parseScope ( scope , depth = 0 )
55
+ function parseScope ( scope , depth = 0 , forceOmitEmptyNonArrays = false )
56
56
{
57
57
if ( typeof scope === "object" && scope !== null )
58
58
{
@@ -82,8 +82,11 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
82
82
appender ( slice ) ;
83
83
else
84
84
append ( slice )
85
+
86
+ // TODO: structs need a proper recursive solution to make merging generic
85
87
if ( sliceType == "struct" ) {
86
88
const allFields = { } ;
89
+ let insideOmitEmpty = false ;
87
90
88
91
// for each field counts how many times appears
89
92
for ( let i = 0 ; i < scopeLength ; i ++ )
@@ -112,6 +115,47 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
112
115
}
113
116
114
117
if ( areObjects ( existingValue , currentValue ) ) {
118
+ const currentKeys = Object . keys ( currentValue )
119
+ const existingKeys = Object . keys ( existingValue )
120
+
121
+ // try to merge two object fields instead of creating separate ones
122
+ // TODO: find a proper handling of omitempty for nested structs instead of
123
+ // fake-forcing omitempty on all nested elements
124
+ if ( existingKeys . length > 0 && currentKeys . length > 0 ) {
125
+ if ( ! allOmitempty ) {
126
+ // check if any of the existingKeys (which are assumed to be mandatory),
127
+ // is not in the currentKeys
128
+ for ( const key of existingKeys ) {
129
+ if ( ! Object . keys ( currentKeys ) . includes ( key ) ) {
130
+ insideOmitEmpty = true // TODO: only set this one key to omitempty
131
+ break
132
+ }
133
+ }
134
+ }
135
+
136
+ var mergedValues = existingValue
137
+ for ( const key of currentKeys ) {
138
+ // check if key has been found previously
139
+ if ( ! Object . keys ( mergedValues ) . includes ( key ) ) {
140
+ mergedValues [ key ] = currentValue [ key ]
141
+ insideOmitEmpty = true // TODO: only set this one key to omitempty
142
+ continue
143
+ }
144
+
145
+ // check if types between previously found values and the current value
146
+ if ( ! areSameType ( mergedValues [ key ] , currentValue [ key ] ) ) {
147
+ if ( mergedValues [ key ] !== null ) {
148
+ mergedValues [ key ] = null // force type "any" if types are not identical
149
+ console . warn ( `Warning: nested key "${ key } " uses multiple types. Defaulting to type "any".` )
150
+ }
151
+ }
152
+ }
153
+
154
+ allFields [ keyname ] . value = mergedValues ;
155
+ allFields [ keyname ] . count ++ ;
156
+ continue ;
157
+ }
158
+
115
159
const comparisonResult = compareObjectKeys (
116
160
Object . keys ( currentValue ) ,
117
161
Object . keys ( existingValue )
@@ -139,7 +183,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
139
183
struct [ keyname ] = elem . value ;
140
184
omitempty [ keyname ] = elem . count != scopeLength ;
141
185
}
142
- parseStruct ( depth + 1 , innerTabs , struct , omitempty , previousParents ) ; // finally parse the struct !!
186
+ parseStruct ( depth + 1 , innerTabs , struct , omitempty , previousParents , insideOmitEmpty ) ; // finally parse the struct !!
143
187
}
144
188
else if ( sliceType == "slice" ) {
145
189
parseScope ( scope [ 0 ] , depth )
@@ -162,7 +206,16 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
162
206
append ( parent )
163
207
}
164
208
}
165
- parseStruct ( depth + 1 , innerTabs , scope , false , previousParents ) ;
209
+
210
+ const omitempty = { } ;
211
+ if ( forceOmitEmptyNonArrays ) {
212
+ const allKeys = Object . keys ( scope )
213
+ for ( let k in allKeys ) {
214
+ const keyname = allKeys [ k ] ;
215
+ omitempty [ keyname ] = true ;
216
+ }
217
+ }
218
+ parseStruct ( depth + 1 , innerTabs , scope , omitempty , previousParents ) ;
166
219
}
167
220
}
168
221
else {
@@ -175,7 +228,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
175
228
}
176
229
}
177
230
178
- function parseStruct ( depth , innerTabs , scope , omitempty , oldParents )
231
+ function parseStruct ( depth , innerTabs , scope , omitempty , oldParents , insideOmitEmpty )
179
232
{
180
233
if ( flatten ) {
181
234
stack . push (
@@ -221,7 +274,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
221
274
222
275
appender ( typename + " " ) ;
223
276
parent = typename
224
- parseScope ( scope [ keys [ i ] ] , depth ) ;
277
+ parseScope ( scope [ keys [ i ] ] , depth , insideOmitEmpty ) ;
225
278
appender ( ' `json:"' + keyname ) ;
226
279
if ( allOmitempty || ( omitempty && omitempty [ keys [ i ] ] === true ) )
227
280
{
0 commit comments