Skip to content

Commit

Permalink
Merge pull request #10 from SpectrumQT/master
Browse files Browse the repository at this point in the history
Slice of structs support
  • Loading branch information
creasty authored Jan 30, 2019
2 parents 585ac22 + 8262bff commit edf4f6a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 11 deletions.
14 changes: 11 additions & 3 deletions defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func setField(field reflect.Value, defaultVal string) error {
return nil
}

if !shouldInitializeField(field.Kind(), defaultVal) {
if !shouldInitializeField(field, defaultVal) {
return nil
}

Expand Down Expand Up @@ -157,6 +157,12 @@ func setField(field reflect.Value, defaultVal string) error {
}
callSetter(ref.Interface())
field.Set(ref.Elem())
case reflect.Slice:
for j := 0; j < field.Len(); j++ {
if err := setField(field.Index(j), defaultVal); err != nil {
return err
}
}
}

return nil
Expand All @@ -166,10 +172,12 @@ func isInitialValue(field reflect.Value) bool {
return reflect.DeepEqual(reflect.Zero(field.Type()).Interface(), field.Interface())
}

func shouldInitializeField(kind reflect.Kind, tag string) bool {
switch kind {
func shouldInitializeField(field reflect.Value, tag string) bool {
switch field.Kind() {
case reflect.Struct:
return true
case reflect.Slice:
return field.Len() > 0 || tag != ""
}

return (tag != "")
Expand Down
21 changes: 13 additions & 8 deletions defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,11 @@ type Sample struct {
NoDefault *string `default:"-"`
NoDefaultStruct Struct `default:"-"`

MapWithNoTag map[string]int
SliceWithNoTag []string
StructPtrWithNoTag *Struct
StructWithNoTag Struct
MapWithNoTag map[string]int
SliceWithNoTag []string
StructPtrWithNoTag *Struct
StructWithNoTag Struct
DeepSliceOfStructsWithNoTag [][][]Struct

NonInitialString string `default:"foo"`
NonInitialSlice []int `default:"[123]"`
Expand All @@ -110,10 +111,11 @@ type Emmbeded struct {

func TestInit(t *testing.T) {
sample := &Sample{
NonInitialString: "string",
NonInitialSlice: []int{1, 2, 3},
NonInitialStruct: Struct{Foo: 123},
NonInitialStructPtr: &Struct{Foo: 123},
NonInitialString: "string",
NonInitialSlice: []int{1, 2, 3},
NonInitialStruct: Struct{Foo: 123},
NonInitialStructPtr: &Struct{Foo: 123},
DeepSliceOfStructsWithNoTag: [][][]Struct{{{{Foo: 123}}}},
}

if err := Set(sample); err != nil {
Expand Down Expand Up @@ -346,6 +348,9 @@ func TestInit(t *testing.T) {
if sample.StructWithNoTag.WithDefault != "foo" {
t.Errorf("it should automatically recurse into a struct even without a tag")
}
if !reflect.DeepEqual(sample.DeepSliceOfStructsWithNoTag, [][][]Struct{{{{Emmbeded: Emmbeded{Int: 1}, Foo: 123, Bar: 456, WithDefault: "foo"}}}}) {
t.Errorf("it should automatically recurse into a slice of structs even without a tag")
}
})

t.Run("opt-out", func(t *testing.T) {
Expand Down

0 comments on commit edf4f6a

Please sign in to comment.