Skip to content
Open
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
18 changes: 10 additions & 8 deletions aconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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"},
},
},
}
Expand Down
46 changes: 33 additions & 13 deletions reflection.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion testdata/slice-struct-primitive-slice.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"name": "service1",
"strings": ["string1", "string2"],
"integers": [1, 2],
"booleans": [true, false]
"booleans": [true, false],
"another_strings": ["another1", "another2"]
}
]
}
Loading