From 3f36236a5818536cb219a218f1aeb43aa441fcc7 Mon Sep 17 00:00:00 2001 From: oldme Date: Thu, 21 Dec 2023 11:32:41 +0800 Subject: [PATCH 1/4] enhance #3221 --- util/gutil/gutil_struct.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/util/gutil/gutil_struct.go b/util/gutil/gutil_struct.go index dee73648119..0e155f2caa4 100644 --- a/util/gutil/gutil_struct.go +++ b/util/gutil/gutil_struct.go @@ -89,6 +89,14 @@ func FillStructWithDefault(structPtr interface{}) error { return err } for _, field := range fields { + if field.Kind() == reflect.Struct { + err := FillStructWithDefault(field.Value.Addr()) + if err != nil { + return err + } + continue + } + if defaultValue := field.TagDefault(); defaultValue != "" { if field.IsEmpty() { field.Value.Set(reflect.ValueOf( @@ -97,5 +105,6 @@ func FillStructWithDefault(structPtr interface{}) error { } } } + return nil } From 5e0ab2a6c94ef1e7a2f3293d2d36c6eee54b6d9f Mon Sep 17 00:00:00 2001 From: oldme Date: Thu, 21 Dec 2023 14:19:17 +0800 Subject: [PATCH 2/4] enhance #3221 --- util/gutil/gutil_struct.go | 2 +- util/gutil/gutil_z_unit_struct_test.go | 32 +++++++++++++++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/util/gutil/gutil_struct.go b/util/gutil/gutil_struct.go index 0e155f2caa4..9aea7709d7d 100644 --- a/util/gutil/gutil_struct.go +++ b/util/gutil/gutil_struct.go @@ -83,7 +83,7 @@ func FillStructWithDefault(structPtr interface{}) error { } fields, err := gstructs.Fields(gstructs.FieldsInput{ Pointer: reflectValue, - RecursiveOption: gstructs.RecursiveOptionNone, + RecursiveOption: gstructs.RecursiveOptionEmbedded, }) if err != nil { return err diff --git a/util/gutil/gutil_z_unit_struct_test.go b/util/gutil/gutil_z_unit_struct_test.go index fe4b62e9753..d4cf0d52751 100755 --- a/util/gutil/gutil_z_unit_struct_test.go +++ b/util/gutil/gutil_z_unit_struct_test.go @@ -40,16 +40,32 @@ func Test_StructToSlice(t *testing.T) { func Test_FillStructWithDefault(t *testing.T) { gtest.C(t, func(t *gtest.T) { type A struct { - V1 int `d:"1.01"` - V2 string `d:"1.01"` - V3 float32 `d:"1.01"` + A1 int `d:"1.01"` + A2 string `d:"1.01"` + A3 float32 `d:"1.01"` } - a := A{} - err := gutil.FillStructWithDefault(&a) + type B struct { + B1 bool `d:"true"` + B2 string + A A + } + type C struct { + C1 float64 `d:"1.01"` + B + C2 bool + A A + } + + c := C{} + err := gutil.FillStructWithDefault(&c) t.AssertNil(err) - t.Assert(a.V1, `1`) - t.Assert(a.V2, `1.01`) - t.Assert(a.V3, `1.01`) + t.Assert(c.C1, `1.01`) + t.Assert(c.C2, false) + t.Assert(c.B1, true) + t.Assert(c.B2, ``) + t.Assert(c.A.A1, `1`) + t.Assert(c.A.A2, `1.01`) + t.Assert(c.A.A3, `1.01`) }) } From a4096028b5fa69a2a62917f4eb0f1a047d44e801 Mon Sep 17 00:00:00 2001 From: oldme Date: Fri, 22 Dec 2023 13:41:35 +0800 Subject: [PATCH 3/4] enhance #3221 --- os/gstructs/gstructs_field.go | 17 +++++++++ util/gutil/gutil_struct.go | 4 +- util/gutil/gutil_z_unit_struct_test.go | 51 +++++++++++++++----------- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/os/gstructs/gstructs_field.go b/os/gstructs/gstructs_field.go index 12213b73d44..870ce727504 100644 --- a/os/gstructs/gstructs_field.go +++ b/os/gstructs/gstructs_field.go @@ -92,9 +92,26 @@ func (f *Field) OriginalKind() reflect.Kind { reflectType = reflectType.Elem() reflectKind = reflectType.Kind() } + return reflectKind } +// OriginalValue retrieves and returns the original reflect.Value of Field `f`. +func (f *Field) OriginalValue() reflect.Value { + var ( + reflectValue = f.Value + reflectType = reflectValue.Type() + reflectKind = reflectType.Kind() + ) + + for reflectKind == reflect.Ptr && !reflectValue.IsNil() { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Type().Kind() + } + + return reflectValue +} + // IsEmpty checks and returns whether the value of this Field is empty. func (f *Field) IsEmpty() bool { return empty.IsEmpty(f.Value) diff --git a/util/gutil/gutil_struct.go b/util/gutil/gutil_struct.go index 9aea7709d7d..f0b87cbcd90 100644 --- a/util/gutil/gutil_struct.go +++ b/util/gutil/gutil_struct.go @@ -89,8 +89,8 @@ func FillStructWithDefault(structPtr interface{}) error { return err } for _, field := range fields { - if field.Kind() == reflect.Struct { - err := FillStructWithDefault(field.Value.Addr()) + if field.OriginalKind() == reflect.Struct { + err := FillStructWithDefault(field.OriginalValue().Addr()) if err != nil { return err } diff --git a/util/gutil/gutil_z_unit_struct_test.go b/util/gutil/gutil_z_unit_struct_test.go index d4cf0d52751..6f2785cddb2 100755 --- a/util/gutil/gutil_z_unit_struct_test.go +++ b/util/gutil/gutil_z_unit_struct_test.go @@ -39,33 +39,40 @@ func Test_StructToSlice(t *testing.T) { func Test_FillStructWithDefault(t *testing.T) { gtest.C(t, func(t *gtest.T) { - type A struct { - A1 int `d:"1.01"` - A2 string `d:"1.01"` - A3 float32 `d:"1.01"` + type myInt int + type Inner1 struct { + I1V1 int + I1V2 bool `d:"true"` } - type B struct { - B1 bool `d:"true"` - B2 string - A A + type Inner2 struct { + I2V1 float64 `d:"1.01"` } - type C struct { - C1 float64 `d:"1.01"` - B - C2 bool - A A + type Inner3 struct { + Inner1 Inner1 + I3V1 myInt `d:"1"` + } + type Outer struct { + O1 int `d:"1.01"` + O2 string `d:"1.01"` + O3 float32 `d:"1.01"` + *Inner1 + O4 bool `d:"true"` + Inner2 + Inner3 Inner3 } - c := C{} - err := gutil.FillStructWithDefault(&c) + outer := Outer{} + err := gutil.FillStructWithDefault(&outer) t.AssertNil(err) - t.Assert(c.C1, `1.01`) - t.Assert(c.C2, false) - t.Assert(c.B1, true) - t.Assert(c.B2, ``) - t.Assert(c.A.A1, `1`) - t.Assert(c.A.A2, `1.01`) - t.Assert(c.A.A3, `1.01`) + t.Assert(outer.O1, 1) + t.Assert(outer.O2, `1.01`) + t.Assert(outer.O3, `1.01`) + t.Assert(outer.O4, true) + t.Assert(outer.Inner1, nil) + t.Assert(outer.Inner2.I2V1, `1.01`) + t.Assert(outer.Inner3.I3V1, 1) + t.Assert(outer.Inner3.Inner1.I1V1, 0) + t.Assert(outer.Inner3.Inner1.I1V2, true) }) } From be95cf67f2a4315d21a937db26f071bb82be079c Mon Sep 17 00:00:00 2001 From: oldme Date: Fri, 22 Dec 2023 14:07:54 +0800 Subject: [PATCH 4/4] enhance #3221 --- os/gstructs/gstructs_field.go | 2 +- util/gutil/gutil_z_unit_struct_test.go | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/os/gstructs/gstructs_field.go b/os/gstructs/gstructs_field.go index 870ce727504..639291fd25c 100644 --- a/os/gstructs/gstructs_field.go +++ b/os/gstructs/gstructs_field.go @@ -104,7 +104,7 @@ func (f *Field) OriginalValue() reflect.Value { reflectKind = reflectType.Kind() ) - for reflectKind == reflect.Ptr && !reflectValue.IsNil() { + for reflectKind == reflect.Ptr && !f.IsNil() { reflectValue = reflectValue.Elem() reflectKind = reflectValue.Type().Kind() } diff --git a/util/gutil/gutil_z_unit_struct_test.go b/util/gutil/gutil_z_unit_struct_test.go index 6f2785cddb2..d9ebde8057b 100755 --- a/util/gutil/gutil_z_unit_struct_test.go +++ b/util/gutil/gutil_z_unit_struct_test.go @@ -51,6 +51,8 @@ func Test_FillStructWithDefault(t *testing.T) { Inner1 Inner1 I3V1 myInt `d:"1"` } + type Inner4 struct { + } type Outer struct { O1 int `d:"1.01"` O2 string `d:"1.01"` @@ -59,6 +61,7 @@ func Test_FillStructWithDefault(t *testing.T) { O4 bool `d:"true"` Inner2 Inner3 Inner3 + Inner4 *Inner4 } outer := Outer{} @@ -74,5 +77,6 @@ func Test_FillStructWithDefault(t *testing.T) { t.Assert(outer.Inner3.I3V1, 1) t.Assert(outer.Inner3.Inner1.I1V1, 0) t.Assert(outer.Inner3.Inner1.I1V2, true) + t.Assert(outer.Inner4, nil) }) }