github.com/codingeasygo/util@v0.0.0-20231206062002-1ce2f004b7d9/xmap/wrap.go (about) 1 package xmap 2 3 import ( 4 "fmt" 5 "reflect" 6 "sync" 7 ) 8 9 // Wrap will wrap raw map to safe 10 func Wrap(v interface{}) (m M) { 11 if v == nil { 12 panic("v is nil") 13 } 14 if mval, ok := v.(M); ok { 15 m = mval 16 } else if mval, ok := v.(map[string]interface{}); ok { 17 m = M(mval) 18 } else if rm, ok := v.(RawMapable); ok { 19 m = M(rm.RawMap()) 20 } else { 21 panic(fmt.Sprintf("not supported type %v", reflect.TypeOf(v))) 22 } 23 return 24 } 25 26 // WrapArray will wrap base values to array 27 func WrapArray(v interface{}) (ms []M) { 28 if v == nil { 29 return nil 30 } 31 vals := reflect.ValueOf(v) 32 if vals.Kind() != reflect.Slice { 33 panic(fmt.Errorf("incompactable kind(%v)", vals.Kind())) 34 } 35 for i := 0; i < vals.Len(); i++ { 36 if vals.Index(i).IsZero() { 37 ms = append(ms, nil) 38 } else { 39 ms = append(ms, Wrap(vals.Index(i).Interface())) 40 } 41 } 42 return 43 } 44 45 // Parse will parse val to map 46 func Parse(v interface{}) (m Valuable, err error) { 47 if v == nil { 48 err = fmt.Errorf("v is nil") 49 return 50 } 51 m, err = MapVal(v) 52 if err == nil { 53 return 54 } 55 err = nil 56 if val, ok := v.(Valuable); ok { 57 m = val 58 } else if base, ok := v.(BaseValuable); ok { 59 m = &impl{BaseValuable: base} 60 } else { 61 err = fmt.Errorf("not supported type %v", reflect.TypeOf(v)) 62 } 63 return 64 } 65 66 // ParseArray will parse value to map array 67 func ParseArray(v interface{}) (ms []Valuable, err error) { 68 if v == nil { 69 return 70 } 71 raws, err := ArrayMapVal(v) 72 if err == nil { 73 for _, raw := range raws { 74 ms = append(ms, raw) 75 } 76 return 77 } 78 err = nil 79 vals := reflect.ValueOf(v) 80 if vals.Kind() != reflect.Slice { 81 err = fmt.Errorf("incompactable kind(%v)", vals.Kind()) 82 return 83 } 84 var m Valuable 85 for i := 0; i < vals.Len(); i++ { 86 if vals.Index(i).IsZero() { 87 m = nil 88 } else { 89 m, err = Parse(vals.Index(i).Interface()) 90 } 91 if err != nil { 92 break 93 } 94 ms = append(ms, m) 95 } 96 return 97 } 98 99 // WrapSafe will wrap raw map to safe 100 func WrapSafe(raw interface{}) (m *SafeM) { 101 if raw == nil { 102 panic("raw is nil") 103 } 104 var b BaseValuable 105 if m, ok := raw.(M); ok { 106 b = m 107 } else if base, ok := raw.(BaseValuable); ok { 108 b = base 109 } else if mval, ok := raw.(map[string]interface{}); ok { 110 b = M(mval) 111 } else if rm, ok := raw.(RawMapable); ok { 112 b = M(rm.RawMap()) 113 } else { 114 panic("not supported type " + reflect.TypeOf(raw).Kind().String()) 115 } 116 m = &SafeM{ 117 raw: b, 118 locker: sync.RWMutex{}, 119 } 120 m.Valuable = &impl{BaseValuable: m} 121 return 122 } 123 124 // ParseSafe will parse val to map 125 func ParseSafe(v interface{}) (m Valuable, err error) { 126 if v == nil { 127 err = fmt.Errorf("v is nil") 128 return 129 } 130 m, err = MapVal(v) 131 if err == nil { 132 m = WrapSafe(m) 133 return 134 } 135 err = nil 136 if base, ok := v.(BaseValuable); ok { 137 m = WrapSafe(base) 138 } else { 139 err = fmt.Errorf("not supported type %v", reflect.TypeOf(v)) 140 } 141 return 142 } 143 144 // WrapSafeArray will wrap raw map to safe 145 func WrapSafeArray(v interface{}) (ms []Valuable) { 146 if v == nil { 147 return nil 148 } 149 vals := reflect.ValueOf(v) 150 if vals.Kind() != reflect.Slice { 151 panic(fmt.Errorf("incompactable kind(%v)", vals.Kind())) 152 } 153 for i := 0; i < vals.Len(); i++ { 154 if vals.Index(i).IsZero() { 155 ms = append(ms, nil) 156 } else { 157 ms = append(ms, WrapSafe(vals.Index(i).Interface())) 158 } 159 } 160 return 161 } 162 163 // ParseSafeArray will parse value to map array 164 func ParseSafeArray(v interface{}) (ms []Valuable, err error) { 165 if v == nil { 166 return 167 } 168 raws, err := ArrayMapVal(v) 169 if err == nil { 170 for _, raw := range raws { 171 ms = append(ms, WrapSafe(raw)) 172 } 173 return 174 } 175 err = nil 176 vals := reflect.ValueOf(v) 177 if vals.Kind() != reflect.Slice { 178 err = fmt.Errorf("incompactable kind(%v)", vals.Kind()) 179 return 180 } 181 var m Valuable 182 for i := 0; i < vals.Len(); i++ { 183 if vals.Index(i).IsZero() { 184 m = nil 185 } else { 186 m, err = ParseSafe(vals.Index(i).Interface()) 187 } 188 if err != nil { 189 break 190 } 191 ms = append(ms, m) 192 } 193 return 194 }