forked from TrueCloudLab/frostfs-node
[#877] neofs-node/config: allow to provide default values
In case we have multiple sections with similar structure (e.g. shards) having defaults in a single place is easier to work with. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
118c3b3cfe
commit
cb9bf00ceb
5 changed files with 78 additions and 4 deletions
|
@ -15,9 +15,19 @@ func (x *Config) Sub(name string) *Config {
|
|||
|
||||
copy(path, x.path)
|
||||
|
||||
var defaultPath []string
|
||||
if x.defaultPath != nil {
|
||||
ln := len(x.defaultPath)
|
||||
defaultPath = make([]string, ln, ln+1)
|
||||
copy(defaultPath, x.defaultPath)
|
||||
}
|
||||
|
||||
copy(path, x.path)
|
||||
|
||||
return &Config{
|
||||
v: x.v,
|
||||
path: append(path, name),
|
||||
defaultPath: append(defaultPath, name),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,5 +40,18 @@ func (x *Config) Sub(name string) *Config {
|
|||
//
|
||||
// Returns nil if config is nil.
|
||||
func (x *Config) Value(name string) interface{} {
|
||||
return x.v.Get(strings.Join(append(x.path, name), separator))
|
||||
value := x.v.Get(strings.Join(append(x.path, name), separator))
|
||||
if value != nil || x.defaultPath == nil {
|
||||
return value
|
||||
}
|
||||
return x.v.Get(strings.Join(append(x.defaultPath, name), separator))
|
||||
}
|
||||
|
||||
// SetDefault sets fallback config for missing values.
|
||||
//
|
||||
// It supports only one level of nesting and is intended to be used
|
||||
// to provide default values.
|
||||
func (x *Config) SetDefault(from *Config) {
|
||||
x.defaultPath = make([]string, len(from.path))
|
||||
copy(x.defaultPath, from.path)
|
||||
}
|
||||
|
|
|
@ -60,3 +60,20 @@ func TestConfig_SubValue(t *testing.T) {
|
|||
require.Equal(t, "val1", sub.Value("key"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestConfig_SetDefault(t *testing.T) {
|
||||
configtest.ForEachFileType("test/config", func(c *config.Config) {
|
||||
c = c.Sub("with_default")
|
||||
s := c.Sub("custom")
|
||||
s.SetDefault(c.Sub("default"))
|
||||
|
||||
require.Equal(t, int64(42), config.Int(s, "missing"))
|
||||
require.Equal(t, "b", config.String(s, "overridden"))
|
||||
require.Equal(t, false, config.Bool(s, "overridden_with_default"))
|
||||
|
||||
// Default can be set only once.
|
||||
s = s.Sub("sub")
|
||||
require.Equal(t, int64(123), config.Int(s, "missing"))
|
||||
require.Equal(t, "y", config.String(s, "overridden"))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
type Config struct {
|
||||
v *viper.Viper
|
||||
|
||||
defaultPath []string
|
||||
path []string
|
||||
}
|
||||
|
||||
|
|
|
@ -56,5 +56,24 @@
|
|||
"size_tb": "5 TB",
|
||||
"size_bytes": "2048b",
|
||||
"size_bytes_no_suffix": 123456
|
||||
},
|
||||
|
||||
"with_default": {
|
||||
"default": {
|
||||
"sub": {
|
||||
"missing": 123,
|
||||
"overridden": "x"
|
||||
},
|
||||
"missing": 42,
|
||||
"overridden": "a",
|
||||
"overridden_with_default": true
|
||||
},
|
||||
"custom": {
|
||||
"sub": {
|
||||
"overridden": "y"
|
||||
},
|
||||
"overridden": "b",
|
||||
"overridden_with_default": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,3 +49,17 @@ sizes:
|
|||
size_tb: 5 TB
|
||||
size_bytes: 2048b
|
||||
size_bytes_no_suffix: 123456
|
||||
|
||||
with_default:
|
||||
default:
|
||||
sub:
|
||||
missing: 123
|
||||
overridden: "x"
|
||||
missing: 42
|
||||
overridden: "a"
|
||||
overridden_with_default: true
|
||||
custom:
|
||||
sub:
|
||||
overridden: "y"
|
||||
overridden: "b"
|
||||
overridden_with_default: false
|
||||
|
|
Loading…
Reference in a new issue