github.com/gocaveman/caveman@v0.0.0-20191211162744-0ddf99dbdf6e/webutil/string-data-map.go (about) 1 package webutil 2 3 import ( 4 "database/sql/driver" 5 "encoding/json" 6 "fmt" 7 ) 8 9 // StringDataMap describes a map of string keys and generic interface values. 10 // Implementations are not thread-safe. 11 type StringDataMap interface { 12 Data(key string) interface{} 13 Keys() []string 14 Set(key string, val interface{}) // Set("key", nil) will delete "key" 15 } 16 17 // StringDataMapReader has read methods for a map, is a subset of StringDataMap. 18 type StringDataMapReader interface { 19 Data(key string) interface{} 20 Keys() []string 21 } 22 23 // type check 24 var _ StringDataMap = SimpleStringDataMap{} 25 26 // SimpleStringDataMap implements StringDataMap on top of map[string]interface{}. 27 type SimpleStringDataMap map[string]interface{} 28 29 func (m SimpleStringDataMap) Data(key string) interface{} { 30 return m[key] 31 } 32 func (m SimpleStringDataMap) Keys() (ret []string) { 33 for k := range m { 34 ret = append(ret, k) 35 } 36 return 37 } 38 func (m SimpleStringDataMap) Set(key string, val interface{}) { 39 if val == nil { 40 delete(m, key) 41 } else { 42 m[key] = val 43 } 44 } 45 46 func (m *SimpleStringDataMap) Scan(value interface{}) error { 47 if value == nil { 48 *m = nil 49 return nil 50 } 51 *m = make(SimpleStringDataMap) 52 err := fmt.Errorf("cannot Scan() type %T", value) 53 switch v := value.(type) { 54 case string: 55 err = json.Unmarshal([]byte(v), m) 56 case []byte: 57 err = json.Unmarshal(v, m) 58 } 59 return err 60 } 61 62 func (m SimpleStringDataMap) Value() (driver.Value, error) { 63 b, err := json.Marshal(m) 64 return driver.Value(string(b)), err 65 }