mirror of
https://github.com/netbirdio/easyjson.git
synced 2026-05-22 18:44:42 -07:00
Support embedded pointer fields.
This commit is contained in:
+32
-4
@@ -162,7 +162,11 @@ func mergeStructFields(fields1, fields2 []reflect.StructField) (fields []reflect
|
||||
return
|
||||
}
|
||||
|
||||
func getStructFields(t reflect.Type) []reflect.StructField {
|
||||
func getStructFields(t reflect.Type) ([]reflect.StructField, error) {
|
||||
if t.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("got %v; expected a struct", t)
|
||||
}
|
||||
|
||||
var efields []reflect.StructField
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
@@ -170,7 +174,16 @@ func getStructFields(t reflect.Type) []reflect.StructField {
|
||||
continue
|
||||
}
|
||||
|
||||
efields = mergeStructFields(efields, getStructFields(f.Type))
|
||||
t1 := f.Type
|
||||
if t1.Kind() == reflect.Ptr {
|
||||
t1 = t1.Elem()
|
||||
}
|
||||
|
||||
fs, err := getStructFields(t1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error processing embedded field: %v", err)
|
||||
}
|
||||
efields = mergeStructFields(efields, fs)
|
||||
}
|
||||
|
||||
var fields []reflect.StructField
|
||||
@@ -185,7 +198,7 @@ func getStructFields(t reflect.Type) []reflect.StructField {
|
||||
fields = append(fields, f)
|
||||
}
|
||||
}
|
||||
return mergeStructFields(efields, fields)
|
||||
return mergeStructFields(efields, fields), nil
|
||||
}
|
||||
|
||||
func (g *Generator) genStructDecoder(t reflect.Type) error {
|
||||
@@ -197,6 +210,16 @@ func (g *Generator) genStructDecoder(t reflect.Type) error {
|
||||
typ := g.getType(t)
|
||||
|
||||
fmt.Fprintln(g.out, "func "+fname+"(in *jlexer.Lexer, out *"+typ+") {")
|
||||
|
||||
// Init embedded pointer fields.
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
f := t.Field(i)
|
||||
if !f.Anonymous || f.Type.Kind() != reflect.Ptr {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintln(g.out, " out."+f.Name+" = new("+g.getType(f.Type.Elem())+")")
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, " in.Delim('{')")
|
||||
fmt.Fprintln(g.out, " for !in.IsDelim('}') {")
|
||||
fmt.Fprintln(g.out, " key := in.UnsafeString()")
|
||||
@@ -208,7 +231,12 @@ func (g *Generator) genStructDecoder(t reflect.Type) error {
|
||||
fmt.Fprintln(g.out, " }")
|
||||
fmt.Fprintln(g.out, " switch key {")
|
||||
|
||||
for _, f := range getStructFields(t) {
|
||||
fs, err := getStructFields(t)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot generate decoder for %v: %v", t, err)
|
||||
}
|
||||
|
||||
for _, f := range fs {
|
||||
if err := g.genStructFieldDecoder(t, f); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+5
-1
@@ -185,7 +185,11 @@ func (g *Generator) genStructEncoder(t reflect.Type) error {
|
||||
fmt.Fprintln(g.out, " first := true")
|
||||
fmt.Fprintln(g.out, " _ = first")
|
||||
|
||||
for _, f := range getStructFields(t) {
|
||||
fs, err := getStructFields(t)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot generate encoder for %v: %v", t, err)
|
||||
}
|
||||
for _, f := range fs {
|
||||
if err := g.genStructFieldEncoder(t, f); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+10
-1
@@ -174,10 +174,16 @@ type SubStruct struct {
|
||||
unexpored bool
|
||||
}
|
||||
|
||||
type SubP struct {
|
||||
V string
|
||||
}
|
||||
|
||||
type SubStructAlias SubStruct
|
||||
|
||||
type Structs struct {
|
||||
SubStruct
|
||||
*SubP
|
||||
|
||||
Value2 int
|
||||
|
||||
Sub1 SubStruct `json:"substruct"`
|
||||
@@ -209,7 +215,9 @@ type Structs struct {
|
||||
|
||||
var structsValue = Structs{
|
||||
SubStruct: SubStruct{Value: "test"},
|
||||
Value2: 5,
|
||||
SubP: &SubP{V: "subp"},
|
||||
|
||||
Value2: 5,
|
||||
|
||||
Sub1: SubStruct{Value: "test1", Value2: "v"},
|
||||
Sub2: &SubStruct{Value: "test2", Value2: "v2"},
|
||||
@@ -263,6 +271,7 @@ var structsString = "{" +
|
||||
`"AnonymousPtrSlice":[{"V":3},{"V":4}],` +
|
||||
|
||||
// Embedded fields go last.
|
||||
`"V":"subp",` +
|
||||
`"Value":"test"` +
|
||||
"}"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user