github.com/codingeasygo/util@v0.0.0-20231206062002-1ce2f004b7d9/xmap/map.go (about)

     1  package xmap
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"reflect"
     8  	"strconv"
     9  	"strings"
    10  	"sync"
    11  
    12  	"github.com/codingeasygo/util/attrvalid"
    13  
    14  	"github.com/codingeasygo/util/converter"
    15  )
    16  
    17  // BaseValuable is interface which can be store value
    18  type BaseValuable interface {
    19  	ValueVal(path ...string) (v interface{}, err error)
    20  	//SetValue will set value to path
    21  	SetValue(path string, val interface{}) (err error)
    22  	//Delete will delete value on path
    23  	Delete(path string) (err error)
    24  	//Clear will clear all key on map
    25  	Clear() (err error)
    26  	//Length will return value count
    27  	Length() (l int)
    28  	//Exist will return true if key having
    29  	Exist(path ...string) bool
    30  }
    31  
    32  // RawMapable will get the raw map
    33  type RawMapable interface {
    34  	RawMap() map[string]interface{}
    35  }
    36  
    37  // Valuable is interface which can be store and convert value
    38  type Valuable interface {
    39  	attrvalid.ValueGetter
    40  	attrvalid.Validable
    41  	BaseValuable
    42  	//Raw will return raw base valuable
    43  	Raw() BaseValuable
    44  	//Int will convert path value to int
    45  	Int(path ...string) int
    46  	//IntDef will convert path value to int, return default when not exist or convert fail
    47  	IntDef(def int, path ...string) (v int)
    48  	//IntVal will convert path value to int, return error when not exist or convert fail
    49  	IntVal(path ...string) (int, error)
    50  	//Int64 will convert path value to int64
    51  	Int64(path ...string) int64
    52  	//Int64Def will convert path value to int64, return default when not exist or convert fail
    53  	Int64Def(def int64, path ...string) (v int64)
    54  	//Int64Val will convert path value to int64, return error when not exist or convert fail
    55  	Int64Val(path ...string) (int64, error)
    56  	//Uint64 will convert path value to uint64
    57  	Uint64(path ...string) uint64
    58  	//Uint64Def will convert path value to uint64, return default when not exist or convert fail
    59  	Uint64Def(def uint64, path ...string) (v uint64)
    60  	//Uint64Val will convert path value to uint64, return error when not exist or convert fail
    61  	Uint64Val(path ...string) (uint64, error)
    62  	//Float64 will convert path value to float64
    63  	Float64(path ...string) float64
    64  	//Float64Def will convert path value to float64, return default when not exist or convert fail
    65  	Float64Def(def float64, path ...string) (v float64)
    66  	//Float64Val will convert path value to float64, return error when not exist or convert fail
    67  	Float64Val(path ...string) (float64, error)
    68  	//Str will convert path value to string
    69  	Str(path ...string) string
    70  	//StrDef will convert path value to string, return default when not exist or convert fail
    71  	StrDef(def string, path ...string) (v string)
    72  	//StrVal will convert path value to string, return error when not exist or convert fail
    73  	StrVal(path ...string) (string, error)
    74  	//Map will convert path value to map
    75  	Map(path ...string) M
    76  	//MapDef will convert path value to map, return default when not exist or convert fail
    77  	MapDef(def M, path ...string) (v M)
    78  	//MapVal will convert path value to map, return error when not exist or convert fail
    79  	MapVal(path ...string) (M, error)
    80  	//ArrayDef will convert path value to array, return default when not exist or convert fail
    81  	ArrayDef(def []interface{}, path ...string) []interface{}
    82  	//ArrayVal will convert path value to interface{} array, return error when not exist or convert fail
    83  	ArrayVal(path ...string) ([]interface{}, error)
    84  	//ArrayMapDef will convert path value to map array, return default when not exist or convert fail
    85  	ArrayMapDef(def []M, path ...string) []M
    86  	//ArrayMapVal will convert path value to map array, return error when not exist or convert fail
    87  	ArrayMapVal(path ...string) ([]M, error)
    88  	//ArrayStrDef will convert path value to string array, return default when not exist or convert fail
    89  	ArrayStrDef(def []string, path ...string) []string
    90  	//ArrayStrVal will convert path value to string array, return error when not exist or convert fail
    91  	ArrayStrVal(path ...string) ([]string, error)
    92  	//ArrayIntDef will convert path value to int array, return default when not exist or convert fail
    93  	ArrayIntDef(def []int, path ...string) []int
    94  	//ArrayIntVal will convert path value to int array, return error when not exist or convert fail
    95  	ArrayIntVal(path ...string) ([]int, error)
    96  	//ArrayInt64Def will convert path value to int64 array, return default when not exist or convert fail
    97  	ArrayInt64Def(def []int64, path ...string) []int64
    98  	//ArrayInt64Val will convert path value to int64 array, return error when not exist or convert fail
    99  	ArrayInt64Val(path ...string) ([]int64, error)
   100  	//ArrayUint64Def will convert path value to uint64 array, return default when not exist or convert fail
   101  	ArrayUint64Def(def []uint64, path ...string) []uint64
   102  	//ArrayUint64Val will convert path value to uint64 array, return error when not exist or convert fail
   103  	ArrayUint64Val(path ...string) ([]uint64, error)
   104  	//ArrayFloat64Def will convert path value to float64 array, return default when not exist or convert fail
   105  	ArrayFloat64Def(def []float64, path ...string) []float64
   106  	//ArrayFloat64Val will convert path value to float64 array, return error when not exist or convert fail
   107  	ArrayFloat64Val(path ...string) ([]float64, error)
   108  	//Value will convert path value to interface{}
   109  	Value(path ...string) interface{}
   110  	//ReplaceAll will replace all value by ${path}
   111  	ReplaceAll(in string, usingEnv, keepEmpty bool) (out string)
   112  }
   113  
   114  type impl struct {
   115  	BaseValuable
   116  }
   117  
   118  // Raw will return raw base valuable
   119  func (i *impl) Raw() BaseValuable {
   120  	return i.BaseValuable
   121  }
   122  
   123  // Int will convert path value to int
   124  func (i *impl) Int(path ...string) int {
   125  	return converter.Int(i.Value(path...))
   126  }
   127  
   128  // IntDef will convert path value to int, return default when not exist or convert fail
   129  func (i *impl) IntDef(def int, path ...string) (v int) {
   130  	v, err := i.IntVal(path...)
   131  	if err != nil {
   132  		v = def
   133  	}
   134  	return
   135  }
   136  
   137  // IntVal will convert path value to int, return error when not exist or convert fail
   138  func (i *impl) IntVal(path ...string) (int, error) {
   139  	return converter.IntVal(i.Value(path...))
   140  }
   141  
   142  // Int64 will convert path value to int64
   143  func (i *impl) Int64(path ...string) int64 {
   144  	return converter.Int64(i.Value(path...))
   145  }
   146  
   147  // Int64Def will convert path value to int64, return default when not exist or convert fail
   148  func (i *impl) Int64Def(def int64, path ...string) (v int64) {
   149  	v, err := i.Int64Val(path...)
   150  	if err != nil {
   151  		v = def
   152  	}
   153  	return
   154  }
   155  
   156  // Int64Val will convert path value to int64, return error when not exist or convert fail
   157  func (i *impl) Int64Val(path ...string) (int64, error) {
   158  	return converter.Int64Val(i.Value(path...))
   159  }
   160  
   161  // Uint64 will convert path value to uint64
   162  func (i *impl) Uint64(path ...string) uint64 {
   163  	return converter.Uint64(i.Value(path...))
   164  }
   165  
   166  // Uint64Def will convert path value to uint64, return default when not exist or convert fail
   167  func (i *impl) Uint64Def(def uint64, path ...string) (v uint64) {
   168  	v, err := i.Uint64Val(path...)
   169  	if err != nil {
   170  		v = def
   171  	}
   172  	return
   173  }
   174  
   175  // Uint64Val will convert path value to uint64, return error when not exist or convert fail
   176  func (i *impl) Uint64Val(path ...string) (uint64, error) {
   177  	return converter.Uint64Val(i.Value(path...))
   178  }
   179  
   180  // Float64 will convert path value to float64
   181  func (i *impl) Float64(path ...string) float64 {
   182  	return converter.Float64(i.Value(path...))
   183  }
   184  
   185  // Float64Def will convert path value to float64, return default when not exist or convert fail
   186  func (i *impl) Float64Def(def float64, path ...string) (v float64) {
   187  	v, err := i.Float64Val(path...)
   188  	if err != nil {
   189  		v = def
   190  	}
   191  	return
   192  }
   193  
   194  // Float64Val will convert path value to float64, return error when not exist or convert fail
   195  func (i *impl) Float64Val(path ...string) (float64, error) {
   196  	return converter.Float64Val(i.Value(path...))
   197  }
   198  
   199  // Str will convert path value to string
   200  func (i *impl) Str(path ...string) string {
   201  	return converter.String(i.Value(path...))
   202  }
   203  
   204  // StrDef will convert path value to string, return default when not exist or convert fail
   205  func (i *impl) StrDef(def string, path ...string) (v string) {
   206  	v, err := i.StrVal(path...)
   207  	if err != nil {
   208  		v = def
   209  	}
   210  	return
   211  }
   212  
   213  // StrVal will convert path value to string, return error when not exist or convert fail
   214  func (i *impl) StrVal(path ...string) (string, error) {
   215  	return converter.StringVal(i.Value(path...))
   216  }
   217  
   218  // Map will convert path value to map
   219  func (i *impl) Map(path ...string) M {
   220  	v, _ := MapVal(i.Value(path...))
   221  	return v
   222  }
   223  
   224  // MapDef will convert path value to map, return default when not exist or convert fail
   225  func (i *impl) MapDef(def M, path ...string) (v M) {
   226  	v, err := i.MapVal(path...)
   227  	if err != nil {
   228  		v = def
   229  	}
   230  	return
   231  }
   232  
   233  // MapVal will convert path value to map, return error when not exist or convert fail
   234  func (i *impl) MapVal(path ...string) (M, error) {
   235  	return MapVal(i.Value(path...))
   236  }
   237  
   238  // ArrayDef will convert path value to interface{} array, return default when not exist or convert fail
   239  func (i *impl) ArrayDef(def []interface{}, path ...string) []interface{} {
   240  	vals, err := i.ArrayVal(path...)
   241  	if err != nil {
   242  		vals = def
   243  	}
   244  	return vals
   245  }
   246  
   247  // ArrayVal will convert path value to interface{} array, return error when not exist or convert fail
   248  func (i *impl) ArrayVal(path ...string) ([]interface{}, error) {
   249  	return converter.ArrayVal(i.Value(path...))
   250  }
   251  
   252  // ArrayMapDef will convert path value to interface{} array, return default when not exist or convert fail
   253  func (i *impl) ArrayMapDef(def []M, path ...string) []M {
   254  	vals, err := i.ArrayMapVal(path...)
   255  	if err != nil || len(vals) < 1 {
   256  		vals = def
   257  	}
   258  	return vals
   259  }
   260  
   261  // ArrayMapVal will convert path value to map array, return error when not exist or convert fail
   262  func (i *impl) ArrayMapVal(path ...string) ([]M, error) {
   263  	return ArrayMapVal(i.Value(path...))
   264  }
   265  
   266  // ArrayStrDef will convert path value to string array, return default when not exist or convert fail
   267  func (i *impl) ArrayStrDef(def []string, path ...string) []string {
   268  	vals, err := i.ArrayStrVal(path...)
   269  	if err != nil {
   270  		vals = def
   271  	}
   272  	return vals
   273  }
   274  
   275  // ArrayStrVal will convert path value to string array, return error when not exist or convert fail
   276  func (i *impl) ArrayStrVal(path ...string) ([]string, error) {
   277  	return converter.ArrayStringVal(i.Value(path...))
   278  }
   279  
   280  // ArrayIntDef will convert path value to string array, return default when not exist or convert fail
   281  func (i *impl) ArrayIntDef(def []int, path ...string) []int {
   282  	vals, err := i.ArrayIntVal(path...)
   283  	if err != nil {
   284  		vals = def
   285  	}
   286  	return vals
   287  }
   288  
   289  // ArrayIntVal will convert path value to int array, return error when not exist or convert fail
   290  func (i *impl) ArrayIntVal(path ...string) ([]int, error) {
   291  	return converter.ArrayIntVal(i.Value(path...))
   292  }
   293  
   294  // ArrayInt64Def will convert path value to int64 array, return default when not exist or convert fail
   295  func (i *impl) ArrayInt64Def(def []int64, path ...string) []int64 {
   296  	vals, err := i.ArrayInt64Val(path...)
   297  	if err != nil {
   298  		vals = def
   299  	}
   300  	return vals
   301  }
   302  
   303  // ArrayInt64Val will convert path value to int64 array, return error when not exist or convert fail
   304  func (i *impl) ArrayInt64Val(path ...string) ([]int64, error) {
   305  	return converter.ArrayInt64Val(i.Value(path...))
   306  }
   307  
   308  // ArrayUint64Def will convert path value to uint64 array, return default when not exist or convert fail
   309  func (i *impl) ArrayUint64Def(def []uint64, path ...string) []uint64 {
   310  	vals, err := i.ArrayUint64Val(path...)
   311  	if err != nil {
   312  		vals = def
   313  	}
   314  	return vals
   315  }
   316  
   317  // ArrayUint64Val will convert path value to uint64 array, return error when not exist or convert fail
   318  func (i *impl) ArrayUint64Val(path ...string) ([]uint64, error) {
   319  	return converter.ArrayUint64Val(i.Value(path...))
   320  }
   321  
   322  // ArrayFloat64Def will convert path value to float64 array, return default when not exist or convert fail
   323  func (i *impl) ArrayFloat64Def(def []float64, path ...string) []float64 {
   324  	vals, err := i.ArrayFloat64Val(path...)
   325  	if err != nil {
   326  		vals = def
   327  	}
   328  	return vals
   329  }
   330  
   331  // ArrayFloat64Val will convert path value to float64 array, return error when not exist or convert fail
   332  func (i *impl) ArrayFloat64Val(path ...string) ([]float64, error) {
   333  	return converter.ArrayFloat64Val(i.Value(path...))
   334  }
   335  
   336  // Value will convert path value to interface{}
   337  func (i *impl) Value(path ...string) interface{} {
   338  	v, _ := i.ValueVal(path...)
   339  	return v
   340  }
   341  
   342  // Get is implement for attrvalid.ValueGetter
   343  func (i *impl) Get(path string) (interface{}, error) {
   344  	return i.Value(strings.Split(path, "|")...), nil
   345  }
   346  
   347  // ValidFormat is implement for attrvalid.Validable
   348  func (i *impl) ValidFormat(f string, args ...interface{}) error {
   349  	return attrvalid.ValidAttrFormat(f, i, true, args...)
   350  }
   351  
   352  // ReplaceAll will replace value by ${xx}, which xx is having
   353  func (i *impl) ReplaceAll(in string, usingEnv, keepEmpty bool) (out string) {
   354  	out = ReplaceAll(func(key string) interface{} {
   355  		v, err := i.ValueVal(key)
   356  		if err != nil {
   357  			return nil
   358  		}
   359  		return v
   360  	}, in, usingEnv, keepEmpty)
   361  	return
   362  }
   363  
   364  // MapVal will conventer value to map
   365  func MapVal(v interface{}) (M, error) {
   366  	if mv, ok := v.(M); ok {
   367  		return mv, nil
   368  	} else if mv, ok := v.(map[string]interface{}); ok {
   369  		return M(mv), nil
   370  	} else if rm, ok := v.(RawMapable); ok {
   371  		mv = M(rm.RawMap())
   372  		return mv, nil
   373  	} else if sv, ok := v.(string); ok {
   374  		mv := M{}
   375  		return mv, json.Unmarshal([]byte(sv), &mv)
   376  	} else if sv, ok := v.([]byte); ok {
   377  		mv := M{}
   378  		return mv, json.Unmarshal(sv, &mv)
   379  	} else {
   380  		return nil, fmt.Errorf("incompactable kind(%v)", reflect.ValueOf(v).Kind())
   381  	}
   382  }
   383  
   384  // ArrayMapVal will convert value to map array
   385  func ArrayMapVal(v interface{}) (mvals []M, err error) {
   386  	if v == nil {
   387  		return nil, nil
   388  	}
   389  	var mval M
   390  	if vals, ok := v.([]M); ok {
   391  		return vals, nil
   392  	} else if vals, ok := v.([]interface{}); ok {
   393  		for _, v := range vals {
   394  			mval, err = MapVal(v)
   395  			if err != nil {
   396  				return
   397  			}
   398  			mvals = append(mvals, mval)
   399  		}
   400  		return
   401  	} else if vals, ok := v.([]map[string]interface{}); ok {
   402  		for _, v := range vals {
   403  			mvals = append(mvals, M(v))
   404  		}
   405  	}
   406  	if sv, ok := v.(string); ok {
   407  		err = json.Unmarshal([]byte(sv), &mvals)
   408  		return
   409  	}
   410  	if sv, ok := v.([]byte); ok {
   411  		err = json.Unmarshal(sv, &mvals)
   412  		return
   413  	}
   414  	vals := reflect.ValueOf(v)
   415  	if vals.Kind() != reflect.Slice {
   416  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
   417  		return
   418  	}
   419  	for i := 0; i < vals.Len(); i++ {
   420  		if vals.Index(i).IsZero() {
   421  			mval, err = MapVal(nil)
   422  		} else {
   423  			mval, err = MapVal(vals.Index(i).Interface())
   424  		}
   425  		if err != nil {
   426  			return
   427  		}
   428  		mvals = append(mvals, mval)
   429  	}
   430  	return
   431  }
   432  
   433  // M is type define to map[string]interface{}
   434  type M map[string]interface{}
   435  
   436  // New will create map Valuable
   437  func New() (m M) {
   438  	return M{}
   439  }
   440  
   441  // ValueVal will convert path value to value, return error when not exist or convert fail
   442  func (m M) ValueVal(path ...string) (v interface{}, err error) {
   443  	for _, p := range path {
   444  		v, err = m.pathValue(p)
   445  		if err == nil {
   446  			break
   447  		}
   448  	}
   449  	return
   450  }
   451  
   452  // SetValue will set value to path
   453  func (m M) SetValue(path string, val interface{}) (err error) {
   454  	if len(path) < 1 {
   455  		err = fmt.Errorf("path is empty")
   456  		return
   457  	}
   458  	path = strings.TrimPrefix(path, "/")
   459  	keys := strings.Split(path, "/")
   460  	if len(keys) == 1 {
   461  		m.setValue(keys[0], val)
   462  	} else {
   463  		err = m.setPathValue(path, val)
   464  	}
   465  	return
   466  }
   467  
   468  // Delete will delete value on path
   469  func (m M) Delete(path string) (err error) {
   470  	return m.setPathValue(path, nil)
   471  }
   472  
   473  // Clear will clear all key on map
   474  func (m M) Clear() (err error) {
   475  	for key := range m {
   476  		delete(m, key)
   477  	}
   478  	return
   479  }
   480  
   481  func (m M) setValue(path string, val interface{}) {
   482  	if val == nil {
   483  		delete(m, path)
   484  	} else {
   485  		m[path] = val
   486  	}
   487  }
   488  
   489  func (m M) pathValue(path string) (interface{}, error) {
   490  	if v, ok := m[path]; ok {
   491  		return v, nil
   492  	}
   493  	path = strings.TrimPrefix(path, "/")
   494  	keys := []string{}
   495  	key := strings.Builder{}
   496  	wrapped := false
   497  	for _, c := range path {
   498  		switch c {
   499  		case '\\':
   500  			wrapped = true
   501  		case '/':
   502  			if wrapped {
   503  				key.WriteRune(c)
   504  				wrapped = false
   505  			} else {
   506  				keys = append(keys, key.String())
   507  				key = strings.Builder{}
   508  			}
   509  		default:
   510  			key.WriteRune(c)
   511  		}
   512  	}
   513  	if key.Len() > 0 {
   514  		keys = append(keys, key.String())
   515  		key = strings.Builder{}
   516  	}
   517  	return m.valP(keys...)
   518  }
   519  
   520  func (m M) valP(keys ...string) (interface{}, error) {
   521  	count := len(keys)
   522  	var tv interface{} = m
   523  	for i := 0; i < count; i++ {
   524  		if tv == nil {
   525  			break
   526  		}
   527  		switch reflect.TypeOf(tv).Kind() {
   528  		case reflect.Slice: //if array
   529  			ary, ok := tv.([]interface{}) //check if valid array
   530  			if !ok {
   531  				return nil, fmt.Errorf(
   532  					"invalid array(%v) in path(/%v),expected []interface{}",
   533  					reflect.TypeOf(tv).String(), strings.Join(keys[:i+1], "/"),
   534  				)
   535  			}
   536  			if keys[i] == "@len" { //check if have @len
   537  				return len(ary), nil //return the array length
   538  			}
   539  			idx, err := strconv.Atoi(keys[i]) //get the target index.
   540  			if err != nil {
   541  				return nil, fmt.Errorf(
   542  					"invalid array index(/%v)", strings.Join(keys[:i+1], "/"),
   543  				)
   544  			}
   545  			if idx >= len(ary) || idx < 0 { //check index valid
   546  				return nil, fmt.Errorf(
   547  					"array out of index in path(/%v)", strings.Join(keys[:i+1], "/"),
   548  				)
   549  			}
   550  			tv = ary[idx]
   551  			continue
   552  		case reflect.Map: //if map
   553  			tm, _ := MapVal(tv) //check map covert
   554  			if tm == nil {
   555  				return nil, fmt.Errorf(
   556  					"invalid map in path(/%v)", strings.Join(keys[:i], "/"),
   557  				)
   558  			}
   559  			tv = tm[keys[i]]
   560  			continue
   561  		default: //unknow type
   562  			return nil, fmt.Errorf(
   563  				"invalid type(%v) in path(/%v)",
   564  				reflect.TypeOf(tv).Kind(), strings.Join(keys[:i], "/"),
   565  			)
   566  		}
   567  	}
   568  	if tv == nil { //if valud not found
   569  		return nil, fmt.Errorf(
   570  			"value not found in path(/%v)", strings.Join(keys, "/"),
   571  		)
   572  	}
   573  	return tv, nil
   574  }
   575  
   576  func (m M) setPathValue(path string, val interface{}) error {
   577  	if len(path) < 1 {
   578  		return errors.New("path is empty")
   579  	}
   580  	path = strings.TrimPrefix(path, "/")
   581  	keys := strings.Split(path, "/")
   582  	//
   583  	i := len(keys) - 1
   584  	pv, err := m.valP(keys[:i]...)
   585  	if err != nil {
   586  		return err
   587  	}
   588  	switch reflect.TypeOf(pv).Kind() {
   589  	case reflect.Slice:
   590  		ary, ok := pv.([]interface{}) //check if valid array
   591  		if !ok {
   592  			return fmt.Errorf(
   593  				"invalid array(%v) in path(/%v),expected []interface{}",
   594  				reflect.TypeOf(pv).String(), strings.Join(keys[:i+1], "/"),
   595  			)
   596  		}
   597  		idx, err := strconv.Atoi(keys[i]) //get the target index.
   598  		if err != nil {
   599  			return fmt.Errorf(
   600  				"invalid array index(/%v)", strings.Join(keys[:i+1], "/"),
   601  			)
   602  		}
   603  		if idx >= len(ary) || idx < 0 { //check index valid
   604  			return fmt.Errorf(
   605  				"array out of index in path(/%v)", strings.Join(keys[:i+1], "/"),
   606  			)
   607  		}
   608  		ary[idx] = val
   609  	case reflect.Map:
   610  		tm, _ := MapVal(pv) //check map covert
   611  		if tm == nil {
   612  			return fmt.Errorf(
   613  				"invalid map in path(/%v)", strings.Join(keys[:i], "/"),
   614  			)
   615  		}
   616  		tm.setValue(keys[i], val)
   617  	default: //unknow type
   618  		return fmt.Errorf(
   619  			"not map type(%v) in path(/%v)",
   620  			reflect.TypeOf(pv).Kind(), strings.Join(keys[:i], "/"),
   621  		)
   622  	}
   623  	return nil
   624  }
   625  
   626  // Length will return value count
   627  func (m M) Length() (l int) {
   628  	l = len(m)
   629  	return
   630  }
   631  
   632  // Exist will return true if key having
   633  func (m M) Exist(path ...string) bool {
   634  	_, err := m.ValueVal(path...)
   635  	return err == nil
   636  }
   637  
   638  // Raw will return raw base valuable
   639  func (m M) Raw() BaseValuable {
   640  	return m
   641  }
   642  
   643  // Int will convert path value to int
   644  func (m M) Int(path ...string) int {
   645  	return converter.Int(m.Value(path...))
   646  }
   647  
   648  // IntDef will convert path value to int, return default when not exist or convert fail
   649  func (m M) IntDef(def int, path ...string) (v int) {
   650  	v, err := m.IntVal(path...)
   651  	if err != nil {
   652  		v = def
   653  	}
   654  	return
   655  }
   656  
   657  // IntVal will convert path value to int, return error when not exist or convert fail
   658  func (m M) IntVal(path ...string) (int, error) {
   659  	return converter.IntVal(m.Value(path...))
   660  }
   661  
   662  // Int64 will convert path value to int64
   663  func (m M) Int64(path ...string) int64 {
   664  	return converter.Int64(m.Value(path...))
   665  }
   666  
   667  // Int64Def will convert path value to int64, return default when not exist or convert fail
   668  func (m M) Int64Def(def int64, path ...string) (v int64) {
   669  	v, err := m.Int64Val(path...)
   670  	if err != nil {
   671  		v = def
   672  	}
   673  	return
   674  }
   675  
   676  // Int64Val will convert path value to int64, return error when not exist or convert fail
   677  func (m M) Int64Val(path ...string) (int64, error) {
   678  	return converter.Int64Val(m.Value(path...))
   679  }
   680  
   681  // Uint64 will convert path value to uint64
   682  func (m M) Uint64(path ...string) uint64 {
   683  	return converter.Uint64(m.Value(path...))
   684  }
   685  
   686  // Uint64Def will convert path value to uint64, return default when not exist or convert fail
   687  func (m M) Uint64Def(def uint64, path ...string) (v uint64) {
   688  	v, err := m.Uint64Val(path...)
   689  	if err != nil {
   690  		v = def
   691  	}
   692  	return
   693  }
   694  
   695  // Uint64Val will convert path value to uint64, return error when not exist or convert fail
   696  func (m M) Uint64Val(path ...string) (uint64, error) {
   697  	return converter.Uint64Val(m.Value(path...))
   698  }
   699  
   700  // Float64 will convert path value to float64
   701  func (m M) Float64(path ...string) float64 {
   702  	return converter.Float64(m.Value(path...))
   703  }
   704  
   705  // Float64Def will convert path value to float64, return default when not exist or convert fail
   706  func (m M) Float64Def(def float64, path ...string) (v float64) {
   707  	v, err := m.Float64Val(path...)
   708  	if err != nil {
   709  		v = def
   710  	}
   711  	return
   712  }
   713  
   714  // Float64Val will convert path value to float64, return error when not exist or convert fail
   715  func (m M) Float64Val(path ...string) (float64, error) {
   716  	return converter.Float64Val(m.Value(path...))
   717  }
   718  
   719  // Str will convert path value to string
   720  func (m M) Str(path ...string) string {
   721  	return converter.String(m.Value(path...))
   722  }
   723  
   724  // StrDef will convert path value to string, return default when not exist or convert fail
   725  func (m M) StrDef(def string, path ...string) (v string) {
   726  	v, err := m.StrVal(path...)
   727  	if err != nil {
   728  		v = def
   729  	}
   730  	return
   731  }
   732  
   733  // StrVal will convert path value to string, return error when not exist or convert fail
   734  func (m M) StrVal(path ...string) (string, error) {
   735  	return converter.StringVal(m.Value(path...))
   736  }
   737  
   738  // Map will convert path value to map
   739  func (m M) Map(path ...string) M {
   740  	v, _ := MapVal(m.Value(path...))
   741  	return v
   742  }
   743  
   744  // MapDef will convert path value to map, return default when not exist or convert fail
   745  func (m M) MapDef(def M, path ...string) (v M) {
   746  	v, err := m.MapVal(path...)
   747  	if err != nil {
   748  		v = def
   749  	}
   750  	return
   751  }
   752  
   753  // MapVal will convert path value to map, return error when not exist or convert fail
   754  func (m M) MapVal(path ...string) (M, error) {
   755  	return MapVal(m.Value(path...))
   756  }
   757  
   758  // ArrayDef will convert path value to interface{} array, return default when not exist or convert fail
   759  func (m M) ArrayDef(def []interface{}, path ...string) []interface{} {
   760  	vals, err := m.ArrayVal(path...)
   761  	if err != nil {
   762  		vals = def
   763  	}
   764  	return vals
   765  }
   766  
   767  // ArrayVal will convert path value to interface{} array, return error when not exist or convert fail
   768  func (m M) ArrayVal(path ...string) ([]interface{}, error) {
   769  	return converter.ArrayVal(m.Value(path...))
   770  }
   771  
   772  // ArrayMapDef will convert path value to interface{} array, return default when not exist or convert fail
   773  func (m M) ArrayMapDef(def []M, path ...string) []M {
   774  	vals, err := m.ArrayMapVal(path...)
   775  	if err != nil || len(vals) < 1 {
   776  		vals = def
   777  	}
   778  	return vals
   779  }
   780  
   781  // ArrayMapVal will convert path value to map array, return error when not exist or convert fail
   782  func (m M) ArrayMapVal(path ...string) ([]M, error) {
   783  	return ArrayMapVal(m.Value(path...))
   784  }
   785  
   786  // ArrayStrDef will convert path value to string array, return default when not exist or convert fail
   787  func (m M) ArrayStrDef(def []string, path ...string) []string {
   788  	vals, err := m.ArrayStrVal(path...)
   789  	if err != nil {
   790  		vals = def
   791  	}
   792  	return vals
   793  }
   794  
   795  // ArrayStrVal will convert path value to string array, return error when not exist or convert fail
   796  func (m M) ArrayStrVal(path ...string) ([]string, error) {
   797  	return converter.ArrayStringVal(m.Value(path...))
   798  }
   799  
   800  // ArrayIntDef will convert path value to string array, return default when not exist or convert fail
   801  func (m M) ArrayIntDef(def []int, path ...string) []int {
   802  	vals, err := m.ArrayIntVal(path...)
   803  	if err != nil {
   804  		vals = def
   805  	}
   806  	return vals
   807  }
   808  
   809  // ArrayIntVal will convert path value to int array, return error when not exist or convert fail
   810  func (m M) ArrayIntVal(path ...string) ([]int, error) {
   811  	return converter.ArrayIntVal(m.Value(path...))
   812  }
   813  
   814  // ArrayInt64Def will convert path value to int64 array, return default when not exist or convert fail
   815  func (m M) ArrayInt64Def(def []int64, path ...string) []int64 {
   816  	vals, err := m.ArrayInt64Val(path...)
   817  	if err != nil {
   818  		vals = def
   819  	}
   820  	return vals
   821  }
   822  
   823  // ArrayInt64Val will convert path value to int64 array, return error when not exist or convert fail
   824  func (m M) ArrayInt64Val(path ...string) ([]int64, error) {
   825  	return converter.ArrayInt64Val(m.Value(path...))
   826  }
   827  
   828  // ArrayUint64Def will convert path value to uint64 array, return default when not exist or convert fail
   829  func (m M) ArrayUint64Def(def []uint64, path ...string) []uint64 {
   830  	vals, err := m.ArrayUint64Val(path...)
   831  	if err != nil {
   832  		vals = def
   833  	}
   834  	return vals
   835  }
   836  
   837  // ArrayUint64Val will convert path value to uint64 array, return error when not exist or convert fail
   838  func (m M) ArrayUint64Val(path ...string) ([]uint64, error) {
   839  	return converter.ArrayUint64Val(m.Value(path...))
   840  }
   841  
   842  // ArrayFloat64Def will convert path value to float64 array, return default when not exist or convert fail
   843  func (m M) ArrayFloat64Def(def []float64, path ...string) []float64 {
   844  	vals, err := m.ArrayFloat64Val(path...)
   845  	if err != nil {
   846  		vals = def
   847  	}
   848  	return vals
   849  }
   850  
   851  // ArrayFloat64Val will convert path value to float64 array, return error when not exist or convert fail
   852  func (m M) ArrayFloat64Val(path ...string) ([]float64, error) {
   853  	return converter.ArrayFloat64Val(m.Value(path...))
   854  }
   855  
   856  // Value will convert path value to interface{}
   857  func (m M) Value(path ...string) interface{} {
   858  	v, _ := m.ValueVal(path...)
   859  	return v
   860  }
   861  
   862  // Get is implement for attrvalid.ValueGetter
   863  func (m M) Get(path string) (interface{}, error) {
   864  	return m.Value(strings.Split(path, "|")...), nil
   865  }
   866  
   867  // ValidFormat is implement for attrvalid.Validable
   868  func (m M) ValidFormat(f string, args ...interface{}) error {
   869  	return attrvalid.ValidAttrFormat(f, m, true, args...)
   870  }
   871  
   872  // ReplaceAll will replace input string by ${xx}, which xx is in values,
   873  // if usingEnv is true, xx will check use env when vals is not having xx,
   874  // if usingEmpty is true, xx will check use empty string when vals is not having xx and env is not exist
   875  func (m M) ReplaceAll(in string, usingEnv, usingEmpty bool) (out string) {
   876  	out = ReplaceAll(func(key string) interface{} {
   877  		v, err := m.ValueVal(key)
   878  		if err != nil {
   879  			return nil
   880  		}
   881  		return v
   882  	}, in, usingEnv, usingEmpty)
   883  	return
   884  }
   885  
   886  func ValueEqual(a, b interface{}) bool {
   887  	if a == nil || b == nil {
   888  		return a == nil && b == nil
   889  	}
   890  	resultValue := reflect.ValueOf(a)
   891  	if !resultValue.CanConvert(reflect.TypeOf(b)) {
   892  		return false
   893  	}
   894  	targetValue := resultValue.Convert(reflect.TypeOf(b)).Interface()
   895  	return reflect.DeepEqual(targetValue, b)
   896  }
   897  
   898  func (m M) ValueEqual(key string, value interface{}) bool {
   899  	return ValueEqual(m.Value(key), value)
   900  }
   901  
   902  // SafeM is safe map
   903  type SafeM struct {
   904  	Valuable
   905  	raw    BaseValuable
   906  	locker sync.RWMutex
   907  }
   908  
   909  // NewSafe will return new safe map
   910  func NewSafe() (m *SafeM) {
   911  	m = &SafeM{
   912  		raw:    M{},
   913  		locker: sync.RWMutex{},
   914  	}
   915  	m.Valuable = &impl{BaseValuable: m}
   916  	return
   917  }
   918  
   919  func NewSafeByBase(base BaseValuable) (m *SafeM) {
   920  	m = &SafeM{
   921  		raw:    base,
   922  		locker: sync.RWMutex{},
   923  	}
   924  	m.Valuable = &impl{BaseValuable: m}
   925  	return
   926  }
   927  
   928  func (s *SafeM) Lock() {
   929  	s.locker.Lock()
   930  }
   931  
   932  func (s *SafeM) Unlock() {
   933  	s.locker.Unlock()
   934  }
   935  
   936  func (s *SafeM) RLock() {
   937  	s.locker.RLock()
   938  }
   939  
   940  func (s *SafeM) RUnlock() {
   941  	s.locker.RUnlock()
   942  }
   943  
   944  // Raw will return raw base
   945  func (s *SafeM) Raw() BaseValuable {
   946  	return s.raw
   947  }
   948  
   949  // ValueVal will convert path value to value, return error when not exist or convert fail
   950  func (s *SafeM) ValueVal(path ...string) (v interface{}, err error) {
   951  	s.locker.RLock()
   952  	defer s.locker.RUnlock()
   953  	return s.raw.ValueVal(path...)
   954  }
   955  
   956  // SetValue will set value to path
   957  func (s *SafeM) SetValue(path string, val interface{}) (err error) {
   958  	s.locker.Lock()
   959  	defer s.locker.Unlock()
   960  	return s.raw.SetValue(path, val)
   961  }
   962  
   963  // Delete will delete value on path
   964  func (s *SafeM) Delete(path string) (err error) {
   965  	s.locker.Lock()
   966  	defer s.locker.Unlock()
   967  	return s.raw.SetValue(path, nil)
   968  }
   969  
   970  // Clear will clear all key
   971  func (s *SafeM) Clear() (err error) {
   972  	s.locker.Lock()
   973  	defer s.locker.Unlock()
   974  	return s.raw.Clear()
   975  }
   976  
   977  // Length will return value count
   978  func (s *SafeM) Length() (l int) {
   979  	s.locker.RLock()
   980  	defer s.locker.RUnlock()
   981  	return s.raw.Length()
   982  }
   983  
   984  // Exist will return true if key having
   985  func (s *SafeM) Exist(path ...string) bool {
   986  	s.locker.RLock()
   987  	defer s.locker.RUnlock()
   988  	return s.raw.Exist(path...)
   989  }
   990  
   991  // ReplaceAll will replace input string by ${xx}, which xx is in values,
   992  // if usingEnv is true, xx will check use env when vals is not having xx,
   993  // if usingEmpty is true, xx will check use empty string when vals is not having xx and env is not exist
   994  func (s *SafeM) ReplaceAll(in string, usingEnv, usingEmpty bool) (out string) {
   995  	out = ReplaceAll(func(key string) interface{} {
   996  		v, err := s.ValueVal(key)
   997  		if err != nil {
   998  			return nil
   999  		}
  1000  		return v
  1001  	}, in, usingEnv, usingEmpty)
  1002  	return
  1003  }
  1004  
  1005  // func (m Map) ToS(dest interface{}) {
  1006  // 	M2S(m, dest)
  1007  // }
  1008  
  1009  // func NewMap(f string) (Map, error) {
  1010  // 	bys, err := ioutil.ReadFile(f)
  1011  // 	if err != nil {
  1012  // 		return nil, err
  1013  // 	}
  1014  // 	var kvs Map = Map{}
  1015  // 	err = json.Unmarshal(bys, &kvs)
  1016  // 	return kvs, err
  1017  // }
  1018  
  1019  // func NewMaps(f string) ([]Map, error) {
  1020  // 	bys, err := ioutil.ReadFile(f)
  1021  // 	if err != nil {
  1022  // 		return nil, err
  1023  // 	}
  1024  // 	var kvs []Map = []Map{}
  1025  // 	err = json.Unmarshal(bys, &kvs)
  1026  // 	return kvs, err
  1027  // }
  1028  
  1029  type MSorter struct {
  1030  	All  []M
  1031  	Path []string
  1032  	Type int //0 is int,1 is float,2 is string
  1033  	Desc bool
  1034  }
  1035  
  1036  func NewMSorter(all []M, vtype int, desc bool, path ...string) *MSorter {
  1037  	return &MSorter{
  1038  		All:  all,
  1039  		Path: path,
  1040  		Type: vtype,
  1041  		Desc: desc,
  1042  	}
  1043  }
  1044  func (m *MSorter) Len() int {
  1045  	return len(m.All)
  1046  }
  1047  
  1048  func (m *MSorter) Less(i, j int) bool {
  1049  	switch m.Type {
  1050  	case 0:
  1051  		if m.Desc {
  1052  			return m.All[i].Int(m.Path...) > m.All[j].Int(m.Path...)
  1053  		}
  1054  		return m.All[i].Int(m.Path...) < m.All[j].Int(m.Path...)
  1055  	case 1:
  1056  		if m.Desc {
  1057  			return m.All[i].Float64(m.Path...) > m.All[j].Float64(m.Path...)
  1058  		}
  1059  		return m.All[i].Float64(m.Path...) < m.All[j].Float64(m.Path...)
  1060  	default:
  1061  		if m.Desc {
  1062  			return m.All[i].Str(m.Path...) > m.All[j].Str(m.Path...)
  1063  		}
  1064  		return m.All[i].Str(m.Path...) < m.All[j].Str(m.Path...)
  1065  	}
  1066  }
  1067  func (m *MSorter) Swap(i, j int) {
  1068  	m.All[i], m.All[j] = m.All[j], m.All[i]
  1069  }
  1070  
  1071  type ValuableSorter struct {
  1072  	All  []Valuable
  1073  	Path []string
  1074  	Type int //0 is int,1 is float,2 is string
  1075  	Desc bool
  1076  }
  1077  
  1078  func NewValuableSorter(all []Valuable, vtype int, desc bool, path ...string) *ValuableSorter {
  1079  	return &ValuableSorter{
  1080  		All:  all,
  1081  		Path: path,
  1082  		Type: vtype,
  1083  		Desc: desc,
  1084  	}
  1085  }
  1086  func (v *ValuableSorter) Len() int {
  1087  	return len(v.All)
  1088  }
  1089  
  1090  func (v *ValuableSorter) Less(i, j int) bool {
  1091  	switch v.Type {
  1092  	case 0:
  1093  		if v.Desc {
  1094  			return v.All[i].Int(v.Path...) > v.All[j].Int(v.Path...)
  1095  		}
  1096  		return v.All[i].Int(v.Path...) < v.All[j].Int(v.Path...)
  1097  	case 1:
  1098  		if v.Desc {
  1099  			return v.All[i].Float64(v.Path...) > v.All[j].Float64(v.Path...)
  1100  		}
  1101  		return v.All[i].Float64(v.Path...) < v.All[j].Float64(v.Path...)
  1102  	default:
  1103  		if v.Desc {
  1104  			return v.All[i].Str(v.Path...) > v.All[j].Str(v.Path...)
  1105  		}
  1106  		return v.All[i].Str(v.Path...) < v.All[j].Str(v.Path...)
  1107  	}
  1108  }
  1109  func (v *ValuableSorter) Swap(i, j int) {
  1110  	v.All[i], v.All[j] = v.All[j], v.All[i]
  1111  }
  1112  
  1113  // func Maps2Map(ms []Map, path ...string) Map {
  1114  // 	var res = Map{}
  1115  // 	for _, m := range ms {
  1116  // 		res[m.StrValP(path)] = m
  1117  // 	}
  1118  // 	return res
  1119  // }