Spaces:
Paused
Paused
| package mapx | |
| import ( | |
| "encoding/json" | |
| "fmt" | |
| "net/url" | |
| "reflect" | |
| "sort" | |
| "strconv" | |
| "strings" | |
| "time" | |
| ) | |
| const dot = "." | |
| type Mapx map[string]interface{} | |
| func (m *Mapx) IsNil(key string) bool { | |
| return m.Get(key) == nil | |
| } | |
| func (m *Mapx) GetString(key string) string { | |
| return fmt.Sprintf("%v", m.Get(key)) | |
| } | |
| func (m *Mapx) GetTime(key string) time.Time { | |
| t, _ := time.ParseInLocation(time.RFC3339, m.GetString(key), time.Local) | |
| return t | |
| } | |
| func (m *Mapx) GetInt(key string) int64 { | |
| i, _ := strconv.ParseInt(m.GetString(key), 10, 64) | |
| return i | |
| } | |
| func (m *Mapx) GetFloat(key string) float64 { | |
| f, _ := strconv.ParseFloat(fmt.Sprintf("%v", m.Get(key)), 64) | |
| return f | |
| } | |
| func (m *Mapx) GetBool(key string) bool { | |
| b, _ := strconv.ParseBool(fmt.Sprintf("%v", m.Get(key))) | |
| return b | |
| } | |
| func (m *Mapx) GetMapx(key string) *Mapx { | |
| v, _ := m.Get(key).(map[string]interface{}) | |
| return (*Mapx)(&v) | |
| } | |
| func (m *Mapx) GetSlice(key string, fn func(item *Mapx, index int) bool) { | |
| value := reflect.ValueOf(m.Get(key)) | |
| if value.Kind() != reflect.Slice { | |
| return | |
| } | |
| for i := 0; i < value.Len(); i++ { | |
| item := value.Index(i) | |
| if item.Kind() != reflect.Invalid { | |
| v, _ := item.Interface().(map[string]interface{}) | |
| if !fn((*Mapx)(&v), i) { | |
| break | |
| } | |
| } | |
| } | |
| } | |
| func (m *Mapx) Set(key string, val any) *Mapx { | |
| (*m)[key] = val | |
| return m | |
| } | |
| func (m *Mapx) Get(key string) any { | |
| if m == nil { | |
| return nil | |
| } | |
| var v any = map[string]interface{}(*m) | |
| keys := strings.Split(key, dot) | |
| for i := 0; i < len(keys); i++ { | |
| if v == nil { | |
| return nil | |
| } | |
| k := keys[i] | |
| switch kind := reflect.TypeOf(v).Kind(); kind { | |
| case reflect.Map: | |
| _v := reflect.ValueOf(v).MapIndex(reflect.ValueOf(k)) | |
| if _v.Kind() != reflect.Invalid { | |
| v = _v.Interface() | |
| } else { | |
| v = nil | |
| } | |
| case reflect.Slice: | |
| if len(k) > 2 && k[0] == '[' && k[len(k)-1] == ']' { | |
| idx, err := strconv.Atoi(k[1 : len(k)-1]) | |
| if err != nil { | |
| return nil | |
| } | |
| _v := reflect.ValueOf(v).Index(idx) | |
| if _v.Kind() != reflect.Invalid { | |
| v = _v.Interface() | |
| } else { | |
| v = nil | |
| } | |
| } | |
| case reflect.Struct: | |
| _v := reflect.ValueOf(v).FieldByName(k) | |
| if _v.Kind() != reflect.Invalid { | |
| v = _v.Interface() | |
| } else { | |
| v = nil | |
| } | |
| case reflect.Ptr: | |
| v = reflect.ValueOf(v).Elem().Interface() | |
| i-- | |
| case reflect.Invalid: | |
| return nil | |
| default: | |
| return nil | |
| } | |
| } | |
| return v | |
| } | |
| func (m *Mapx) Remove(key string) { | |
| delete(*m, key) | |
| } | |
| func (m *Mapx) Json() string { | |
| b, _ := json.Marshal(&m) | |
| return string(b) | |
| } | |
| func UnmarshalJSON(data []byte) (m *Mapx) { | |
| _ = json.Unmarshal(data, &m) | |
| return | |
| } | |
| // EncodeAliPaySignParams ("bar=baz&foo=quux") sorted by key. | |
| func (m *Mapx) EncodeAliPaySignParams() string { | |
| if m == nil { | |
| return "" | |
| } | |
| var ( | |
| buf strings.Builder | |
| keyList []string | |
| ) | |
| for k := range *m { | |
| keyList = append(keyList, k) | |
| } | |
| sort.Strings(keyList) | |
| for _, k := range keyList { | |
| if v := m.GetString(k); v != "" { | |
| buf.WriteString(k) | |
| buf.WriteByte('=') | |
| buf.WriteString(v) | |
| buf.WriteByte('&') | |
| } | |
| } | |
| if buf.Len() <= 0 { | |
| return "" | |
| } | |
| return buf.String()[:buf.Len()-1] | |
| } | |
| // EncodeURLParams ("bar=baz&foo=quux") sorted by key. | |
| func (m *Mapx) EncodeURLParams() string { | |
| if m == nil { | |
| return "" | |
| } | |
| var ( | |
| buf strings.Builder | |
| keys []string | |
| ) | |
| for k := range *m { | |
| keys = append(keys, k) | |
| } | |
| sort.Strings(keys) | |
| for _, k := range keys { | |
| if v := m.GetString(k); v != "" { | |
| buf.WriteString(url.QueryEscape(k)) | |
| buf.WriteByte('=') | |
| buf.WriteString(url.QueryEscape(v)) | |
| buf.WriteByte('&') | |
| } | |
| } | |
| if buf.Len() <= 0 { | |
| return "" | |
| } | |
| return buf.String()[:buf.Len()-1] | |
| } | |
| func (m *Mapx) ValidateEmpty(keys ...string) error { | |
| var emptyKeys []string | |
| for _, k := range keys { | |
| if m.IsNil(k) { | |
| emptyKeys = append(emptyKeys, k) | |
| } | |
| } | |
| if len(emptyKeys) > 0 { | |
| return fmt.Errorf("[miss param error], %v", strings.Join(emptyKeys, ", ")) | |
| } | |
| return nil | |
| } | |