Skip to content
Merged
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
33 changes: 23 additions & 10 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func getLoggerValue(field fmap.Field, val any) string {
return valueLog
}

func copyToSubConfig(conf, subConf any, subpath string) error {
func copyToSubConfig(conf, subConf any, subpath string, parsedPaths []string) error {
confFields, err := fmap.GetFrom(conf)
if err != nil {
return err
Expand All @@ -82,15 +82,24 @@ func copyToSubConfig(conf, subConf any, subpath string) error {
return err
}
for _, path := range confFields.GetAllPaths() {
if path != subpath && strings.HasPrefix(path, subpath) {
field := confFields.MustFind(path)
subFieldPath := strings.Replace(path, subpath+".", "", -1)
subField, ok := subConfFields.Find(subFieldPath)
if !ok {
return fmt.Errorf("subconf field %s not found", path)
// exclude paths that is not parsed by tinyconf drivers
skip := true
for _, parsedPath := range parsedPaths {
if path == parsedPath {
skip = false
break
}
subField.Set(subConf, field.Get(conf))
}
if skip || path == subpath || !strings.HasPrefix(path, subpath) {
continue
}
field := confFields.MustFind(path)
subFieldPath := strings.Replace(path, subpath+".", "", -1)
subField, ok := subConfFields.Find(subFieldPath)
if !ok {
return fmt.Errorf("subconf field %s not found", path)
}
subField.Set(subConf, field.Get(conf))
}
return nil
}
Expand All @@ -99,7 +108,9 @@ func (c *Manager) Parse(conf any) (err error) {
confParse := conf
confTypeOf := reflect.TypeOf(conf)
register, ok := c.registered[confTypeOf]
parsedPaths := make([]string, 0)
if !ok {
RegisteredLoop:
for registeredTypeOf, registeredConf := range c.registered {
for _, path := range registeredConf.Storage.GetAllPaths() {
field := registeredConf.Storage.MustFind(path)
Expand All @@ -109,9 +120,9 @@ func (c *Manager) Parse(conf any) (err error) {
register = registeredConf
confParse = reflect.New(registeredTypeOf.Elem()).Interface()
defer func() {
err = copyToSubConfig(confParse, conf, field.GetStructPath())
err = copyToSubConfig(confParse, conf, field.GetStructPath(), parsedPaths)
}()
break
break RegisteredLoop
}
}
}
Expand Down Expand Up @@ -144,6 +155,8 @@ func (c *Manager) Parse(conf any) (err error) {
if currentValue != driverValue.Value {
log.Debug("override", LogField("value", getLoggerValue(field, driverValue.Value)))
field.Set(confParse, driverValue.Value)
// only for sub configs
parsedPaths = append(parsedPaths, path)
}
}
}
Expand Down
56 changes: 46 additions & 10 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,21 +329,57 @@ func (tl *testLogger) With(_ ...Field) Logger {

func TestManager_ParseSubConfig(t *testing.T) {
type FieldConfig struct {
Test string
Test string
Test2 string
}
type Config struct {
Field FieldConfig
}
c := &Manager{
drivers: []Driver{&parseMockDriver{name: "d3", value: "test"}},
registered: make(map[reflect.Type]*Registered),
log: &testLogger{},
testCases := []struct {
Name string
Drivers []Driver
expectedFieldValues any
config *FieldConfig
}{
{
Name: "Simple value",
Drivers: []Driver{
&parseMockDriver{
value: "test",
},
},
expectedFieldValues: "test",
config: &FieldConfig{},
},
{
Name: "Driver no value, no override existing fields values",
Drivers: []Driver{
&parseMockDriver{
value: "",
err: ErrValueNotFound,
},
},
expectedFieldValues: "test123",
config: &FieldConfig{
Test: "test123",
Test2: "test123",
},
},
}
for _, testCase := range testCases {
t.Run(testCase.Name, func(t *testing.T) {
c := &Manager{
drivers: testCase.Drivers,
registered: make(map[reflect.Type]*Registered),
log: &testLogger{},
}
conf := &Config{Field: FieldConfig{}}
assert.NoError(t, c.Register(conf))
assert.NoError(t, c.Parse(testCase.config))
assert.Equal(t, testCase.expectedFieldValues, testCase.config.Test)
assert.Equal(t, testCase.expectedFieldValues, testCase.config.Test2)
})
}
conf := &Config{}
subConf := &FieldConfig{}
assert.NoError(t, c.Register(conf))

assert.NoError(t, c.Parse(subConf))
}
func TestManager_Parse(t *testing.T) {
t.Parallel()
Expand Down