github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/util/generic/map.go (about) 1 package generic 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 type Map interface { 9 IsEmpty() bool 10 Count() int 11 Keys() []interface{} 12 Has(key interface{}) bool 13 Except(keys []interface{}) Map 14 IsNil(key interface{}) bool 15 NotNil(key interface{}) bool 16 Get(key interface{}) interface{} 17 Set(key interface{}, value interface{}) 18 Delete(key interface{}) 19 String() string 20 } 21 22 type ConcreteMap map[interface{}]interface{} 23 24 func newEmptyMap() Map { 25 return &ConcreteMap{} 26 } 27 28 func NewMap(data ...interface{}) Map { 29 if len(data) == 0 { 30 return newEmptyMap() 31 } else if len(data) > 1 { 32 panic("NewMap called with more than one argument") 33 } 34 35 switch data := data[0].(type) { 36 case nil: 37 return newEmptyMap() 38 case Map: 39 return data 40 case map[string]string: 41 stringMap := newEmptyMap() 42 for key, val := range data { 43 stringMap.Set(key, val) 44 } 45 return stringMap 46 case map[string]interface{}: 47 stringToInterfaceMap := newEmptyMap() 48 for key, val := range data { 49 stringToInterfaceMap.Set(key, val) 50 } 51 return stringToInterfaceMap 52 case map[interface{}]interface{}: 53 mapp := ConcreteMap(data) 54 return &mapp 55 } 56 57 fmt.Printf("\n\n map: %T", data) 58 panic("NewMap called with unexpected argument") 59 } 60 61 func (data *ConcreteMap) IsEmpty() bool { 62 return data.Count() == 0 63 } 64 65 func (data *ConcreteMap) Count() int { 66 return len(*data) 67 } 68 69 func (data *ConcreteMap) Has(key interface{}) bool { 70 _, ok := (*data)[key] 71 return ok 72 } 73 74 func (data *ConcreteMap) Except(keys []interface{}) Map { 75 otherMap := NewMap() 76 Each(data, func(key, value interface{}) { 77 if !Contains(keys, key) { 78 otherMap.Set(key, value) 79 } 80 }) 81 return otherMap 82 } 83 84 func (data *ConcreteMap) IsNil(key interface{}) bool { 85 maybe, ok := (*data)[key] 86 return ok && maybe == nil 87 } 88 89 func (data *ConcreteMap) NotNil(key interface{}) bool { 90 maybe, ok := (*data)[key] 91 return ok && maybe != nil 92 } 93 94 func (data *ConcreteMap) Keys() (keys []interface{}) { 95 keys = make([]interface{}, 0, data.Count()) 96 for key := range *data { 97 keys = append(keys, key) 98 } 99 100 return 101 } 102 103 func (data *ConcreteMap) Get(key interface{}) interface{} { 104 return (*data)[key] 105 } 106 107 func (data *ConcreteMap) Set(key, value interface{}) { 108 (*data)[key] = value 109 } 110 111 func (data *ConcreteMap) Delete(key interface{}) { 112 delete(*data, key) 113 } 114 115 func (data *ConcreteMap) String() string { 116 return fmt.Sprintf("% v", *data) 117 } 118 119 func IsMappable(value interface{}) bool { 120 if value == nil { 121 return false 122 } 123 switch value.(type) { 124 case Map: 125 return true 126 default: 127 return reflect.TypeOf(value).Kind() == reflect.Map 128 } 129 } 130 131 type Iterator func(key, val interface{}) 132 133 func Each(collection Map, cb Iterator) { 134 for _, key := range collection.Keys() { 135 cb(key, collection.Get(key)) 136 } 137 } 138 139 func Contains(collection, item interface{}) bool { 140 switch collection := collection.(type) { 141 case Map: 142 return collection.Has(item) 143 case []interface{}: 144 for _, val := range collection { 145 if val == item { 146 return true 147 } 148 } 149 return false 150 } 151 152 panic("unexpected type passed to Contains") 153 }