Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance #3221 #3224

Merged
merged 5 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions os/gstructs/gstructs_field.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 && !f.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)
Expand Down
11 changes: 10 additions & 1 deletion util/gutil/gutil_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,20 @@ func FillStructWithDefault(structPtr interface{}) error {
}
fields, err := gstructs.Fields(gstructs.FieldsInput{
Pointer: reflectValue,
RecursiveOption: gstructs.RecursiveOptionNone,
RecursiveOption: gstructs.RecursiveOptionEmbedded,
})
if err != nil {
return err
}
for _, field := range fields {
if field.OriginalKind() == reflect.Struct {
err := FillStructWithDefault(field.OriginalValue().Addr())
if err != nil {
return err
}
continue
}

if defaultValue := field.TagDefault(); defaultValue != "" {
if field.IsEmpty() {
field.Value.Set(reflect.ValueOf(
Expand All @@ -97,5 +105,6 @@ func FillStructWithDefault(structPtr interface{}) error {
}
}
}

return nil
}
45 changes: 36 additions & 9 deletions util/gutil/gutil_z_unit_struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,44 @@ 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"`
type myInt int
type Inner1 struct {
I1V1 int
I1V2 bool `d:"true"`
}
a := A{}
err := gutil.FillStructWithDefault(&a)
type Inner2 struct {
I2V1 float64 `d:"1.01"`
}
type Inner3 struct {
Inner1 Inner1
I3V1 myInt `d:"1"`
}
type Inner4 struct {
}
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
Inner4 *Inner4
}

outer := Outer{}
err := gutil.FillStructWithDefault(&outer)
t.AssertNil(err)

t.Assert(a.V1, `1`)
t.Assert(a.V2, `1.01`)
t.Assert(a.V3, `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)
t.Assert(outer.Inner4, nil)
})
}