Add Sub() for Viper, which returns a branch of a Viper instance.

This commit is contained in:
Lei Feng 2015-12-24 19:44:44 +08:00
parent 79971f1ae7
commit 105e3d0d19
3 changed files with 71 additions and 0 deletions

View file

@ -441,6 +441,52 @@ will be returned instead. E.g.
GetString("datastore.metric.host") //returns "0.0.0.0" GetString("datastore.metric.host") //returns "0.0.0.0"
``` ```
### Extract sub-tree
Extract sub-tree from Viper.
For example, `viper` represents:
```json
app:
cache1:
max-items: 100
item-size: 64
cache2:
max-items: 200
item-size: 80
```
After executing:
```go
subv := viper.Sub("app.cache1")
```
`subv` represents:
```json
max-items: 100
item-size: 64
```
Suppose we have:
```go
func NewCache(cfg *Viper) *Cache {...}
```
which creates a cache based on config information formatted as `subv`.
Now it's easy to create these 2 caches separately as:
```go
cfg1 := viper.Sub("app.cache1")
cache1 := NewCache(cfg1)
cfg2 := viper.Sub("app.cache2")
cache2 := NewCache(cfg2)
```
### Unmarshaling ### Unmarshaling
You also have the option of Unmarshaling all or a specific value to a struct, map, You also have the option of Unmarshaling all or a specific value to a struct, map,

View file

@ -513,6 +513,18 @@ func (v *Viper) Get(key string) interface{} {
return val return val
} }
// Returns new Viper instance representing a sub tree of this instance
func Sub(key string) *Viper { return v.Sub(key) }
func (v *Viper) Sub(key string) *Viper {
data, ok := v.Get(key).(map[string]interface{})
if !ok {
return nil
}
subv := New()
subv.config = data
return subv
}
// Returns the value associated with the key as a string // Returns the value associated with the key as a string
func GetString(key string) string { return v.GetString(key) } func GetString(key string) string { return v.GetString(key) }
func (v *Viper) GetString(key string) string { func (v *Viper) GetString(key string) string {

View file

@ -724,3 +724,16 @@ func TestWrongDirsSearchNotFound(t *testing.T) {
// been ignored by the client, the default still loads // been ignored by the client, the default still loads
assert.Equal(t, `default`, v.GetString(`key`)) assert.Equal(t, `default`, v.GetString(`key`))
} }
func TestSub(t *testing.T) {
v := New()
v.SetConfigType("yaml")
v.ReadConfig(bytes.NewBuffer(yamlExample))
subv := v.Sub("clothing.pants")
assert.Equal(t, v.Get("clothing.pants.size"), subv.Get("size"))
subv = v.Sub("clothing.pants.size")
assert.Equal(t, subv, (*Viper)(nil))
}