Fixed encoding/decoding of maps.

This commit is contained in:
Victor Starodub
2016-04-12 14:10:37 +03:00
parent c58ffd2012
commit 92fdbb21de
4 changed files with 52 additions and 25 deletions
+20 -16
View File
@@ -108,25 +108,29 @@ func (g *Generator) genTypeDecoder(t reflect.Type, out string, indent int) error
elem := t.Elem()
tmpVar := g.uniqueVarName()
fmt.Fprintln(g.out, ws+"in.Delim('{')")
fmt.Fprintln(g.out, ws+"if !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+out+" = make("+g.getType(t)+")")
fmt.Fprintln(g.out, ws+"if in.IsNull() {")
fmt.Fprintln(g.out, ws+" in.Skip()")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+out+" = nil")
fmt.Fprintln(g.out, ws+" in.Delim('{')")
fmt.Fprintln(g.out, ws+" if !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+" "+out+" = make("+g.getType(t)+")")
fmt.Fprintln(g.out, ws+" } else {")
fmt.Fprintln(g.out, ws+" "+out+" = nil")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" for !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+" key := in.String()")
fmt.Fprintln(g.out, ws+" in.WantColon()")
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
g.genTypeDecoder(elem, tmpVar, indent+2)
fmt.Fprintln(g.out, ws+" ("+out+")[key] = "+tmpVar)
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.Delim('}')")
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"for !in.IsDelim('}') {")
fmt.Fprintln(g.out, ws+" key := in.String()")
fmt.Fprintln(g.out, ws+" in.WantColon()")
fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem))
g.genTypeDecoder(elem, tmpVar, indent+1)
fmt.Fprintln(g.out, ws+" ("+out+")[key] = "+tmpVar)
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"in.Delim('}')")
case reflect.Interface:
if t.NumMethod() != 0 {
return fmt.Errorf("interface type %v not supported: only interface{} is allowed", t)
+13 -8
View File
@@ -91,17 +91,22 @@ func (g *Generator) genTypeEncoder(t reflect.Type, in string, indent int) error
}
tmpVar := g.uniqueVarName()
fmt.Fprintln(g.out, ws+"out.RawByte('{')")
fmt.Fprintln(g.out, ws+tmpVar+"_first := true")
fmt.Fprintln(g.out, ws+"for "+tmpVar+"_name, "+tmpVar+"_value := range "+in+" {")
fmt.Fprintln(g.out, ws+" if !"+tmpVar+"_first { out.RawByte(',') }")
fmt.Fprintln(g.out, ws+" "+tmpVar+"_first = false")
fmt.Fprintln(g.out, ws+" out.String("+tmpVar+"_name)")
fmt.Fprintln(g.out, ws+"if "+in+" == nil {")
fmt.Fprintln(g.out, ws+" out.RawString(`null`)")
fmt.Fprintln(g.out, ws+"} else {")
fmt.Fprintln(g.out, ws+" out.RawByte('{')")
fmt.Fprintln(g.out, ws+" "+tmpVar+"_first := true")
fmt.Fprintln(g.out, ws+" for "+tmpVar+"_name, "+tmpVar+"_value := range "+in+" {")
fmt.Fprintln(g.out, ws+" if !"+tmpVar+"_first { out.RawByte(',') }")
fmt.Fprintln(g.out, ws+" "+tmpVar+"_first = false")
fmt.Fprintln(g.out, ws+" out.String("+tmpVar+"_name)")
fmt.Fprintln(g.out, ws+" out.RawByte(':')")
g.genTypeEncoder(t.Elem(), tmpVar+"_value", indent+1)
g.genTypeEncoder(t.Elem(), tmpVar+"_value", indent+2)
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" out.RawByte('}')")
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"out.RawByte('}')")
case reflect.Interface:
if t.NumMethod() != 0 {
+2 -1
View File
@@ -29,6 +29,7 @@ var testCases = []struct {
{&stdMarshalerValue, stdMarshalerString},
{&unexportedStructValue, unexportedStructString},
{&excludedFieldValue, excludedFieldString},
{&mapsValue, mapsString},
}
func TestMarshal(t *testing.T) {
@@ -56,7 +57,7 @@ func TestUnmarshal(t *testing.T) {
}
if !reflect.DeepEqual(v, test.Decoded) {
t.Errorf("[%d, %T] UnmarshalJSON(): got \n%+v\n\t\t want \n%+v", i, test.Decoded, v, test.Encoded)
t.Errorf("[%d, %T] UnmarshalJSON(): got \n%+v\n\t\t want \n%+v", i, test.Decoded, v, test.Decoded)
}
}
}
+17
View File
@@ -373,3 +373,20 @@ var excludedFieldValue = ExcludedField{
DoNotProcess: false,
}
var excludedFieldString = `{"process":true}`
type Maps struct {
Map map[string]string
InterfaceMap map[string]interface{}
NilMap map[string]string
}
var mapsValue = Maps{
Map: map[string]string{"A": "b"}, // only one item since map iteration is randomized
InterfaceMap: map[string]interface{}{"G": 1},
}
var mapsString = `{` +
`"Map":{"A":"b"},` +
`"InterfaceMap":{"G":1},` +
`"NilMap":null` +
`}`