Skip to content

Commit c5dd2ab

Browse files
author
Tao Wen
committed
support marshal embed struct
1 parent ac9c237 commit c5dd2ab

File tree

5 files changed

+51
-18
lines changed

5 files changed

+51
-18
lines changed

generator/decoder.go

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ func decodeStructField(structType *ast.StructType) {
196196
case *ast.StarExpr: // embed pointer
197197
switch y := x.X.(type) {
198198
case *ast.Ident:
199+
isNotExported := unicode.IsLower(rune(y.Name[0]))
200+
if isNotExported {
201+
continue
202+
}
199203
_f(" var val%d %s", i, y.Name)
200204
_f(" if %s_json_unmarshal_field(iter, field, &val%d) {", y.Name, i)
201205
_f(" out.%s = new(%s)", y.Name, y.Name)
@@ -251,20 +255,8 @@ func decodeStructField(structType *ast.StructType) {
251255
_f(" if %s_json_unmarshal_field(iter, field, &out.%s) { return true }", nodeToString(x), x.Sel.Name)
252256
}
253257
case *ast.Ident: // embed value
254-
if x.Name == "string" ||
255-
x.Name == "bool" ||
256-
x.Name == "int" ||
257-
x.Name == "uint" ||
258-
x.Name == "int64" ||
259-
x.Name == "uint64" ||
260-
x.Name == "int32" ||
261-
x.Name == "uint32" ||
262-
x.Name == "int16" ||
263-
x.Name == "uint16" ||
264-
x.Name == "int8" ||
265-
x.Name == "uint8" ||
266-
x.Name == "float64" ||
267-
x.Name == "float32" {
258+
isNotExported := unicode.IsLower(rune(x.Name[0]))
259+
if isNotExported {
268260
continue
269261
}
270262
_f(" if %s_json_unmarshal_field(iter, field, &out.%s) { return true }", x.Name, x.Name)

generator/encoder.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ func encodeStruct(typeName string, structType *ast.StructType) {
187187
func encodeStructField(structType *ast.StructType) {
188188
for _, field := range structType.Fields.List {
189189
if len(field.Names) == 0 {
190+
encodeStructEmbedField(field.Type)
190191
continue
191192
}
192193
fieldName := field.Names[0].Name
@@ -216,6 +217,34 @@ func encodeStructField(structType *ast.StructType) {
216217
}
217218
}
218219

220+
func encodeStructEmbedField(fieldType ast.Expr) {
221+
switch x := fieldType.(type) {
222+
case *ast.Ident:
223+
isNotExported := unicode.IsLower(rune(x.Name[0]))
224+
if !isNotExported {
225+
_f(" %s_json_marshal_field(stream, val.%s)", x.Name, x.Name)
226+
}
227+
case *ast.StarExpr:
228+
switch y := x.X.(type) {
229+
case *ast.Ident:
230+
isNotExported := unicode.IsLower(rune(y.Name[0]))
231+
if isNotExported {
232+
return
233+
}
234+
_f(" if val.%s != nil {", y.Name)
235+
_f(" %s_json_marshal_field(stream, *val.%s)", y.Name, y.Name)
236+
_l(" }")
237+
default:
238+
reportError(fmt.Errorf("unknown embed field type: %s", nodeToString(fieldType)))
239+
return
240+
}
241+
case *ast.SelectorExpr:
242+
default:
243+
reportError(fmt.Errorf("unknown embed field type: %s", nodeToString(fieldType)))
244+
return
245+
}
246+
}
247+
219248
func encodeOtherField(typeName string) {
220249
_f(` stream.WriteObjectField("%s")`, typeName)
221250
_f(" %s_json_marshal(stream, val)", prefix)

value_tests/WithEmbedStruct_json.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ func WithEmbedStruct_json_marshal(stream *jsoniter.Stream, val WithEmbedStruct)
4545
stream.WriteObjectTail()
4646
}
4747
func WithEmbedStruct_json_marshal_field(stream *jsoniter.Stream, val WithEmbedStruct) {
48+
if val.WithEmbedStructBase1 != nil {
49+
WithEmbedStructBase1_json_marshal_field(stream, *val.WithEmbedStructBase1)
50+
}
51+
WithEmbedStructBase2_json_marshal_field(stream, val.WithEmbedStructBase2)
4852
stream.WriteObjectField(`Field3`)
4953
stream.WriteString(val.Field3)
5054
stream.WriteMore()

value_tests/WithNamelessField_json.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,8 @@ func WithNamelessField_json_marshal(stream *jsoniter.Stream, val WithNamelessFie
4040
stream.WriteObjectTail()
4141
}
4242
func WithNamelessField_json_marshal_field(stream *jsoniter.Stream, val WithNamelessField) {
43+
WithNamelessField_f1_json_marshal_field(stream, val.WithNamelessField_f1)
44+
if val.WithNamelessField_f2 != nil {
45+
WithNamelessField_f2_json_marshal_field(stream, *val.WithNamelessField_f2)
46+
}
4347
}

value_tests/struct_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package value_tests
22

33
import (
44
"encoding/json"
5+
"strings"
56
"testing"
67

78
jsoniter "github.com/json-iterator/tinygo"
@@ -31,10 +32,13 @@ func Test_struct4(t *testing.T) {
3132
jsonAdapter := jsoniter.CreateJsonAdapter(WithEmbedStruct_json{})
3233
compareWithStdlib(`{"Field1":"hello","Field2":"world","Field3":"abc","Embed3":"123"}`,
3334
jsonAdapter, &val1, &val2)
34-
// bytes, _ := jsonAdapter.MarshalIndent(val2, "", " ")
35-
// if !strings.Contains(string(bytes), "Field1") {
36-
// t.Fatal(string(bytes))
37-
// }
35+
bytes, _ := jsonAdapter.MarshalIndent(val2, "", " ")
36+
if !strings.Contains(string(bytes), "Field1") {
37+
t.Fatal(string(bytes))
38+
}
39+
if !strings.Contains(string(bytes), "Field2") {
40+
t.Fatal(string(bytes))
41+
}
3842
}
3943

4044
func Test_struct5(t *testing.T) {

0 commit comments

Comments
 (0)