@@ -52,7 +52,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
5252 } ;
5353
5454
55- function parseScope ( scope , depth = 0 )
55+ function parseScope ( scope , depth = 0 , forceOmitEmptyNonArrays = false )
5656 {
5757 if ( typeof scope === "object" && scope !== null )
5858 {
@@ -82,8 +82,11 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
8282 appender ( slice ) ;
8383 else
8484 append ( slice )
85+
86+ // TODO: structs need a proper recursive solution to make merging generic
8587 if ( sliceType == "struct" ) {
8688 const allFields = { } ;
89+ let insideOmitEmpty = false ;
8790
8891 // for each field counts how many times appears
8992 for ( let i = 0 ; i < scopeLength ; i ++ )
@@ -112,6 +115,47 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
112115 }
113116
114117 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+
115159 const comparisonResult = compareObjectKeys (
116160 Object . keys ( currentValue ) ,
117161 Object . keys ( existingValue )
@@ -139,7 +183,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
139183 struct [ keyname ] = elem . value ;
140184 omitempty [ keyname ] = elem . count != scopeLength ;
141185 }
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 !!
143187 }
144188 else if ( sliceType == "slice" ) {
145189 parseScope ( scope [ 0 ] , depth )
@@ -162,7 +206,16 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
162206 append ( parent )
163207 }
164208 }
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 ) ;
166219 }
167220 }
168221 else {
@@ -175,7 +228,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
175228 }
176229 }
177230
178- function parseStruct ( depth , innerTabs , scope , omitempty , oldParents )
231+ function parseStruct ( depth , innerTabs , scope , omitempty , oldParents , insideOmitEmpty )
179232 {
180233 if ( flatten ) {
181234 stack . push (
@@ -221,7 +274,7 @@ function jsonToGo(json, typename, flatten = true, example = false, allOmitempty
221274
222275 appender ( typename + " " ) ;
223276 parent = typename
224- parseScope ( scope [ keys [ i ] ] , depth ) ;
277+ parseScope ( scope [ keys [ i ] ] , depth , insideOmitEmpty ) ;
225278 appender ( ' `json:"' + keyname ) ;
226279 if ( allOmitempty || ( omitempty && omitempty [ keys [ i ] ] === true ) )
227280 {
0 commit comments