github.com/lingyao2333/mo-zero@v1.4.1/core/mapping/valuer.go (about) 1 package mapping 2 3 type ( 4 // A Valuer interface defines the way to get values from the underlying object with keys. 5 Valuer interface { 6 // Value gets the value associated with the given key. 7 Value(key string) (interface{}, bool) 8 } 9 10 // A valuerWithParent defines a node that has a parent node. 11 valuerWithParent interface { 12 Valuer 13 // Parent get the parent valuer for current node. 14 Parent() valuerWithParent 15 } 16 17 // A node is a map that can use Value method to get values with given keys. 18 node struct { 19 current Valuer 20 parent valuerWithParent 21 } 22 23 // A valueWithParent is used to wrap the value with its parent. 24 valueWithParent struct { 25 value interface{} 26 parent valuerWithParent 27 } 28 29 // mapValuer is a type for map to meet the Valuer interface. 30 mapValuer map[string]interface{} 31 // simpleValuer is a type to get value from current node. 32 simpleValuer node 33 // recursiveValuer is a type to get the value recursively from current and parent nodes. 34 recursiveValuer node 35 ) 36 37 // Value gets the value assciated with the given key from mv. 38 func (mv mapValuer) Value(key string) (interface{}, bool) { 39 v, ok := mv[key] 40 return v, ok 41 } 42 43 // Value gets the value associated with the given key from sv. 44 func (sv simpleValuer) Value(key string) (interface{}, bool) { 45 v, ok := sv.current.Value(key) 46 return v, ok 47 } 48 49 // Parent get the parent valuer from sv. 50 func (sv simpleValuer) Parent() valuerWithParent { 51 if sv.parent == nil { 52 return nil 53 } 54 55 return recursiveValuer{ 56 current: sv.parent, 57 parent: sv.parent.Parent(), 58 } 59 } 60 61 // Value gets the value associated with the given key from rv, 62 // and it will inherit the value from parent nodes. 63 func (rv recursiveValuer) Value(key string) (interface{}, bool) { 64 val, ok := rv.current.Value(key) 65 if !ok { 66 if parent := rv.Parent(); parent != nil { 67 return parent.Value(key) 68 } 69 70 return nil, false 71 } 72 73 vm, ok := val.(map[string]interface{}) 74 if !ok { 75 return val, true 76 } 77 78 parent := rv.Parent() 79 if parent == nil { 80 return val, true 81 } 82 83 pv, ok := parent.Value(key) 84 if !ok { 85 return val, true 86 } 87 88 pm, ok := pv.(map[string]interface{}) 89 if !ok { 90 return val, true 91 } 92 93 for k, v := range pm { 94 if _, ok := vm[k]; !ok { 95 vm[k] = v 96 } 97 } 98 99 return vm, true 100 } 101 102 // Parent get the parent valuer from rv. 103 func (rv recursiveValuer) Parent() valuerWithParent { 104 if rv.parent == nil { 105 return nil 106 } 107 108 return recursiveValuer{ 109 current: rv.parent, 110 parent: rv.parent.Parent(), 111 } 112 }