commit ea31b296341595ece17e747a1dd24f260af48cf7
parent f801fd9a9b630c005451ac293c7ca64fa1123be4
Author: francoispqt <francois@parquet.ninja>
Date: Sun, 24 Jun 2018 00:42:14 +0800
refactor error handling in generator
Diffstat:
20 files changed, 901 insertions(+), 341 deletions(-)
diff --git a/encode_array_test.go b/encode_array_test.go
@@ -331,3 +331,8 @@ func TestEncoderArrErrors(t *testing.T) {
assert.True(t, false, "should not be called as it should have panicked")
})
}
+
+func TestEncoderArrayFunc(t *testing.T) {
+ var f EncodeArrayFunc
+ assert.True(t, f.IsNil())
+}
diff --git a/gojay/Makefile b/gojay/Makefile
@@ -8,4 +8,8 @@ test:
.PHONY: cover
cover:
- go test -tags test -coverprofile=profile.out
-\ No newline at end of file
+ go test -tags test -coverprofile=coverage.out
+
+.PHONY: coverhtml
+coverhtml:
+ go tool cover -html=coverage.out
+\ No newline at end of file
diff --git a/gojay/gen.go b/gojay/gen.go
@@ -11,12 +11,15 @@ const gojayAnnotation = "//gojay:json"
const genFileSuffix = "_gojay.go"
var pkgTpl *template.Template
+var genHeader = []byte("// Code generated by GoJay. DO NOT EDIT.\n\n")
var gojayImport = []byte("import \"github.com/francoispqt/gojay\"\n")
+// Gen is the structure representing a generator
type Gen struct {
b *strings.Builder
pkg string
src string
+ types []string
genTypes map[string]*ast.TypeSpec
vis *vis
}
@@ -48,9 +51,10 @@ func parseTemplates(tpls templateList, pfx string) {
}
// NewGen returns a new generator
-func NewGen(p string) *Gen {
+func NewGen(p string, types []string) *Gen {
g := &Gen{
src: p,
+ types: types,
b: &strings.Builder{},
genTypes: make(map[string]*ast.TypeSpec),
}
@@ -77,9 +81,33 @@ func (g *Gen) writeGojayImport() error {
return nil
}
+func (g *Gen) writeGenHeader() error {
+ _, err := g.b.Write(genHeader)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (g *Gen) isGenType(typeName string) bool {
+ // check if type is in types
+ for _, t := range g.types {
+ if t == typeName {
+ return true
+ }
+ }
+ return false
+}
+
+// Gen starts the generation writing to the string builder
func (g *Gen) Gen() error {
+ err := g.writeGenHeader()
+ if err != nil {
+ return err
+ }
+
// write package
- err := g.writePkg(g.pkg)
+ err = g.writePkg(g.pkg)
if err != nil {
return err
}
diff --git a/gojay/gen_array_test.go b/gojay/gen_array_test.go
@@ -360,7 +360,11 @@ func (v *SliceStrSlice) IsNil() bool {
if err != nil {
t.Fatal(err)
}
- assert.Equal(t, testCase.expectedResult, g.b.String())
+ assert.Equal(
+ t,
+ string(genHeader)+testCase.expectedResult,
+ g.b.String(),
+ )
})
}
}
diff --git a/gojay/gen_map_marshal.go b/gojay/gen_map_marshal.go
@@ -3,6 +3,7 @@ package main
import (
"errors"
"go/ast"
+ "log"
)
func (g *Gen) mapGenIsNil(n string) error {
@@ -52,81 +53,37 @@ func (g *Gen) mapGenMarshalObj(n string, s *ast.MapType) error {
func (g *Gen) mapGenMarshalIdent(i *ast.Ident, ptr bool) error {
switch i.String() {
case "string":
- var err = g.mapMarshalString(ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalString(ptr)
case "bool":
- var err = g.mapMarshalBool(ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalBool(ptr)
case "int":
- var err = g.mapMarshalInt("", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalInt("", ptr)
case "int64":
- var err = g.mapMarshalInt("64", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalInt("64", ptr)
case "int32":
- var err = g.mapMarshalInt("32", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalInt("32", ptr)
case "int16":
- var err = g.mapMarshalInt("16", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalInt("16", ptr)
case "int8":
- var err = g.mapMarshalInt("8", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalInt("8", ptr)
case "uint64":
- var err = g.mapMarshalUint("64", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalUint("64", ptr)
case "uint32":
- var err = g.mapMarshalUint("32", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalUint("32", ptr)
case "uint16":
- var err = g.mapMarshalUint("16", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalUint("16", ptr)
case "uint8":
- var err = g.mapMarshalUint("8", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalUint("8", ptr)
case "float64":
- var err = g.mapMarshalFloat("", ptr)
- if err != nil {
- return err
- }
+ g.mapMarshalFloat("", ptr)
default:
// if ident is already in our spec list
if sp, ok := g.genTypes[i.Name]; ok {
- err := g.mapMarshalNonPrim(sp, ptr)
- if err != nil {
- return err
- }
-
+ g.mapMarshalNonPrim(sp, ptr)
} else if i.Obj != nil {
switch t := i.Obj.Decl.(type) {
case *ast.TypeSpec:
- var err = g.mapMarshalNonPrim(t, ptr)
- if err != nil {
- return err
- }
-
+ g.mapMarshalNonPrim(t, ptr)
default:
return errors.New("could not determine what to do with type " + i.String())
}
@@ -137,17 +94,16 @@ func (g *Gen) mapGenMarshalIdent(i *ast.Ident, ptr bool) error {
return nil
}
-func (g *Gen) mapMarshalNonPrim(sp *ast.TypeSpec, ptr bool) error {
+func (g *Gen) mapMarshalNonPrim(sp *ast.TypeSpec, ptr bool) {
switch sp.Type.(type) {
case *ast.StructType:
- return g.mapMarshalStruct(sp, ptr)
+ g.mapMarshalStruct(sp, ptr)
case *ast.ArrayType:
- return g.mapMarshalArr(sp, ptr)
+ g.mapMarshalArr(sp, ptr)
}
- return nil
}
-func (g *Gen) mapMarshalString(ptr bool) error {
+func (g *Gen) mapMarshalString(ptr bool) {
ptrStr := ""
if ptr {
ptrStr = "*"
@@ -156,12 +112,11 @@ func (g *Gen) mapMarshalString(ptr bool) error {
Ptr string
}{ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) mapMarshalBool(ptr bool) error {
+func (g *Gen) mapMarshalBool(ptr bool) {
ptrStr := ""
if ptr {
ptrStr = "*"
@@ -170,12 +125,11 @@ func (g *Gen) mapMarshalBool(ptr bool) error {
Ptr string
}{ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) mapMarshalInt(intLen string, ptr bool) error {
+func (g *Gen) mapMarshalInt(intLen string, ptr bool) {
ptrStr := ""
if ptr {
ptrStr = "*"
@@ -185,12 +139,11 @@ func (g *Gen) mapMarshalInt(intLen string, ptr bool) error {
Ptr string
}{intLen, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) mapMarshalUint(intLen string, ptr bool) error {
+func (g *Gen) mapMarshalUint(intLen string, ptr bool) {
ptrStr := ""
if ptr {
ptrStr = "*"
@@ -200,12 +153,11 @@ func (g *Gen) mapMarshalUint(intLen string, ptr bool) error {
Ptr string
}{intLen, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) mapMarshalFloat(intLen string, ptr bool) error {
+func (g *Gen) mapMarshalFloat(intLen string, ptr bool) {
ptrStr := ""
if ptr {
ptrStr = "*"
@@ -215,12 +167,11 @@ func (g *Gen) mapMarshalFloat(intLen string, ptr bool) error {
Ptr string
}{intLen, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) mapMarshalStruct(st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) mapMarshalStruct(st *ast.TypeSpec, ptr bool) {
ptrStr := ""
if ptr {
ptrStr = "*"
@@ -229,12 +180,11 @@ func (g *Gen) mapMarshalStruct(st *ast.TypeSpec, ptr bool) error {
Ptr string
}{ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) mapMarshalArr(st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) mapMarshalArr(st *ast.TypeSpec, ptr bool) {
ptrStr := ""
if ptr {
ptrStr = "*"
@@ -243,7 +193,6 @@ func (g *Gen) mapMarshalArr(st *ast.TypeSpec, ptr bool) error {
Ptr string
}{ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
diff --git a/gojay/gen_map_test.go b/gojay/gen_map_test.go
@@ -82,6 +82,348 @@ func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
`,
},
+ "basicMapStringInt64": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]int64
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i int64
+ if err := dec.Int64(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Int64Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringInt32": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]int32
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i int32
+ if err := dec.Int32(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Int32Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringInt16": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]int16
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i int16
+ if err := dec.Int16(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Int16Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringInt8": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]int8
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i int8
+ if err := dec.Int8(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Int8Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringUint64": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]uint64
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i uint64
+ if err := dec.Uint64(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Uint64Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringUint32": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]uint32
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i uint32
+ if err := dec.Uint32(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Uint32Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringUint16": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]uint16
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i uint16
+ if err := dec.Uint16(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Uint16Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringUint8": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type IntMap map[string]uint8
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v IntMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i uint8
+ if err := dec.Uint8(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v IntMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v IntMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.Uint8Key(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringBool": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type BoolMap map[string]bool
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v BoolMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var b bool
+ if err := dec.Bool(&b); err != nil {
+ return err
+ }
+ v[k] = b
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v BoolMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v BoolMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.BoolKey(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v BoolMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
+ "basicMapStringStruct": {
+ input: strings.NewReader(`package test
+
+//gojay:json
+type BoolMap map[string]*Test
+
+type Test struct{}
+`),
+ expectedResult: `package
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v BoolMap) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var s = &Test{}
+ if err := dec.Object(s); err != nil {
+ return err
+ }
+ v[k] = s
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v BoolMap) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v BoolMap) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.ObjectKey(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v BoolMap) IsNil() bool { return v == nil || len(v) == 0 }
+`,
+ },
}
for n, testCase := range testCases {
t.Run(n, func(t *testing.T) {
@@ -94,7 +436,11 @@ func (v IntMap) IsNil() bool { return v == nil || len(v) == 0 }
t.Fatal(err)
}
log.Print(g.b.String())
- assert.Equal(t, testCase.expectedResult, g.b.String())
+ assert.Equal(
+ t,
+ string(genHeader)+testCase.expectedResult,
+ g.b.String(),
+ )
})
}
}
diff --git a/gojay/gen_map_unmarshal.go b/gojay/gen_map_unmarshal.go
@@ -3,6 +3,7 @@ package main
import (
"errors"
"go/ast"
+ "log"
)
func (g *Gen) mapGenNKeys(n string, count int) error {
@@ -54,65 +55,29 @@ func (g *Gen) mapGenUnmarshalObj(n string, s *ast.MapType) error {
func (g *Gen) mapGenUnmarshalIdent(i *ast.Ident, ptr bool) error {
switch i.String() {
case "string":
- var err = g.mapUnmarshalString(ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalString(ptr)
case "bool":
- var err = g.mapUnmarshalBool(ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalBool(ptr)
case "int":
- var err = g.mapUnmarshalInt("", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalInt("", ptr)
case "int64":
- var err = g.mapUnmarshalInt("64", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalInt("64", ptr)
case "int32":
- var err = g.mapUnmarshalInt("32", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalInt("32", ptr)
case "int16":
- var err = g.mapUnmarshalInt("16", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalInt("16", ptr)
case "int8":
- var err = g.mapUnmarshalInt("8", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalInt("8", ptr)
case "uint64":
- var err = g.mapUnmarshalUint("64", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalUint("64", ptr)
case "uint32":
- var err = g.mapUnmarshalUint("32", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalUint("32", ptr)
case "uint16":
- var err = g.mapUnmarshalUint("16", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalUint("16", ptr)
case "uint8":
- var err = g.mapUnmarshalUint("8", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalUint("8", ptr)
case "float64":
- var err = g.mapUnmarshalFloat("", ptr)
- if err != nil {
- return err
- }
+ g.mapUnmarshalFloat("", ptr)
default:
// if ident is already in our spec list
if sp, ok := g.genTypes[i.Name]; ok {
@@ -141,59 +106,59 @@ func (g *Gen) mapGenUnmarshalIdent(i *ast.Ident, ptr bool) error {
func (g *Gen) mapUnmarshalNonPrim(sp *ast.TypeSpec, ptr bool) error {
switch sp.Type.(type) {
case *ast.StructType:
- return g.mapUnmarshalStruct(sp, ptr)
+ g.mapUnmarshalStruct(sp, ptr)
+ return nil
case *ast.ArrayType:
- return g.mapUnmarshalArr(sp, ptr)
+ g.mapUnmarshalArr(sp, ptr)
+ return nil
}
return errors.New("Unknown type")
}
-func (g *Gen) mapUnmarshalString(ptr bool) error {
+func (g *Gen) mapUnmarshalString(ptr bool) {
if ptr {
err := mapUnmarshalTpl["string"].tpl.Execute(g.b, struct {
Ptr string
}{""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err := mapUnmarshalTpl["string"].tpl.Execute(g.b, struct {
Ptr string
}{"&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) mapUnmarshalBool(ptr bool) error {
+func (g *Gen) mapUnmarshalBool(ptr bool) {
if ptr {
err := mapUnmarshalTpl["bool"].tpl.Execute(g.b, struct {
Ptr string
}{""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err := mapUnmarshalTpl["bool"].tpl.Execute(g.b, struct {
Ptr string
}{"&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) mapUnmarshalInt(intLen string, ptr bool) error {
+func (g *Gen) mapUnmarshalInt(intLen string, ptr bool) {
if ptr {
err := mapUnmarshalTpl["int"].tpl.Execute(g.b, struct {
IntLen string
Ptr string
}{intLen, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err := mapUnmarshalTpl["int"].tpl.Execute(g.b, struct {
@@ -201,20 +166,19 @@ func (g *Gen) mapUnmarshalInt(intLen string, ptr bool) error {
Ptr string
}{intLen, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) mapUnmarshalUint(intLen string, ptr bool) error {
+func (g *Gen) mapUnmarshalUint(intLen string, ptr bool) {
if ptr {
err := mapUnmarshalTpl["uint"].tpl.Execute(g.b, struct {
IntLen string
Ptr string
}{intLen, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err := mapUnmarshalTpl["uint"].tpl.Execute(g.b, struct {
@@ -222,20 +186,19 @@ func (g *Gen) mapUnmarshalUint(intLen string, ptr bool) error {
Ptr string
}{intLen, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) mapUnmarshalFloat(intLen string, ptr bool) error {
+func (g *Gen) mapUnmarshalFloat(intLen string, ptr bool) {
if ptr {
err := mapUnmarshalTpl["float"].tpl.Execute(g.b, struct {
IntLen string
Ptr string
}{intLen, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err := mapUnmarshalTpl["float"].tpl.Execute(g.b, struct {
@@ -243,37 +206,34 @@ func (g *Gen) mapUnmarshalFloat(intLen string, ptr bool) error {
Ptr string
}{intLen, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) mapUnmarshalStruct(st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) mapUnmarshalStruct(st *ast.TypeSpec, ptr bool) {
if ptr {
err := mapUnmarshalTpl["structPtr"].tpl.Execute(g.b, struct {
StructName string
}{st.Name.String()})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err := mapUnmarshalTpl["struct"].tpl.Execute(g.b, struct {
StructName string
}{st.Name.String()})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) mapUnmarshalArr(st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) mapUnmarshalArr(st *ast.TypeSpec, ptr bool) {
err := mapUnmarshalTpl["arr"].tpl.Execute(g.b, struct {
TypeName string
}{st.Name.String()})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
diff --git a/gojay/gen_parse.go b/gojay/gen_parse.go
@@ -31,7 +31,7 @@ func (g *Gen) parseDir() error {
}
// range across packages
for pkgName, pkg := range pkgs {
- v := NewVisitor(g, pkgName)
+ v := newVisitor(g, pkgName)
g.pkg = pkgName
// range on files in package
for _, f := range pkg.Files {
@@ -53,7 +53,7 @@ func (g *Gen) parseFile() error {
return err
}
g.pkg = f.Name.Name
- v := NewVisitor(g, g.pkg)
+ v := newVisitor(g, g.pkg)
ast.Walk(v, f)
if err != nil {
return err
diff --git a/gojay/gen_struct_marshal.go b/gojay/gen_struct_marshal.go
@@ -3,6 +3,7 @@ package main
import (
"errors"
"go/ast"
+ "log"
)
func (g *Gen) structGenIsNil(n string) error {
@@ -64,76 +65,40 @@ func (g *Gen) structGenMarshalIdent(field *ast.Field, i *ast.Ident, keys int, pt
switch i.String() {
case "string":
- var err = g.structMarshalString(field, keyV, ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalString(field, keyV, ptr)
keys++
case "bool":
- var err = g.structMarshalBool(field, keyV, ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalBool(field, keyV, ptr)
keys++
case "int":
- var err = g.structMarshalInt(field, keyV, "", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalInt(field, keyV, "", ptr)
keys++
case "int64":
- var err = g.structMarshalInt(field, keyV, "64", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalInt(field, keyV, "64", ptr)
keys++
case "int32":
- var err = g.structMarshalInt(field, keyV, "32", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalInt(field, keyV, "32", ptr)
keys++
case "int16":
- var err = g.structMarshalInt(field, keyV, "16", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalInt(field, keyV, "16", ptr)
keys++
case "int8":
- var err = g.structMarshalInt(field, keyV, "8", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalInt(field, keyV, "8", ptr)
keys++
case "uint64":
- var err = g.structMarshalUint(field, keyV, "64", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalUint(field, keyV, "64", ptr)
keys++
case "uint32":
- var err = g.structMarshalUint(field, keyV, "32", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalUint(field, keyV, "32", ptr)
keys++
case "uint16":
- var err = g.structMarshalUint(field, keyV, "16", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalUint(field, keyV, "16", ptr)
keys++
case "uint8":
- var err = g.structMarshalUint(field, keyV, "8", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalUint(field, keyV, "8", ptr)
keys++
case "float64":
- var err = g.structMarshalFloat(field, keyV, "", ptr)
- if err != nil {
- return 0, err
- }
+ g.structMarshalFloat(field, keyV, "", ptr)
keys++
default:
// if ident is already in our spec list
@@ -164,14 +129,16 @@ func (g *Gen) structGenMarshalIdent(field *ast.Field, i *ast.Ident, keys int, pt
func (g *Gen) structMarshalNonPrim(field *ast.Field, keyV string, sp *ast.TypeSpec, ptr bool) error {
switch sp.Type.(type) {
case *ast.StructType:
- return g.structMarshalStruct(field, keyV, sp, ptr)
+ g.structMarshalStruct(field, keyV, sp, ptr)
+ return nil
case *ast.ArrayType:
- return g.structMarshalArr(field, keyV, sp, ptr)
+ g.structMarshalArr(field, keyV, sp, ptr)
+ return nil
}
return nil
}
-func (g *Gen) structMarshalString(field *ast.Field, keyV string, ptr bool) error {
+func (g *Gen) structMarshalString(field *ast.Field, keyV string, ptr bool) {
key := field.Names[0].String()
ptrStr := ""
if ptr {
@@ -183,12 +150,11 @@ func (g *Gen) structMarshalString(field *ast.Field, keyV string, ptr bool) error
Ptr string
}{key, keyV, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) structMarshalBool(field *ast.Field, keyV string, ptr bool) error {
+func (g *Gen) structMarshalBool(field *ast.Field, keyV string, ptr bool) {
key := field.Names[0].String()
ptrStr := ""
if ptr {
@@ -200,12 +166,11 @@ func (g *Gen) structMarshalBool(field *ast.Field, keyV string, ptr bool) error {
Ptr string
}{key, keyV, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) structMarshalInt(field *ast.Field, keyV string, intLen string, ptr bool) error {
+func (g *Gen) structMarshalInt(field *ast.Field, keyV string, intLen string, ptr bool) {
key := field.Names[0].String()
ptrStr := ""
if ptr {
@@ -218,12 +183,11 @@ func (g *Gen) structMarshalInt(field *ast.Field, keyV string, intLen string, ptr
Ptr string
}{key, intLen, keyV, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) structMarshalUint(field *ast.Field, keyV string, intLen string, ptr bool) error {
+func (g *Gen) structMarshalUint(field *ast.Field, keyV string, intLen string, ptr bool) {
key := field.Names[0].String()
ptrStr := ""
if ptr {
@@ -236,12 +200,11 @@ func (g *Gen) structMarshalUint(field *ast.Field, keyV string, intLen string, pt
Ptr string
}{key, intLen, keyV, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) structMarshalFloat(field *ast.Field, keyV string, intLen string, ptr bool) error {
+func (g *Gen) structMarshalFloat(field *ast.Field, keyV string, intLen string, ptr bool) {
key := field.Names[0].String()
ptrStr := ""
if ptr {
@@ -254,12 +217,11 @@ func (g *Gen) structMarshalFloat(field *ast.Field, keyV string, intLen string, p
Ptr string
}{key, intLen, keyV, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) structMarshalStruct(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) structMarshalStruct(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) {
key := field.Names[0].String()
ptrStr := ""
if ptr {
@@ -271,12 +233,11 @@ func (g *Gen) structMarshalStruct(field *ast.Field, keyV string, st *ast.TypeSpe
Ptr string
}{keyV, key, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
-func (g *Gen) structMarshalArr(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) structMarshalArr(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) {
key := field.Names[0].String()
ptrStr := ""
if ptr {
@@ -288,7 +249,6 @@ func (g *Gen) structMarshalArr(field *ast.Field, keyV string, st *ast.TypeSpec,
Ptr string
}{keyV, key, ptrStr})
if err != nil {
- return err
+ log.Fatal(err)
}
- return nil
}
diff --git a/gojay/gen_struct_test.go b/gojay/gen_struct_test.go
@@ -23,6 +23,9 @@ type Struct struct{
Int16 int16
Int32 int32
Int64 int64
+ Uint8 uint8
+ Uint16 uint16
+ Uint32 uint32
Uint64 uint64
Float float64
Str string
@@ -46,6 +49,12 @@ func (v *Struct) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
return dec.Int32(&v.Int32)
case "int64":
return dec.Int64(&v.Int64)
+ case "uint8":
+ return dec.Uint8(&v.Uint8)
+ case "uint16":
+ return dec.Uint16(&v.Uint16)
+ case "uint32":
+ return dec.Uint32(&v.Uint32)
case "uint64":
return dec.Uint64(&v.Uint64)
case "float":
@@ -59,7 +68,7 @@ func (v *Struct) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
}
// NKeys returns the number of keys to unmarshal
-func (v *Struct) NKeys() int { return 9 }
+func (v *Struct) NKeys() int { return 12 }
// MarshalJSONObject implements gojay's MarshalerJSONObject
func (v *Struct) MarshalJSONObject(enc *gojay.Encoder) {
@@ -68,6 +77,9 @@ func (v *Struct) MarshalJSONObject(enc *gojay.Encoder) {
enc.Int16Key("int16", v.Int16)
enc.Int32Key("int32", v.Int32)
enc.Int64Key("int64", v.Int64)
+ enc.Uint8Key("uint8", v.Uint8)
+ enc.Uint16Key("uint16", v.Uint16)
+ enc.Uint32Key("uint32", v.Uint32)
enc.Uint64Key("uint64", v.Uint64)
enc.FloatKey("float", v.Float)
enc.StringKey("str", v.Str)
@@ -367,7 +379,11 @@ func (v *Struct) IsNil() bool { return v == nil }
if err != nil {
t.Fatal(err)
}
- assert.Equal(t, testCase.expectedResult, g.b.String())
+ assert.Equal(
+ t,
+ string(genHeader)+testCase.expectedResult,
+ g.b.String(),
+ )
})
}
}
diff --git a/gojay/gen_struct_unmarshal.go b/gojay/gen_struct_unmarshal.go
@@ -3,6 +3,7 @@ package main
import (
"errors"
"go/ast"
+ "log"
)
var structUnmarshalSwitchOpen = []byte("\tswitch k {\n")
@@ -75,76 +76,40 @@ func (g *Gen) structGenUnmarshalIdent(field *ast.Field, i *ast.Ident, keys int,
switch i.String() {
case "string":
- var err = g.structUnmarshalString(field, keyV, ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalString(field, keyV, ptr)
keys++
case "bool":
- var err = g.structUnmarshalBool(field, keyV, ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalBool(field, keyV, ptr)
keys++
case "int":
- var err = g.structUnmarshalInt(field, keyV, "", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalInt(field, keyV, "", ptr)
keys++
case "int64":
- var err = g.structUnmarshalInt(field, keyV, "64", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalInt(field, keyV, "64", ptr)
keys++
case "int32":
- var err = g.structUnmarshalInt(field, keyV, "32", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalInt(field, keyV, "32", ptr)
keys++
case "int16":
- var err = g.structUnmarshalInt(field, keyV, "16", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalInt(field, keyV, "16", ptr)
keys++
case "int8":
- var err = g.structUnmarshalInt(field, keyV, "8", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalInt(field, keyV, "8", ptr)
keys++
case "uint64":
- var err = g.structUnmarshalUint(field, keyV, "64", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalUint(field, keyV, "64", ptr)
keys++
case "uint32":
- var err = g.structUnmarshalUint(field, keyV, "32", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalUint(field, keyV, "32", ptr)
keys++
case "uint16":
- var err = g.structUnmarshalUint(field, keyV, "16", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalUint(field, keyV, "16", ptr)
keys++
case "uint8":
- var err = g.structUnmarshalUint(field, keyV, "8", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalUint(field, keyV, "8", ptr)
keys++
case "float64":
- var err = g.structUnmarshalFloat(field, keyV, "", ptr)
- if err != nil {
- return 0, err
- }
+ g.structUnmarshalFloat(field, keyV, "", ptr)
keys++
default:
// if ident is already in our spec list
@@ -176,20 +141,22 @@ func (g *Gen) structGenUnmarshalIdent(field *ast.Field, i *ast.Ident, keys int,
func (g *Gen) structUnmarshalNonPrim(field *ast.Field, keyV string, sp *ast.TypeSpec, ptr bool) error {
switch sp.Type.(type) {
case *ast.StructType:
- return g.structUnmarshalStruct(field, keyV, sp, ptr)
+ g.structUnmarshalStruct(field, keyV, sp, ptr)
+ return nil
case *ast.ArrayType:
- return g.structUnmarshalArr(field, keyV, sp, ptr)
+ g.structUnmarshalArr(field, keyV, sp, ptr)
+ return nil
}
return errors.New("Unknown type")
}
-func (g *Gen) structUnmarshalString(field *ast.Field, keyV string, ptr bool) error {
+func (g *Gen) structUnmarshalString(field *ast.Field, keyV string, ptr bool) {
key := field.Names[0].String()
err := structUnmarshalTpl["case"].tpl.Execute(g.b, struct {
Key string
}{keyV})
if err != nil {
- return err
+ log.Fatal(err)
}
if ptr {
err = structUnmarshalTpl["string"].tpl.Execute(g.b, struct {
@@ -197,7 +164,7 @@ func (g *Gen) structUnmarshalString(field *ast.Field, keyV string, ptr bool) err
Ptr string
}{key, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err = structUnmarshalTpl["string"].tpl.Execute(g.b, struct {
@@ -205,19 +172,18 @@ func (g *Gen) structUnmarshalString(field *ast.Field, keyV string, ptr bool) err
Ptr string
}{key, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) structUnmarshalBool(field *ast.Field, keyV string, ptr bool) error {
+func (g *Gen) structUnmarshalBool(field *ast.Field, keyV string, ptr bool) {
key := field.Names[0].String()
err := structUnmarshalTpl["case"].tpl.Execute(g.b, struct {
Key string
}{keyV})
if err != nil {
- return err
+ log.Fatal(err)
}
if ptr {
err = structUnmarshalTpl["bool"].tpl.Execute(g.b, struct {
@@ -225,7 +191,7 @@ func (g *Gen) structUnmarshalBool(field *ast.Field, keyV string, ptr bool) error
Ptr string
}{key, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err = structUnmarshalTpl["bool"].tpl.Execute(g.b, struct {
@@ -233,19 +199,18 @@ func (g *Gen) structUnmarshalBool(field *ast.Field, keyV string, ptr bool) error
Ptr string
}{key, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) structUnmarshalInt(field *ast.Field, keyV string, intLen string, ptr bool) error {
+func (g *Gen) structUnmarshalInt(field *ast.Field, keyV string, intLen string, ptr bool) {
key := field.Names[0].String()
err := structUnmarshalTpl["case"].tpl.Execute(g.b, struct {
Key string
}{keyV})
if err != nil {
- return err
+ log.Fatal(err)
}
if ptr {
err = structUnmarshalTpl["int"].tpl.Execute(g.b, struct {
@@ -254,7 +219,7 @@ func (g *Gen) structUnmarshalInt(field *ast.Field, keyV string, intLen string, p
Ptr string
}{key, intLen, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err = structUnmarshalTpl["int"].tpl.Execute(g.b, struct {
@@ -263,19 +228,18 @@ func (g *Gen) structUnmarshalInt(field *ast.Field, keyV string, intLen string, p
Ptr string
}{key, intLen, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) structUnmarshalUint(field *ast.Field, keyV string, intLen string, ptr bool) error {
+func (g *Gen) structUnmarshalUint(field *ast.Field, keyV string, intLen string, ptr bool) {
key := field.Names[0].String()
err := structUnmarshalTpl["case"].tpl.Execute(g.b, struct {
Key string
}{keyV})
if err != nil {
- return err
+ log.Fatal(err)
}
if ptr {
err = structUnmarshalTpl["uint"].tpl.Execute(g.b, struct {
@@ -284,7 +248,7 @@ func (g *Gen) structUnmarshalUint(field *ast.Field, keyV string, intLen string,
Ptr string
}{key, intLen, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err = structUnmarshalTpl["uint"].tpl.Execute(g.b, struct {
@@ -293,19 +257,18 @@ func (g *Gen) structUnmarshalUint(field *ast.Field, keyV string, intLen string,
Ptr string
}{key, intLen, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) structUnmarshalFloat(field *ast.Field, keyV string, intLen string, ptr bool) error {
+func (g *Gen) structUnmarshalFloat(field *ast.Field, keyV string, intLen string, ptr bool) {
key := field.Names[0].String()
err := structUnmarshalTpl["case"].tpl.Execute(g.b, struct {
Key string
}{keyV})
if err != nil {
- return err
+ log.Fatal(err)
}
if ptr {
err = structUnmarshalTpl["float"].tpl.Execute(g.b, struct {
@@ -314,7 +277,7 @@ func (g *Gen) structUnmarshalFloat(field *ast.Field, keyV string, intLen string,
Ptr string
}{key, intLen, ""})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err = structUnmarshalTpl["float"].tpl.Execute(g.b, struct {
@@ -323,19 +286,18 @@ func (g *Gen) structUnmarshalFloat(field *ast.Field, keyV string, intLen string,
Ptr string
}{key, intLen, "&"})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) structUnmarshalStruct(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) structUnmarshalStruct(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) {
key := field.Names[0].String()
err := structUnmarshalTpl["case"].tpl.Execute(g.b, struct {
Key string
}{keyV})
if err != nil {
- return err
+ log.Fatal(err)
}
if ptr {
err = structUnmarshalTpl["structPtr"].tpl.Execute(g.b, struct {
@@ -343,7 +305,7 @@ func (g *Gen) structUnmarshalStruct(field *ast.Field, keyV string, st *ast.TypeS
StructName string
}{key, st.Name.String()})
if err != nil {
- return err
+ log.Fatal(err)
}
} else {
err = structUnmarshalTpl["struct"].tpl.Execute(g.b, struct {
@@ -351,26 +313,34 @@ func (g *Gen) structUnmarshalStruct(field *ast.Field, keyV string, st *ast.TypeS
StructName string
}{key, st.Name.String()})
if err != nil {
- return err
+ log.Fatal(err)
}
}
- return nil
}
-func (g *Gen) structUnmarshalArr(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) error {
+func (g *Gen) structUnmarshalArr(field *ast.Field, keyV string, st *ast.TypeSpec, ptr bool) {
key := field.Names[0].String()
err := structUnmarshalTpl["case"].tpl.Execute(g.b, struct {
Key string
}{keyV})
if err != nil {
- return err
+ log.Fatal(err)
}
- err = structUnmarshalTpl["arr"].tpl.Execute(g.b, struct {
- Field string
- TypeName string
- }{key, st.Name.String()})
- if err != nil {
- return err
+ if ptr {
+ err = structUnmarshalTpl["arrPtr"].tpl.Execute(g.b, struct {
+ Field string
+ TypeName string
+ }{key, st.Name.String()})
+ if err != nil {
+ log.Fatal(err)
+ }
+ } else {
+ err = structUnmarshalTpl["arr"].tpl.Execute(g.b, struct {
+ Field string
+ TypeName string
+ }{key, st.Name.String()})
+ if err != nil {
+ log.Fatal(err)
+ }
}
- return nil
}
diff --git a/gojay/gen_struct_unmarshal_tpl.go b/gojay/gen_struct_unmarshal_tpl.go
@@ -51,6 +51,14 @@ func (v *{{.StructName}}) NKeys() int { return {{.NKeys}} }
return dec.Array(&v.{{.Field}})
`,
},
+ "arrPtr": &genTpl{
+ strTpl: ` if v.{{.Field}} == nil {
+ arr := make({{.TypeName}}, 0)
+ v.{{.Field}} = &arr
+ }
+ return dec.Array(v.{{.Field}})
+`,
+ },
}
func init() {
diff --git a/gojay/gen_test.go b/gojay/gen_test.go
@@ -8,13 +8,13 @@ import (
)
func MakeGenFromReader(input io.Reader) (*Gen, error) {
- g := NewGen("")
+ g := NewGen("", []string{})
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "", input, parser.ParseComments)
if err != nil {
return nil, err
}
- v := NewVisitor(g, g.pkg)
+ v := newVisitor(g, g.pkg)
ast.Walk(v, f)
if err != nil {
return nil, err
diff --git a/gojay/main.go b/gojay/main.go
@@ -13,6 +13,7 @@ import (
var dst = flag.String("o", "", "destination file to output generated implementations")
var src = flag.String("s", "", "source dir or file")
+var types = flag.String("t", "", "types to generate")
func hasAnnotation(fP string) bool {
b, err := ioutil.ReadFile(fP)
@@ -26,11 +27,16 @@ func hasAnnotation(fP string) bool {
func getPath() (string, error) {
var err error
var p string
- if *src != "" {
+ if *src != "" { // if src is present parse from src
p, err = filepath.Abs(*src)
if err != nil {
return "", err
}
+ } else if len(os.Args) > 1 { // else if there is a command line arg, use it as path to a package $GOPATH/src/os.Args[1]
+ p, err = filepath.Abs(os.Getenv("GOPATH") + "/src/" + os.Args[1])
+ if err != nil {
+ return "", err
+ }
} else {
p, err = os.Getwd()
if err != nil {
@@ -40,15 +46,32 @@ func getPath() (string, error) {
return p, nil
}
-func main() {
+func getTypes() (t []string) {
+ if *types != "" { // if src is present parse from src
+ return strings.Split(*types, ",")
+ } else if *src == "" && *dst == "" && len(os.Args) > 2 { // else if there is a command line arg, use it as path to a package $GOPATH/src/os.Args[1]
+ return strings.Split(os.Args[2], ",")
+ }
+ return t
+}
+
+func parseArgs() (p string, t []string, err error) {
flag.Parse()
- // get path
- p, err := getPath()
+ p, err = getPath()
+ if err != nil {
+ return p, t, err
+ }
+ t = getTypes()
+ return p, t, err
+}
+
+func main() {
+ p, t, err := parseArgs()
if err != nil {
log.Fatal(err)
}
// parse source files
- g := NewGen(p)
+ g := NewGen(p, t)
err = g.parse()
if err != nil {
log.Fatal(err)
diff --git a/gojay/tests/complex_structs.go b/gojay/tests/complex_structs.go
@@ -1 +0,0 @@
-package tests
diff --git a/gojay/tests/json.go b/gojay/tests/json.go
@@ -0,0 +1,284 @@
+// Code generated by GoJay. DO NOT EDIT.
+
+package tests
+
+import "github.com/francoispqt/gojay"
+
+// UnmarshalJSONArray implements gojay's UnmarshalerJSONArray
+func (v *StrSlice) UnmarshalJSONArray(dec *gojay.Decoder) error {
+ var str string
+ if err := dec.String(&str); err != nil {
+ return err
+ }
+ *v = append(*v, str)
+ return nil
+}
+
+// MarshalJSONArray implements gojay's MarshalerJSONArray
+func (v *StrSlice) MarshalJSONArray(enc *gojay.Encoder) {
+ for _, s := range *v {
+ enc.String(s)
+ }
+}
+
+// IsNil implements gojay's MarshalerJSONArray
+func (v *StrSlice) IsNil() bool {
+ return *v == nil || len(*v) == 0
+}
+
+// UnmarshalJSONArray implements gojay's UnmarshalerJSONArray
+func (v *IntSlice) UnmarshalJSONArray(dec *gojay.Decoder) error {
+ var i int
+ if err := dec.Int(&i); err != nil {
+ return err
+ }
+ *v = append(*v, i)
+ return nil
+}
+
+// MarshalJSONArray implements gojay's MarshalerJSONArray
+func (v *IntSlice) MarshalJSONArray(enc *gojay.Encoder) {
+ for _, s := range *v {
+ enc.Int(s)
+ }
+}
+
+// IsNil implements gojay's MarshalerJSONArray
+func (v *IntSlice) IsNil() bool {
+ return *v == nil || len(*v) == 0
+}
+
+// UnmarshalJSONArray implements gojay's UnmarshalerJSONArray
+func (v *BoolSlice) UnmarshalJSONArray(dec *gojay.Decoder) error {
+ var b bool
+ if err := dec.Bool(&b); err != nil {
+ return err
+ }
+ *v = append(*v, b)
+ return nil
+}
+
+// MarshalJSONArray implements gojay's MarshalerJSONArray
+func (v *BoolSlice) MarshalJSONArray(enc *gojay.Encoder) {
+ for _, s := range *v {
+ enc.Bool(s)
+ }
+}
+
+// IsNil implements gojay's MarshalerJSONArray
+func (v *BoolSlice) IsNil() bool {
+ return *v == nil || len(*v) == 0
+}
+
+// UnmarshalJSONArray implements gojay's UnmarshalerJSONArray
+func (v *StructSlice) UnmarshalJSONArray(dec *gojay.Decoder) error {
+ var s = &A{}
+ if err := dec.Object(s); err != nil {
+ return err
+ }
+ *v = append(*v, s)
+ return nil
+}
+
+// MarshalJSONArray implements gojay's MarshalerJSONArray
+func (v *StructSlice) MarshalJSONArray(enc *gojay.Encoder) {
+ for _, s := range *v {
+ enc.Object(s)
+ }
+}
+
+// IsNil implements gojay's MarshalerJSONArray
+func (v *StructSlice) IsNil() bool {
+ return *v == nil || len(*v) == 0
+}
+
+// UnmarshalJSONArray implements gojay's UnmarshalerJSONArray
+func (v *SliceSlice) UnmarshalJSONArray(dec *gojay.Decoder) error {
+ var s = make(StrSlice, 0)
+ if err := dec.Array(&s); err != nil {
+ return err
+ }
+ *v = append(*v, &s)
+ return nil
+}
+
+// MarshalJSONArray implements gojay's MarshalerJSONArray
+func (v *SliceSlice) MarshalJSONArray(enc *gojay.Encoder) {
+ for _, s := range *v {
+ enc.Array(s)
+ }
+}
+
+// IsNil implements gojay's MarshalerJSONArray
+func (v *SliceSlice) IsNil() bool {
+ return *v == nil || len(*v) == 0
+}
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v *A) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ switch k {
+ case "string":
+ return dec.String(&v.Str)
+ case "bool":
+ return dec.Bool(&v.Bool)
+ case "int":
+ return dec.Int(&v.Int)
+ case "int64":
+ return dec.Int64(&v.Int64)
+ case "int32":
+ return dec.Int32(&v.Int32)
+ case "int16":
+ return dec.Int16(&v.Int16)
+ case "int8":
+ return dec.Int8(&v.Int8)
+ case "uint64":
+ return dec.Uint64(&v.Uint64)
+ case "uint32":
+ return dec.Uint32(&v.Uint32)
+ case "uint16":
+ return dec.Uint16(&v.Uint16)
+ case "uint8":
+ return dec.Uint8(&v.Uint8)
+ case "bval":
+ if v.Bval == nil {
+ v.Bval = &B{}
+ }
+ return dec.Object(v.Bval)
+ case "arrval":
+ if v.Arrval == nil {
+ arr := make(StrSlice, 0)
+ v.Arrval = &arr
+ }
+ return dec.Array(v.Arrval)
+ }
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v *A) NKeys() int { return 13 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v *A) MarshalJSONObject(enc *gojay.Encoder) {
+ enc.StringKey("string", v.Str)
+ enc.BoolKey("bool", v.Bool)
+ enc.IntKey("int", v.Int)
+ enc.Int64Key("int64", v.Int64)
+ enc.Int32Key("int32", v.Int32)
+ enc.Int16Key("int16", v.Int16)
+ enc.Int8Key("int8", v.Int8)
+ enc.Uint64Key("uint64", v.Uint64)
+ enc.Uint32Key("uint32", v.Uint32)
+ enc.Uint16Key("uint16", v.Uint16)
+ enc.Uint8Key("uint8", v.Uint8)
+ enc.ObjectKey("bval", v.Bval)
+ enc.ArrayKey("arrval", v.Arrval)
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v *A) IsNil() bool { return v == nil }
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v *B) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ switch k {
+ case "str":
+ return dec.String(&v.Str)
+ case "bool":
+ return dec.Bool(&v.Bool)
+ case "int":
+ return dec.Int(&v.Int)
+ case "int64":
+ return dec.Int64(&v.Int64)
+ case "int32":
+ return dec.Int32(&v.Int32)
+ case "int16":
+ return dec.Int16(&v.Int16)
+ case "int8":
+ return dec.Int8(&v.Int8)
+ case "uint64":
+ return dec.Uint64(&v.Uint64)
+ case "uint32":
+ return dec.Uint32(&v.Uint32)
+ case "uint16":
+ return dec.Uint16(&v.Uint16)
+ case "uint8":
+ return dec.Uint8(&v.Uint8)
+ case "strPtr":
+ return dec.String(v.StrPtr)
+ case "boolPtr":
+ return dec.Bool(v.BoolPtr)
+ case "intPtr":
+ return dec.Int(v.IntPtr)
+ case "int64Ptr":
+ return dec.Int64(v.Int64Ptr)
+ case "int32Ptr":
+ return dec.Int32(v.Int32Ptr)
+ case "int16Ptr":
+ return dec.Int16(v.Int16Ptr)
+ case "int8Ptr":
+ return dec.Int8(v.Int8Ptr)
+ case "uint64Ptr":
+ return dec.Uint64(v.Uint64Ptr)
+ case "uint32Ptr":
+ return dec.Uint32(v.Uint32Ptr)
+ case "uint16Ptr":
+ return dec.Uint16(v.Uint16Ptr)
+ case "uint8PTr":
+ return dec.Uint8(v.Uint8PTr)
+ }
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v *B) NKeys() int { return 22 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v *B) MarshalJSONObject(enc *gojay.Encoder) {
+ enc.StringKey("str", v.Str)
+ enc.BoolKey("bool", v.Bool)
+ enc.IntKey("int", v.Int)
+ enc.Int64Key("int64", v.Int64)
+ enc.Int32Key("int32", v.Int32)
+ enc.Int16Key("int16", v.Int16)
+ enc.Int8Key("int8", v.Int8)
+ enc.Uint64Key("uint64", v.Uint64)
+ enc.Uint32Key("uint32", v.Uint32)
+ enc.Uint16Key("uint16", v.Uint16)
+ enc.Uint8Key("uint8", v.Uint8)
+ enc.StringKey("strPtr", *v.StrPtr)
+ enc.BoolKey("boolPtr", *v.BoolPtr)
+ enc.IntKey("intPtr", *v.IntPtr)
+ enc.Int64Key("int64Ptr", *v.Int64Ptr)
+ enc.Int32Key("int32Ptr", *v.Int32Ptr)
+ enc.Int16Key("int16Ptr", *v.Int16Ptr)
+ enc.Int8Key("int8Ptr", *v.Int8Ptr)
+ enc.Uint64Key("uint64Ptr", *v.Uint64Ptr)
+ enc.Uint32Key("uint32Ptr", *v.Uint32Ptr)
+ enc.Uint16Key("uint16Ptr", *v.Uint16Ptr)
+ enc.Uint8Key("uint8PTr", *v.Uint8PTr)
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v *B) IsNil() bool { return v == nil }
+
+// UnmarshalJSONObject implements gojay's UnmarshalerJSONObject
+func (v MapStringInt) UnmarshalJSONObject(dec *gojay.Decoder, k string) error {
+ var i int
+ if err := dec.Int(&i); err != nil {
+ return err
+ }
+ v[k] = i
+ return nil
+}
+
+// NKeys returns the number of keys to unmarshal
+func (v MapStringInt) NKeys() int { return 0 }
+
+// MarshalJSONObject implements gojay's MarshalerJSONObject
+func (v MapStringInt) MarshalJSONObject(enc *gojay.Encoder) {
+ for k, s := range v {
+ enc.IntKey(k, s)
+ }
+}
+
+// IsNil returns wether the structure is nil value or not
+func (v MapStringInt) IsNil() bool { return v == nil || len(v) == 0 }
diff --git a/gojay/tests/maps.go b/gojay/tests/maps.go
@@ -0,0 +1,4 @@
+package tests
+
+//gojay:json
+type MapStringInt map[string]int
diff --git a/gojay/tests/basic_slices.go b/gojay/tests/slices.go
diff --git a/gojay/tests/basic_structs.go b/gojay/tests/structs.go
diff --git a/gojay/visitor.go b/gojay/visitor.go
@@ -29,12 +29,12 @@ func (v *vis) Visit(n ast.Node) (w ast.Visitor) {
v.commentFound = false
return v
case *ast.GenDecl:
- if n.Doc != nil {
+ if len(v.g.types) == 0 && n.Doc != nil {
v.commentFound = docContains(n.Doc, gojayAnnotation)
}
return v
case *ast.TypeSpec:
- if v.commentFound {
+ if v.commentFound || v.g.isGenType(n.Name.Name) {
v.g.genTypes[n.Name.Name] = n
}
v.commentFound = false
@@ -46,7 +46,7 @@ func (v *vis) Visit(n ast.Node) (w ast.Visitor) {
return v
}
-func NewVisitor(g *Gen, pkgName string) *vis {
+func newVisitor(g *Gen, pkgName string) *vis {
return &vis{
g: g,
pkg: pkgName,