diff --git a/gen/decoder.go b/gen/decoder.go index 600bb32..1cf7257 100644 --- a/gen/decoder.go +++ b/gen/decoder.go @@ -36,16 +36,18 @@ var primitiveDecoders = map[reflect.Kind]string{ } var primitiveStringDecoders = map[reflect.Kind]string{ - reflect.Int: "in.IntStr()", - reflect.Int8: "in.Int8Str()", - reflect.Int16: "in.Int16Str()", - reflect.Int32: "in.Int32Str()", - reflect.Int64: "in.Int64Str()", - reflect.Uint: "in.UintStr()", - reflect.Uint8: "in.Uint8Str()", - reflect.Uint16: "in.Uint16Str()", - reflect.Uint32: "in.Uint32Str()", - reflect.Uint64: "in.Uint64Str()", + reflect.String: "in.String()", + reflect.Int: "in.IntStr()", + reflect.Int8: "in.Int8Str()", + reflect.Int16: "in.Int16Str()", + reflect.Int32: "in.Int32Str()", + reflect.Int64: "in.Int64Str()", + reflect.Uint: "in.UintStr()", + reflect.Uint8: "in.Uint8Str()", + reflect.Uint16: "in.Uint16Str()", + reflect.Uint32: "in.Uint32Str()", + reflect.Uint64: "in.Uint64Str()", + reflect.Uintptr: "in.UintptrStr()", } // genTypeDecoder generates decoding code for the type t, but uses unmarshaler interface if implemented by t. @@ -198,8 +200,9 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field case reflect.Map: key := t.Key() - if key.Kind() != reflect.String { - return fmt.Errorf("map type %v not supported: only string keys are allowed", key) + keyDec, ok := primitiveStringDecoders[key.Kind()] + if !ok { + return fmt.Errorf("map type %v not supported: only string and integer keys are allowed", key) } elem := t.Elem() tmpVar := g.uniqueVarName() @@ -215,7 +218,7 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field fmt.Fprintln(g.out, ws+" }") fmt.Fprintln(g.out, ws+" for !in.IsDelim('}') {") - fmt.Fprintln(g.out, ws+" key := "+g.getType(t.Key())+"(in.String())") + fmt.Fprintln(g.out, ws+" key := "+g.getType(key)+"("+keyDec+")") fmt.Fprintln(g.out, ws+" in.WantColon()") fmt.Fprintln(g.out, ws+" var "+tmpVar+" "+g.getType(elem)) diff --git a/gen/encoder.go b/gen/encoder.go index e3f7c40..408ae55 100644 --- a/gen/encoder.go +++ b/gen/encoder.go @@ -33,16 +33,18 @@ var primitiveEncoders = map[reflect.Kind]string{ } var primitiveStringEncoders = map[reflect.Kind]string{ - reflect.Int: "out.IntStr(int(%v))", - reflect.Int8: "out.Int8Str(int8(%v))", - reflect.Int16: "out.Int16Str(int16(%v))", - reflect.Int32: "out.Int32Str(int32(%v))", - reflect.Int64: "out.Int64Str(int64(%v))", - reflect.Uint: "out.UintStr(uint(%v))", - reflect.Uint8: "out.Uint8Str(uint8(%v))", - reflect.Uint16: "out.Uint16Str(uint16(%v))", - reflect.Uint32: "out.Uint32Str(uint32(%v))", - reflect.Uint64: "out.Uint64Str(uint64(%v))", + reflect.String: "out.String(string(%v))", + reflect.Int: "out.IntStr(int(%v))", + reflect.Int8: "out.Int8Str(int8(%v))", + reflect.Int16: "out.Int16Str(int16(%v))", + reflect.Int32: "out.Int32Str(int32(%v))", + reflect.Int64: "out.Int64Str(int64(%v))", + reflect.Uint: "out.UintStr(uint(%v))", + reflect.Uint8: "out.Uint8Str(uint8(%v))", + reflect.Uint16: "out.Uint16Str(uint16(%v))", + reflect.Uint32: "out.Uint32Str(uint32(%v))", + reflect.Uint64: "out.Uint64Str(uint64(%v))", + reflect.Uintptr: "out.UintptrStr(uintptr(%v))", } // fieldTags contains parsed version of json struct field tags. @@ -186,8 +188,9 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT case reflect.Map: key := t.Key() - if key.Kind() != reflect.String { - return fmt.Errorf("map type %v not supported: only string keys are allowed", key) + keyEnc, ok := primitiveStringEncoders[key.Kind()] + if !ok { + return fmt.Errorf("map key type %v not supported: only string and integer keys are allowed", key) } tmpVar := g.uniqueVarName() @@ -199,7 +202,7 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT 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(string("+tmpVar+"Name))") + fmt.Fprintln(g.out, ws+" "+fmt.Sprintf(keyEnc, tmpVar+"Name")) fmt.Fprintln(g.out, ws+" out.RawByte(':')") if err := g.genTypeEncoder(t.Elem(), tmpVar+"Value", tags, indent+2); err != nil { diff --git a/jlexer/lexer.go b/jlexer/lexer.go index e81f103..ab94657 100644 --- a/jlexer/lexer.go +++ b/jlexer/lexer.go @@ -903,6 +903,10 @@ func (r *Lexer) UintStr() uint { return uint(r.Uint64Str()) } +func (r *Lexer) UintptrStr() uintptr { + return uintptr(r.Uint64Str()) +} + func (r *Lexer) Int8Str() int8 { s, b := r.unsafeString() if !r.Ok() { diff --git a/jwriter/writer.go b/jwriter/writer.go index 7b55293..250920d 100644 --- a/jwriter/writer.go +++ b/jwriter/writer.go @@ -196,6 +196,13 @@ func (w *Writer) Uint64Str(n uint64) { w.Buffer.Buf = append(w.Buffer.Buf, '"') } +func (w *Writer) UintptrStr(n uintptr) { + w.Buffer.EnsureSpace(20) + w.Buffer.Buf = append(w.Buffer.Buf, '"') + w.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10) + w.Buffer.Buf = append(w.Buffer.Buf, '"') +} + func (w *Writer) Int8Str(n int8) { w.Buffer.EnsureSpace(4) w.Buffer.Buf = append(w.Buffer.Buf, '"')