github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmgType/MapType.go (about) 1 package kmgType 2 3 import ( 4 "fmt" 5 "reflect" 6 ) 7 8 //path -> key(Key type) 9 //key can be bool,string,stringEnum,int,float, 10 //map elem CanSet() will be false 11 //even if map CanSet false , SetMapIndex will success 12 //if elem change(can not set),map must use SetMapIndex to set it.. 13 type MapType struct { 14 reflectTypeGetterImp 15 KeyStringConverter StringConverterInterface 16 KeyType KmgType 17 ElemType KmgType 18 } 19 20 func (t *MapType) Init() (err error) { 21 if t.KeyStringConverter != nil { 22 return 23 } 24 t.KeyType, err = TypeOf(t.GetReflectType().Key()) 25 if err != nil { 26 return err 27 } 28 var ok bool 29 t.KeyStringConverter, ok = t.KeyType.(StringConverterInterface) 30 if !ok { 31 return fmt.Errorf( 32 "mapType key type not implement stringConverterType,key: %s", 33 t.KeyType.GetReflectType().Kind().String(), 34 ) 35 } 36 t.ElemType, err = TypeOf(t.GetReflectType().Elem()) 37 if err != nil { 38 return err 39 } 40 return nil 41 } 42 43 func (t *MapType) GetElemByString(v reflect.Value, k string) (ev reflect.Value, et KmgType, err error) { 44 err = t.Init() 45 if err != nil { 46 return 47 } 48 vk, err := t.KeyStringConverter.FromString(k) 49 if err != nil { 50 return 51 } 52 if err != nil { 53 return 54 } 55 ev = v.MapIndex(vk) 56 if !ev.IsValid() { 57 err = fmt.Errorf("[mapType.getSubValueByString] map key not found k:%s", k) 58 return 59 } 60 et = t.ElemType 61 return 62 } 63 64 func (t *MapType) SaveByPath(v *reflect.Value, path Path, value string) (err error) { 65 err = t.Init() 66 if err != nil { 67 return 68 } 69 if len(path) == 0 { 70 return fmt.Errorf("[mapType.save] get map with no path, value:%s", value) 71 } 72 //OriginCanSet := v.CanSet() 73 if v.IsNil() { 74 if v.CanSet() { 75 v.Set(reflect.MakeMap(t.GetReflectType())) 76 } else { 77 *v = reflect.MakeMap(t.GetReflectType()) 78 } 79 } 80 vk, err := t.KeyStringConverter.FromString(path[0]) 81 if err != nil { 82 return err 83 } 84 saveElemV := v.MapIndex(vk) 85 KeyNotExist := false 86 if !saveElemV.IsValid() { 87 saveElemV = reflect.New(t.ElemType.GetReflectType()).Elem() 88 KeyNotExist = true 89 } 90 oElemV := saveElemV 91 err = t.ElemType.SaveByPath(&saveElemV, path[1:], value) 92 if err != nil { 93 return err 94 } 95 if KeyNotExist { 96 v.SetMapIndex(vk, saveElemV) 97 } 98 if oElemV != saveElemV { 99 v.SetMapIndex(vk, saveElemV) 100 } 101 return nil 102 } 103 104 func (t *MapType) DeleteByPath(v *reflect.Value, path Path) (err error) { 105 err = t.Init() 106 if err != nil { 107 return 108 } 109 if len(path) > 1 { 110 vk, err := t.KeyStringConverter.FromString(path[0]) 111 if err != nil { 112 return err 113 } 114 ev := v.MapIndex(vk) 115 et := t.ElemType 116 oEv := ev 117 err = et.DeleteByPath(&ev, path[1:]) 118 if err != nil { 119 return err 120 } 121 if oEv == ev { 122 return nil 123 } 124 v.SetMapIndex(vk, ev) 125 return nil 126 } else if len(path) == 0 { 127 return fmt.Errorf("[MapType.DeleteByPath] delete map with no path.") 128 } 129 //Addressable? 130 vk, err := t.KeyStringConverter.FromString(path[0]) 131 if err != nil { 132 return err 133 } 134 v.SetMapIndex(vk, reflect.Value{}) 135 return nil 136 }