Skip to content

Commit f223e87

Browse files
Merge pull request #56 from mahdi-hosseini/master
Fix parse miss of structs with identical names
2 parents d569dba + 09c4579 commit f223e87

File tree

1 file changed

+86
-12
lines changed

1 file changed

+86
-12
lines changed

json-to-go.js

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function jsonToGo(json, typename, flatten = true)
1414
let go = "";
1515
let tabs = 0;
1616

17-
const seen = [];
17+
const seen = {};
1818
const stack = [];
1919
let accumulator = "";
2020
let innerTabs = 0;
@@ -84,14 +84,31 @@ function jsonToGo(json, typename, flatten = true)
8484
const keys = Object.keys(scope[i])
8585
for (let k in keys)
8686
{
87-
const keyname = keys[k];
87+
let keyname = keys[k];
8888
if (!(keyname in allFields)) {
8989
allFields[keyname] = {
9090
value: scope[i][keyname],
9191
count: 0
9292
}
9393
}
94+
else {
95+
const existingValue = allFields[keyname].value;
96+
const currentValue = scope[i][keyname];
9497

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+
}
95112
allFields[keyname].count++;
96113
}
97114
}
@@ -155,24 +172,30 @@ function jsonToGo(json, typename, flatten = true)
155172
if (flatten && depth >= 2)
156173
{
157174
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])) {
159181
stack.pop();
160182
return
161183
}
162-
seen.push(parentType);
184+
seen[parent] = scopeKeys;
185+
163186
appender(`${parentType} struct {\n`);
164187
++innerTabs;
165188
const keys = Object.keys(scope);
166189
for (let i in keys)
167190
{
168-
const keyname = keys[i];
191+
const keyname = getOriginalName(keys[i]);
169192
indenter(innerTabs)
170193
const typename = format(keyname)
171194
appender(typename+" ");
172195
parent = typename
173-
parseScope(scope[keyname], depth);
196+
parseScope(scope[keys[i]], depth);
174197
appender(' `json:"'+keyname);
175-
if (omitempty && omitempty[keyname] === true)
198+
if (omitempty && omitempty[keys[i]] === true)
176199
{
177200
appender(',omitempty');
178201
}
@@ -188,15 +211,14 @@ function jsonToGo(json, typename, flatten = true)
188211
const keys = Object.keys(scope);
189212
for (let i in keys)
190213
{
191-
const keyname = keys[i];
214+
const keyname = getOriginalName(keys[i]);
192215
indent(tabs);
193216
const typename = format(keyname);
194217
append(typename+" ");
195218
parent = typename
196-
parseScope(scope[keyname], depth);
197-
219+
parseScope(scope[keys[i]], depth);
198220
append(' `json:"'+keyname);
199-
if (omitempty && omitempty[keyname] === true)
221+
if (omitempty && omitempty[keys[i]] === true)
200222
{
201223
append(',omitempty');
202224
}
@@ -320,6 +342,58 @@ function jsonToGo(json, typename, flatten = true)
320342
return sep + frag;
321343
});
322344
}
345+
346+
function uuidv4() {
347+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/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-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-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+
}
323397
}
324398

325399
if (typeof module != 'undefined') {
@@ -331,4 +405,4 @@ if (typeof module != 'undefined') {
331405
} else {
332406
module.exports = jsonToGo
333407
}
334-
}
408+
}

0 commit comments

Comments
 (0)