github.com/masahide/goansible@v0.0.0-20160116054156-01eac649e9f2/scope.go (about) 1 package goansible 2 3 import ( 4 "encoding/json" 5 "fmt" 6 ) 7 8 type Value interface { 9 Read() interface{} 10 } 11 12 type AnyValue struct { 13 v interface{} 14 } 15 16 func (a AnyValue) Read() interface{} { 17 return a.v 18 } 19 20 type AnyMap struct { 21 m map[interface{}]interface{} 22 } 23 24 func (a AnyMap) Read() interface{} { 25 return a.m 26 } 27 28 func (a AnyMap) Get(key string) (Value, bool) { 29 if v, ok := a.m[key]; ok { 30 return Any(v), true 31 } 32 33 return nil, false 34 } 35 36 type StrMap struct { 37 m map[string]interface{} 38 } 39 40 func (a StrMap) Get(key string) (Value, bool) { 41 if v, ok := a.m[key]; ok { 42 return Any(v), true 43 } 44 45 return nil, false 46 } 47 48 func (a StrMap) Read() interface{} { 49 return a.m 50 } 51 52 func (a AnyValue) MarshalJSON() ([]byte, error) { 53 return json.Marshal(a.v) 54 } 55 56 func (a AnyMap) MarshalJSON() ([]byte, error) { 57 return json.Marshal(a.m) 58 } 59 60 func (a StrMap) MarshalJSON() ([]byte, error) { 61 return json.Marshal(a.m) 62 } 63 64 func Any(v interface{}) Value { 65 switch sv := v.(type) { 66 case AnyValue: 67 return sv 68 case map[interface{}]interface{}: 69 return AnyMap{sv} 70 case map[string]interface{}: 71 return StrMap{sv} 72 default: 73 return AnyValue{v} 74 } 75 } 76 77 func (a AnyValue) GetYAML() (string, interface{}) { 78 return "", a.v 79 } 80 81 func (a AnyValue) SetYAML(tag string, v interface{}) bool { 82 a.v = v 83 return true 84 } 85 86 type Map interface { 87 Get(key string) (Value, bool) 88 } 89 90 type Scope interface { 91 Get(key string) (Value, bool) 92 Set(key string, val interface{}) 93 } 94 95 type ScopeGetter interface { 96 Get(key string) (Value, bool) 97 } 98 99 func SV(v interface{}, ok bool) interface{} { 100 if !ok { 101 return nil 102 } 103 104 return v 105 } 106 107 type NestedScope struct { 108 Scope Scope 109 Vars Vars 110 } 111 112 func NewNestedScope(parent Scope) *NestedScope { 113 return &NestedScope{parent, make(Vars)} 114 } 115 116 func SpliceOverrides(cur Scope, override *NestedScope) *NestedScope { 117 ns := NewNestedScope(cur) 118 119 for k, v := range override.Vars { 120 ns.Set(k, v) 121 } 122 123 return ns 124 } 125 126 func (n *NestedScope) Get(key string) (v Value, ok bool) { 127 v, ok = n.Vars[key] 128 if !ok && n.Scope != nil { 129 v, ok = n.Scope.Get(key) 130 } 131 132 return 133 } 134 135 func (n *NestedScope) Set(key string, v interface{}) { 136 n.Vars[key] = Any(v) 137 } 138 139 func (n *NestedScope) Empty() bool { 140 return len(n.Vars) == 0 141 } 142 143 func (n *NestedScope) Flatten() Scope { 144 if len(n.Vars) == 0 && n.Scope != nil { 145 return n.Scope 146 } 147 148 return n 149 } 150 151 func (n *NestedScope) addMapVars(mv map[interface{}]interface{}) error { 152 for k, v := range mv { 153 if sk, ok := k.(string); ok { 154 if sv, ok := v.(string); ok { 155 var err error 156 157 v, err = ExpandVars(n, sv) 158 if err != nil { 159 return err 160 } 161 } 162 163 n.Set(sk, v) 164 } 165 } 166 167 return nil 168 } 169 170 func (n *NestedScope) addVars(vars interface{}) (err error) { 171 switch mv := vars.(type) { 172 case map[interface{}]interface{}: 173 err = n.addMapVars(mv) 174 case []interface{}: 175 for _, i := range mv { 176 err = n.addVars(i) 177 if err != nil { 178 return 179 } 180 } 181 } 182 183 return 184 } 185 186 func ImportVarsFile(s Scope, path string) error { 187 //pp.Print(path) 188 var fv map[string]string 189 190 err := yamlFile(path, &fv) 191 192 if err != nil { 193 return err 194 } 195 196 for k, v := range fv { 197 s.Set(k, inferString(v)) 198 } 199 200 return nil 201 } 202 203 func DisplayScope(s Scope) { 204 if ns, ok := s.(*NestedScope); ok { 205 DisplayScope(ns.Scope) 206 207 for k, v := range ns.Vars { 208 fmt.Printf("%s: %v\n", k, v) 209 } 210 } 211 }