From 28f6100264d516d02bb150ade745e92316227666 Mon Sep 17 00:00:00 2001 From: Bogdan Daragan <19273017+BoRuDar@users.noreply.github.com> Date: Tue, 28 Jun 2022 22:45:12 +0100 Subject: [PATCH] Support slices of pointers (#21) --- configurator_test.go | 10 ++++++++++ fieldSetter.go | 9 +++++++++ fieldStetter_test.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/configurator_test.go b/configurator_test.go index 1d5b98d..ae5fcd3 100644 --- a/configurator_test.go +++ b/configurator_test.go @@ -16,6 +16,11 @@ func TestConfigurator(t *testing.T) { // setting env variable t.Setenv("AGE_ENV", "45") + expectedURLs := []string{ + "http://localhost:3000", + "1.2.3.4:8080", + } + // defining a struct cfg := struct { Name string `flag:"name"` @@ -34,6 +39,7 @@ func TestConfigurator(t *testing.T) { IntSlice []int64 `default:"3; 4"` unexported string `xml:"ignored"` } + URLs []*string `default:"http://localhost:3000;1.2.3.4:8080"` }{} configurator := New( @@ -66,6 +72,10 @@ func TestConfigurator(t *testing.T) { assert(t, []string{"one", "two"}, cfg.Obj.StrSlice) assert(t, []int64{3, 4}, cfg.Obj.IntSlice) assert(t, time.Millisecond*100, cfg.ObjPtr.HundredMS) + + for i := range expectedURLs { + assert(t, expectedURLs[i], *cfg.URLs[i]) + } } func TestConfigurator_Errors(t *testing.T) { diff --git a/fieldSetter.go b/fieldSetter.go index 6d59606..0df6ebc 100644 --- a/fieldSetter.go +++ b/fieldSetter.go @@ -109,6 +109,15 @@ func setSlice(t reflect.Type, v reflect.Value, val string) error { slice.Index(i).SetBool(val) } + case reflect.Pointer: + slice = reflect.MakeSlice(t, size, size) + for i := 0; i < size; i++ { + err := setPtrValue(slice.Index(i).Type(), slice.Index(i), items[i]) + if err != nil { + return fmt.Errorf("setSlice: cannot set type [%s] at index [%d]", slice.Index(i).Type(), i) + } + } + default: return fmt.Errorf("setSlice: unsupported type of slice item: %v", t.Elem().Kind().String()) } diff --git a/fieldStetter_test.go b/fieldStetter_test.go index 49c6a04..0d33923 100644 --- a/fieldStetter_test.go +++ b/fieldStetter_test.go @@ -391,3 +391,37 @@ func TestSetValue_Unsupported(t *testing.T) { err = setSlice(fieldType, fieldVal, testValue) assert(t, "setSlice: unsupported type of slice item: struct", err.Error()) } + +func TestSetValue_IntPtrSlice(t *testing.T) { + var testStr []*int + fieldType := reflect.TypeOf(&testStr).Elem() + fieldVal := reflect.ValueOf(&testStr).Elem() + testValue := "1;2;3" + ints := []int{1, 2, 3} + expected := []*int{&ints[0], &ints[1], &ints[2]} + + err := setValue(fieldType, fieldVal, testValue) + if err != nil { + t.Fatal(err) + } + + if !reflect.DeepEqual(expected, fieldVal.Interface()) { + t.Fatalf("\nexpected result: %+v \nbut got: %+v", expected, fieldVal.Interface()) + } +} + +func TestSetValue_IntPtrSlice_Err(t *testing.T) { + var testStr []*struct{} + fieldType := reflect.TypeOf(&testStr).Elem() + fieldVal := reflect.ValueOf(&testStr).Elem() + testValue := "1;2;4" + + err := setValue(fieldType, fieldVal, testValue) + if err == nil { + t.Fatal("expected err but got nil") + } + + if err.Error() != "setSlice: cannot set type [*struct {}] at index [0]" { + t.Fatalf("wrong error: %v", err) + } +}