Skip to content

Commit 57fba34

Browse files
authored
Merge pull request #1 from Pexeso/usenumber
Add setting for unmarshalling JSON with UseNumber
2 parents a07d3b8 + 6bb25b5 commit 57fba34

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

orderedmap.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type OrderedMap struct {
4646
keys []string
4747
values map[string]interface{}
4848
escapeHTML bool
49+
useNumber bool
4950
}
5051

5152
func New() *OrderedMap {
@@ -60,6 +61,10 @@ func (o *OrderedMap) SetEscapeHTML(on bool) {
6061
o.escapeHTML = on
6162
}
6263

64+
func (o *OrderedMap) SetUseNumber(on bool) {
65+
o.useNumber = on
66+
}
67+
6368
func (o *OrderedMap) Get(key string) (interface{}, bool) {
6469
val, exists := o.values[key]
6570
return val, exists
@@ -125,13 +130,34 @@ func (o *OrderedMap) UnmarshalJSON(b []byte) error {
125130
return nil
126131
}
127132

133+
func unmarshalJSONUseNumber(s string, v interface{}) error {
134+
r := strings.NewReader(s)
135+
decoder := json.NewDecoder(r)
136+
decoder.UseNumber()
137+
err := decoder.Decode(v)
138+
if err != nil {
139+
return err
140+
}
141+
142+
return nil
143+
}
144+
128145
func mapStringToOrderedMap(s string, o *OrderedMap) error {
129146
// parse string into map
130147
m := map[string]interface{}{}
131-
err := json.Unmarshal([]byte(s), &m)
132-
if err != nil {
133-
return err
148+
149+
if o.useNumber {
150+
err := unmarshalJSONUseNumber(s, &m)
151+
if err != nil {
152+
return err
153+
}
154+
} else {
155+
err := json.Unmarshal([]byte(s), &m)
156+
if err != nil {
157+
return err
158+
}
134159
}
160+
135161
// Get the order of the keys
136162
orderedKeys := []KeyIndex{}
137163
for k, _ := range m {
@@ -194,6 +220,7 @@ func mapStringToOrderedMap(s string, o *OrderedMap) error {
194220
// this may be recursive it values in the map are also maps
195221
if hasValidJson {
196222
newMap := New()
223+
newMap.SetUseNumber(o.useNumber) // Preserve number setting
197224
err := mapStringToOrderedMap(valueStr, newMap)
198225
if err != nil {
199226
return err

orderedmap_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,50 @@ func TestUnmarshalJSONStruct(t *testing.T) {
400400
}
401401
}
402402

403+
func TestRemarshalJSONWithoutUseNumber(t *testing.T) {
404+
// 9007199254740993 is the smallest integer which cannot be represented exactly as a float64
405+
const input = `{"data":{"x":9007199254740993}}`
406+
const expected = `{"data":{"x":9007199254740992}}`
407+
408+
o := New()
409+
o.SetUseNumber(false)
410+
411+
err := json.Unmarshal([]byte(input), &o)
412+
if err != nil {
413+
t.Fatalf("JSON unmarshal error: %v", err)
414+
}
415+
416+
marshalled, err := json.Marshal(o)
417+
if err != nil {
418+
t.Errorf("Marshal failed: %v", err)
419+
}
420+
421+
if string(marshalled) != expected {
422+
t.Errorf("unexpected value: %s instead of %s", marshalled, expected)
423+
}
424+
}
425+
426+
func TestRemarshalJSONUseNumber(t *testing.T) {
427+
const input = `{"data":{"x":9007199254740993}}`
428+
429+
o := New()
430+
o.SetUseNumber(true)
431+
432+
err := json.Unmarshal([]byte(input), &o)
433+
if err != nil {
434+
t.Fatalf("JSON unmarshal error: %v", err)
435+
}
436+
437+
marshalled, err := json.Marshal(o)
438+
if err != nil {
439+
t.Errorf("Marshal failed: %v", err)
440+
}
441+
442+
if string(marshalled) != input {
443+
t.Errorf("unexpected value: %s instead of %s", marshalled, input)
444+
}
445+
}
446+
403447
func TestOrderedMap_SortKeys(t *testing.T) {
404448
s := `
405449
{

0 commit comments

Comments
 (0)