diff --git a/aconfig_test.go b/aconfig_test.go index dcb7789..2311efd 100644 --- a/aconfig_test.go +++ b/aconfig_test.go @@ -1536,10 +1536,11 @@ func TestFileConfigFlagDelim(t *testing.T) { func TestSliceOfStructsWithSliceOfPrimitives(t *testing.T) { type TestService struct { - Name string - Strings []string - Integers []int - Booleans []bool + Name string + Strings []string + Integers []int + Booleans []bool + AnotherStrings []string `json:"another_strings"` } type TestConfig struct { @@ -1558,10 +1559,11 @@ func TestSliceOfStructsWithSliceOfPrimitives(t *testing.T) { want := TestConfig{ Services: []TestService{ { - Name: "service1", - Strings: []string{"string1", "string2"}, - Integers: []int{1, 2}, - Booleans: []bool{true, false}, + Name: "service1", + Strings: []string{"string1", "string2"}, + Integers: []int{1, 2}, + Booleans: []bool{true, false}, + AnotherStrings: []string{"another1", "another2"}, }, }, } diff --git a/reflection.go b/reflection.go index c4892e9..3d5f2b5 100644 --- a/reflection.go +++ b/reflection.go @@ -358,22 +358,42 @@ func (l *Loader) setMap(field *fieldData, value string) error { } func (l *Loader) m2s(m map[string]interface{}, structValue reflect.Value) error { - for name, value := range m { - name = strings.Title(name) - structFieldValue := structValue.FieldByName(name) - if !structFieldValue.IsValid() { - return fmt.Errorf("no such field %q in struct", name) - } + for _, dec := range l.config.FileDecoders { + for name, value := range m { + structFieldValue := structValue.FieldByName(name) + for i := 0; i < structValue.NumField(); i++ { + // first try to find field by name + tagName := structValue.Type().Field(i).Tag.Get(dec.Format()) + // if tag is set - use it + if strings.EqualFold(tagName, name) { + name = structValue.Type().Field(i).Name + structFieldValue = structValue.FieldByName(name) + break + } + // if tag is not set - try to find field by name + if tagName == "" { + if strings.EqualFold(structValue.Type().Field(i).Name, name) { + name = structValue.Type().Field(i).Name + structFieldValue = structValue.FieldByName(name) + break + } + } + } - if !structFieldValue.CanSet() { - return fmt.Errorf("cannot set %q field value", name) - } + if !structFieldValue.IsValid() { + return fmt.Errorf("no such field %q in struct", name) + } - field, _ := structValue.Type().FieldByName(name) + if !structFieldValue.CanSet() { + return fmt.Errorf("cannot set %q field value", name) + } - fd := l.newFieldData(field, structFieldValue, nil) - if err := l.setFieldData(fd, value); err != nil { - return err + field, _ := structValue.Type().FieldByName(name) + + fd := l.newFieldData(field, structFieldValue, nil) + if err := l.setFieldData(fd, value); err != nil { + return err + } } } return nil diff --git a/testdata/slice-struct-primitive-slice.json b/testdata/slice-struct-primitive-slice.json index 0010a0e..d7676e0 100644 --- a/testdata/slice-struct-primitive-slice.json +++ b/testdata/slice-struct-primitive-slice.json @@ -4,7 +4,8 @@ "name": "service1", "strings": ["string1", "string2"], "integers": [1, 2], - "booleans": [true, false] + "booleans": [true, false], + "another_strings": ["another1", "another2"] } ] }