@@ -14,7 +14,7 @@ function jsonToGo(json, typename, flatten = true)
14
14
let go = "" ;
15
15
let tabs = 0 ;
16
16
17
- const seen = [ ] ;
17
+ const seen = { } ;
18
18
const stack = [ ] ;
19
19
let accumulator = "" ;
20
20
let innerTabs = 0 ;
@@ -84,14 +84,31 @@ function jsonToGo(json, typename, flatten = true)
84
84
const keys = Object . keys ( scope [ i ] )
85
85
for ( let k in keys )
86
86
{
87
- const keyname = keys [ k ] ;
87
+ let keyname = keys [ k ] ;
88
88
if ( ! ( keyname in allFields ) ) {
89
89
allFields [ keyname ] = {
90
90
value : scope [ i ] [ keyname ] ,
91
91
count : 0
92
92
}
93
93
}
94
+ else {
95
+ const existingValue = allFields [ keyname ] . value ;
96
+ const currentValue = scope [ i ] [ keyname ] ;
94
97
98
+ if ( compareObjects ( existingValue , currentValue ) ) {
99
+ const comparisonResult = compareObjectKeys (
100
+ Object . keys ( currentValue ) ,
101
+ Object . keys ( existingValue )
102
+ )
103
+ if ( ! comparisonResult ) {
104
+ keyname = `${ keyname } _${ uuidv4 ( ) } ` ;
105
+ allFields [ keyname ] = {
106
+ value : currentValue ,
107
+ count : 0
108
+ } ;
109
+ }
110
+ }
111
+ }
95
112
allFields [ keyname ] . count ++ ;
96
113
}
97
114
}
@@ -155,24 +172,30 @@ function jsonToGo(json, typename, flatten = true)
155
172
if ( flatten && depth >= 2 )
156
173
{
157
174
const parentType = `type ${ parent } ` ;
158
- if ( seen . includes ( parentType ) ) {
175
+ const scopeKeys = formatScopeKeys ( Object . keys ( scope ) ) ;
176
+
177
+ // this can only handle two duplicate items
178
+ // future improvement will handle the case where there could
179
+ // three or more duplicate keys with different values
180
+ if ( parent in seen && compareObjectKeys ( scopeKeys , seen [ parent ] ) ) {
159
181
stack . pop ( ) ;
160
182
return
161
183
}
162
- seen . push ( parentType ) ;
184
+ seen [ parent ] = scopeKeys ;
185
+
163
186
appender ( `${ parentType } struct {\n` ) ;
164
187
++ innerTabs ;
165
188
const keys = Object . keys ( scope ) ;
166
189
for ( let i in keys )
167
190
{
168
- const keyname = keys [ i ] ;
191
+ const keyname = getOriginalName ( keys [ i ] ) ;
169
192
indenter ( innerTabs )
170
193
const typename = format ( keyname )
171
194
appender ( typename + " " ) ;
172
195
parent = typename
173
- parseScope ( scope [ keyname ] , depth ) ;
196
+ parseScope ( scope [ keys [ i ] ] , depth ) ;
174
197
appender ( ' `json:"' + keyname ) ;
175
- if ( omitempty && omitempty [ keyname ] === true )
198
+ if ( omitempty && omitempty [ keys [ i ] ] === true )
176
199
{
177
200
appender ( ',omitempty' ) ;
178
201
}
@@ -188,15 +211,14 @@ function jsonToGo(json, typename, flatten = true)
188
211
const keys = Object . keys ( scope ) ;
189
212
for ( let i in keys )
190
213
{
191
- const keyname = keys [ i ] ;
214
+ const keyname = getOriginalName ( keys [ i ] ) ;
192
215
indent ( tabs ) ;
193
216
const typename = format ( keyname ) ;
194
217
append ( typename + " " ) ;
195
218
parent = typename
196
- parseScope ( scope [ keyname ] , depth ) ;
197
-
219
+ parseScope ( scope [ keys [ i ] ] , depth ) ;
198
220
append ( ' `json:"' + keyname ) ;
199
- if ( omitempty && omitempty [ keyname ] === true )
221
+ if ( omitempty && omitempty [ keys [ i ] ] === true )
200
222
{
201
223
append ( ',omitempty' ) ;
202
224
}
@@ -320,6 +342,58 @@ function jsonToGo(json, typename, flatten = true)
320
342
return sep + frag ;
321
343
} ) ;
322
344
}
345
+
346
+ function uuidv4 ( ) {
347
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' . replace ( / [ x y ] / g, function ( c ) {
348
+ var r = Math . random ( ) * 16 | 0 , v = c == 'x' ? r : ( r & 0x3 | 0x8 ) ;
349
+ return v . toString ( 16 ) ;
350
+ } ) ;
351
+ }
352
+
353
+ function getOriginalName ( unique ) {
354
+ const reLiteralUUID = / ^ [ 0 - 9 a - f ] { 8 } - [ 0 - 9 a - f ] { 4 } - [ 1 - 5 ] [ 0 - 9 a - f ] { 3 } - [ 8 9 a b ] [ 0 - 9 a - f ] { 3 } - [ 0 - 9 a - f ] { 12 } $ / i
355
+ const uuidLength = 36 ;
356
+
357
+ if ( unique . length >= uuidLength ) {
358
+ const tail = unique . substr ( - uuidLength ) ;
359
+ if ( reLiteralUUID . test ( tail ) ) {
360
+ return unique . slice ( 0 , - 1 * ( uuidLength + 1 ) )
361
+ }
362
+ }
363
+ return unique
364
+ }
365
+
366
+ function compareObjects ( objectA , objectB ) {
367
+ const object = "[object Object]" ;
368
+ return Object . prototype . toString . call ( objectA ) === object
369
+ && Object . prototype . toString . call ( objectB ) === object ;
370
+ }
371
+
372
+ function compareObjectKeys ( itemAKeys , itemBKeys ) {
373
+ const lengthA = itemAKeys . length ;
374
+ const lengthB = itemBKeys . length ;
375
+
376
+ // nothing to compare, probably identical
377
+ if ( lengthA == 0 && lengthB == 0 )
378
+ return true ;
379
+
380
+ // duh
381
+ if ( lengthA != lengthB )
382
+ return false ;
383
+
384
+ for ( let item of itemAKeys ) {
385
+ if ( ! itemBKeys . includes ( item ) )
386
+ return false ;
387
+ }
388
+ return true ;
389
+ }
390
+
391
+ function formatScopeKeys ( keys ) {
392
+ for ( let i in keys ) {
393
+ keys [ i ] = format ( keys [ i ] ) ;
394
+ }
395
+ return keys
396
+ }
323
397
}
324
398
325
399
if ( typeof module != 'undefined' ) {
@@ -331,4 +405,4 @@ if (typeof module != 'undefined') {
331
405
} else {
332
406
module . exports = jsonToGo
333
407
}
334
- }
408
+ }
0 commit comments