diff --git a/defaults.go b/defaults.go index 1882ac9..3f77fd5 100644 --- a/defaults.go +++ b/defaults.go @@ -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 } @@ -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 @@ -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 != "") diff --git a/defaults_test.go b/defaults_test.go index 8c7b897..b04ca6b 100644 --- a/defaults_test.go +++ b/defaults_test.go @@ -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]"` @@ -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 { @@ -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) {