forked from goraz/onion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
default_layer.go
103 lines (90 loc) · 2.67 KB
/
default_layer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package onion
import (
"errors"
"strings"
)
// DefaultLayer is a layer to handle default value for layer.
type DefaultLayer interface {
Layer
// SetDefault set a default value for a key
SetDefault(string, interface{}) error
// GetDelimiter is used to get current delimiter for this layer. since
// this layer needs to work with keys, the delimiter is needed
GetDelimiter() string
// SetDelimiter is used to set delimiter on this layer
SetDelimiter(d string)
}
type defaultLayer struct {
delimiter string
data map[string]interface{}
}
// Again, the case of two identical function and not convert one to another
func stringSetDefault(k []string, v interface{}, scope map[string]interface{}) error {
if len(k) == 1 {
// this is the key. just set it
scope[k[0]] = v
return nil
}
t, ok := scope[k[0]]
if ok {
// the key is already there. check if its another map?
switch m := t.(type) {
case map[string]interface{}:
return stringSetDefault(k[1:], v, m)
case map[interface{}]interface{}:
return interfaceSetDefault(k[1:], v, m)
default:
return errors.New("the key is not a map")
}
}
scope[k[0]] = make(map[string]interface{})
return stringSetDefault(k[1:], v, scope[k[0]].(map[string]interface{}))
}
func interfaceSetDefault(k []string, v interface{}, scope map[interface{}]interface{}) error {
if len(k) == 1 {
// this is the key. just set it
scope[k[0]] = v
return nil
}
t, ok := scope[k[0]]
if ok {
// the key is already there. check if its another map?
switch m := t.(type) {
case map[string]interface{}:
return stringSetDefault(k[1:], v, m)
case map[interface{}]interface{}:
return interfaceSetDefault(k[1:], v, m)
default:
return errors.New("the key is not a map")
}
}
scope[k[0]] = make(map[string]interface{})
return stringSetDefault(k[1:], v, scope[k[0]].(map[string]interface{}))
}
func (dl *defaultLayer) Load() (map[string]interface{}, error) {
return dl.data, nil
}
func (dl *defaultLayer) SetDefault(k string, v interface{}) error {
ka := strings.Split(k, dl.GetDelimiter())
return stringSetDefault(ka, v, dl.data)
}
// GetDelimiter return the delimiter for nested key
func (dl defaultLayer) GetDelimiter() string {
if dl.delimiter == "" {
dl.delimiter = "."
}
return dl.delimiter
}
// SetDelimiter set the current delimiter
func (dl *defaultLayer) SetDelimiter(d string) {
dl.delimiter = d
}
// NewDefaultLayer is used to return a default layer. should load this layer
// before any other layer, and before adding it, must add default value before
// adding this layer to onion.
func NewDefaultLayer() DefaultLayer {
return &defaultLayer{
delimiter: DefaultDelimiter,
data: make(map[string]interface{}),
}
}