Merge pull request #59 from nsd20463/master

Add support for array types
This commit is contained in:
Victor Starodub
2016-09-24 04:44:49 +04:00
committed by GitHub
5 changed files with 94 additions and 14 deletions
+42 -7
View File
@@ -123,6 +123,41 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field
fmt.Fprintln(g.out, ws+"}")
}
case reflect.Array:
iterVar := g.uniqueVarName()
elem := t.Elem()
if elem.Kind() == reflect.Uint8 {
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+" copy("+out+"[:], in.Bytes())")
fmt.Fprintln(g.out, ws+"}")
} else {
length := t.Len()
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+" in.Delim('[')")
fmt.Fprintln(g.out, ws+" "+iterVar+" := 0")
fmt.Fprintln(g.out, ws+" for !in.IsDelim(']') {")
fmt.Fprintln(g.out, ws+" if "+iterVar+" < "+fmt.Sprint(length)+" {")
g.genTypeDecoder(elem, out+"["+iterVar+"]", tags, indent+3)
fmt.Fprintln(g.out, ws+" "+iterVar+"++")
fmt.Fprintln(g.out, ws+" } else {")
fmt.Fprintln(g.out, ws+" in.SkipRecursive()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.WantComma()")
fmt.Fprintln(g.out, ws+" }")
fmt.Fprintln(g.out, ws+" in.Delim(']')")
fmt.Fprintln(g.out, ws+"}")
}
case reflect.Struct:
dec := g.getDecoderName(t)
g.addType(t)
@@ -287,16 +322,16 @@ func getStructFields(t reflect.Type) ([]reflect.StructField, error) {
func (g *Generator) genDecoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice:
return g.genSliceDecoder(t)
case reflect.Slice, reflect.Array:
return g.genSliceArrayDecoder(t)
default:
return g.genStructDecoder(t)
}
}
func (g *Generator) genSliceDecoder(t reflect.Type) error {
if t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice type", t)
func (g *Generator) genSliceArrayDecoder(t reflect.Type) error {
if t.Kind() != reflect.Slice && t.Kind() != reflect.Array {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice or array type", t)
}
fname := g.getDecoderName(t)
@@ -378,8 +413,8 @@ func (g *Generator) genStructDecoder(t reflect.Type) error {
}
func (g *Generator) genStructUnmarshaller(t reflect.Type) error {
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice type", t)
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice && t.Kind() != reflect.Array {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice/array type", t)
}
fname := g.getDecoderName(t)
+27 -7
View File
@@ -137,6 +137,25 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT
fmt.Fprintln(g.out, ws+"}")
}
case reflect.Array:
elem := t.Elem()
iVar := g.uniqueVarName()
if t.Elem().Kind() == reflect.Uint8 {
fmt.Fprintln(g.out, ws+"out.Base64Bytes("+in+"[:])")
} else {
fmt.Fprintln(g.out, ws+"out.RawByte('[')")
fmt.Fprintln(g.out, ws+"for "+iVar+" := range "+in+" {")
fmt.Fprintln(g.out, ws+" if "+iVar+" > 0 {")
fmt.Fprintln(g.out, ws+" out.RawByte(',')")
fmt.Fprintln(g.out, ws+" }")
g.genTypeEncoder(elem, in+"["+iVar+"]", tags, indent+1)
fmt.Fprintln(g.out, ws+"}")
fmt.Fprintln(g.out, ws+"out.RawByte(']')")
}
case reflect.Struct:
enc := g.getEncoderName(t)
g.addType(t)
@@ -214,6 +233,7 @@ func (g *Generator) notEmptyCheck(t reflect.Type, v string) string {
return v + " != 0"
default:
// note: Array types don't have a useful empty value
return "true"
}
}
@@ -246,16 +266,16 @@ func (g *Generator) genStructFieldEncoder(t reflect.Type, f reflect.StructField)
func (g *Generator) genEncoder(t reflect.Type) error {
switch t.Kind() {
case reflect.Slice:
return g.genSliceEncoder(t)
case reflect.Slice, reflect.Array:
return g.genSliceArrayEncoder(t)
default:
return g.genStructEncoder(t)
}
}
func (g *Generator) genSliceEncoder(t reflect.Type) error {
if t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice type", t)
func (g *Generator) genSliceArrayEncoder(t reflect.Type) error {
if t.Kind() != reflect.Slice && t.Kind() != reflect.Array {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a slice or array type", t)
}
fname := g.getEncoderName(t)
@@ -300,8 +320,8 @@ func (g *Generator) genStructEncoder(t reflect.Type) error {
}
func (g *Generator) genStructMarshaller(t reflect.Type) error {
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice type", t)
if t.Kind() != reflect.Struct && t.Kind() != reflect.Slice && t.Kind() != reflect.Array {
return fmt.Errorf("cannot generate encoder/decoder for %v, not a struct/slice/array type", t)
}
fname := g.getEncoderName(t)
+3
View File
@@ -8,6 +8,7 @@ import (
"path"
"reflect"
"sort"
"strconv"
"strings"
"unicode"
)
@@ -233,6 +234,8 @@ func (g *Generator) getType(t reflect.Type) string {
return "*" + g.getType(t.Elem())
case reflect.Slice:
return "[]" + g.getType(t.Elem())
case reflect.Array:
return "[" + strconv.Itoa(t.Len()) + "]" + g.getType(t.Elem())
case reflect.Map:
return "map[" + g.getType(t.Key()) + "]" + g.getType(t.Elem())
}
+1
View File
@@ -31,6 +31,7 @@ var testCases = []struct {
{&unexportedStructValue, unexportedStructString},
{&excludedFieldValue, excludedFieldString},
{&sliceValue, sliceString},
{&arrayValue, arrayString},
{&mapsValue, mapsString},
{&deepNestValue, deepNestString},
{&IntsValue, IntsString},
+21
View File
@@ -445,6 +445,27 @@ var sliceString = `{` +
`"NilIntSlice":null` +
`}`
type Arrays struct {
ByteArray [3]byte
EmptyByteArray [0]byte
IntArray [5]int
EmptyIntArray [0]int
}
var arrayValue = Arrays{
ByteArray: [3]byte{'a', 'b', 'c'},
EmptyByteArray: [0]byte{},
IntArray: [5]int{1, 2, 3, 4, 5},
EmptyIntArray: [0]int{},
}
var arrayString = `{` +
`"ByteArray":"YWJj",` +
`"EmptyByteArray":"",` +
`"IntArray":[1,2,3,4,5],` +
`"EmptyIntArray":[]` +
`}`
type Str string
type Maps struct {