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

     1  package converter
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/json"
     6  	"encoding/xml"
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"reflect"
    11  	"strconv"
    12  	"strings"
    13  	"time"
    14  )
    15  
    16  var ErrNil = fmt.Errorf("nil value")
    17  
    18  func valueConvert(v interface{}, targetType reflect.Type, defaultRet interface{}, parse func(string) (interface{}, error)) (result interface{}, err error) {
    19  	targetValue := reflect.ValueOf(v)
    20  	if !targetValue.IsValid() {
    21  		return defaultRet, ErrNil
    22  	}
    23  	if timeValue, ok := v.(time.Time); ok {
    24  		if targetValue.IsZero() {
    25  			targetValue = reflect.ValueOf(int64(0))
    26  		} else {
    27  			targetValue = reflect.ValueOf(timeValue.Local().UnixNano() / 1e6)
    28  		}
    29  	}
    30  	if targetValue.CanConvert(reflect.TypeOf(time.Time{})) {
    31  		if targetValue.IsZero() {
    32  			targetValue = reflect.ValueOf(int64(0))
    33  		} else {
    34  			targetValue = reflect.ValueOf(targetValue.Convert(reflect.TypeOf(time.Time{})).Interface().(time.Time).Local().UnixNano() / 1e6)
    35  		}
    36  	}
    37  	if targetValue.Kind() == reflect.String {
    38  		result, err = parse(targetValue.String())
    39  		if err != nil {
    40  			return defaultRet, err
    41  		}
    42  		targetValue = reflect.ValueOf(result)
    43  	}
    44  	if targetValue.CanConvert(targetType) {
    45  		return targetValue.Convert(targetType).Interface(), nil
    46  	}
    47  	if targetValue.Kind() == reflect.Ptr {
    48  		targetValue = reflect.Indirect(targetValue)
    49  		if !targetValue.IsValid() {
    50  			return defaultRet, ErrNil
    51  		}
    52  		result, err = valueConvert(targetValue.Interface(), targetType, defaultRet, parse)
    53  		return
    54  	}
    55  	if valuer, ok := v.(driver.Valuer); ok {
    56  		driverValue, xerr := valuer.Value()
    57  		if xerr != nil {
    58  			err = xerr
    59  			return
    60  		}
    61  		result, err = valueConvert(driverValue, targetType, defaultRet, parse)
    62  		return
    63  	}
    64  	return defaultRet, fmt.Errorf("incompactable kind(%v)", targetValue.Kind())
    65  }
    66  
    67  func Int(v interface{}) (val int) {
    68  	val, _ = IntVal(v)
    69  	return
    70  }
    71  
    72  var _intType = reflect.TypeOf(0)
    73  
    74  func IntVal(v interface{}) (int, error) {
    75  	ret, err := valueConvert(v, _intType, 0, func(s string) (interface{}, error) {
    76  		return strconv.ParseInt(strings.TrimSpace(s), 10, 64)
    77  	})
    78  	if err != nil {
    79  		return 0, err
    80  	}
    81  	return ret.(int), nil
    82  }
    83  
    84  func Int64(v interface{}) int64 {
    85  	val, _ := Int64Val(v)
    86  	return val
    87  }
    88  
    89  var _int64Type = reflect.TypeOf(int64(0))
    90  
    91  func Int64Val(v interface{}) (int64, error) {
    92  	ret, err := valueConvert(v, _int64Type, 0, func(s string) (interface{}, error) {
    93  		return strconv.ParseInt(strings.TrimSpace(s), 10, 64)
    94  	})
    95  	if err != nil {
    96  		return 0, err
    97  	}
    98  	return ret.(int64), nil
    99  }
   100  
   101  func Uint64(v interface{}) uint64 {
   102  	val, _ := Uint64Val(v)
   103  	return val
   104  }
   105  
   106  var _uint64Type = reflect.TypeOf(uint64(0))
   107  
   108  func Uint64Val(v interface{}) (uint64, error) {
   109  	ret, err := valueConvert(v, _uint64Type, 0, func(s string) (interface{}, error) {
   110  		return strconv.ParseInt(strings.TrimSpace(s), 10, 64)
   111  	})
   112  	if err != nil {
   113  		return 0, err
   114  	}
   115  	return ret.(uint64), nil
   116  }
   117  
   118  func Float64(v interface{}) float64 {
   119  	val, _ := Float64Val(v)
   120  	return val
   121  }
   122  
   123  var _float64Type = reflect.TypeOf(float64(0))
   124  
   125  func Float64Val(v interface{}) (float64, error) {
   126  	ret, err := valueConvert(v, _float64Type, 0, func(s string) (interface{}, error) {
   127  		return strconv.ParseFloat(strings.TrimSpace(s), 64)
   128  	})
   129  	if err != nil {
   130  		return 0, err
   131  	}
   132  	return ret.(float64), nil
   133  }
   134  
   135  func String(v interface{}) string {
   136  	val, _ := StringVal(v)
   137  	return val
   138  }
   139  
   140  func StringVal(v interface{}) (res string, err error) {
   141  	if v == nil {
   142  		return "", ErrNil
   143  	}
   144  	switch v := v.(type) {
   145  	case string:
   146  		return v, nil
   147  	case *string:
   148  		return *v, nil
   149  	case []byte:
   150  		return string(v), nil
   151  	case *[]byte:
   152  		return string(*v), nil
   153  	default:
   154  		return fmt.Sprintf("%v", v), nil
   155  	}
   156  }
   157  
   158  //ArrayVal will convert value to array, if v is string will split it by comma, if v is slice will loop element to array, other will error
   159  func ArrayVal(v interface{}) ([]interface{}, error) {
   160  	return ArrayValAll(v, false)
   161  }
   162  
   163  //ArrayValAll will convert all value to array, if v is string will split it by comma, if v is slice will loop element to array, other will return []interface{}{v} when all is true
   164  func ArrayValAll(v interface{}, all bool) ([]interface{}, error) {
   165  	if v == nil {
   166  		return nil, ErrNil
   167  	}
   168  	if vals, ok := v.([]interface{}); ok {
   169  		return vals, nil
   170  	}
   171  	if sval, ok := v.(string); ok {
   172  		vals := []interface{}{}
   173  		for _, val := range strings.Split(sval, ",") {
   174  			vals = append(vals, val)
   175  		}
   176  		return vals, nil
   177  	}
   178  	if sval, ok := v.(*string); ok {
   179  		if sval == nil {
   180  			return nil, ErrNil
   181  		}
   182  		vals := []interface{}{}
   183  		for _, val := range strings.Split(*sval, ",") {
   184  			vals = append(vals, val)
   185  		}
   186  		return vals, nil
   187  	}
   188  	vals := reflect.ValueOf(v)
   189  	if vals.Kind() != reflect.Slice {
   190  		if all {
   191  			return []interface{}{v}, nil
   192  		}
   193  		return nil, fmt.Errorf("incompactable kind(%v)", vals.Kind())
   194  	}
   195  	var vs = []interface{}{}
   196  	for i := 0; i < vals.Len(); i++ {
   197  		vs = append(vs, vals.Index(i).Interface())
   198  	}
   199  	return vs, nil
   200  }
   201  
   202  func ArrayStringVal(v interface{}) (svals []string, err error) {
   203  	if v == nil {
   204  		return nil, ErrNil
   205  	}
   206  	var sval string
   207  	if vals, ok := v.([]interface{}); ok {
   208  		for _, v := range vals {
   209  			sval, err = StringVal(v)
   210  			if err != nil {
   211  				return
   212  			}
   213  			svals = append(svals, sval)
   214  		}
   215  		return
   216  	}
   217  	if sval, ok := v.(string); ok {
   218  		svals = strings.Split(sval, ",")
   219  		return
   220  	}
   221  	if sval, ok := v.(*string); ok {
   222  		if sval == nil {
   223  			return nil, ErrNil
   224  		}
   225  		svals = strings.Split(*sval, ",")
   226  		return
   227  	}
   228  	vals := reflect.ValueOf(v)
   229  	if vals.Kind() != reflect.Slice {
   230  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
   231  		return
   232  	}
   233  	for i := 0; i < vals.Len(); i++ {
   234  		if vals.Index(i).IsZero() {
   235  			sval, err = StringVal(nil)
   236  		} else {
   237  			sval, err = StringVal(vals.Index(i).Interface())
   238  		}
   239  		if err != nil {
   240  			return
   241  		}
   242  		svals = append(svals, sval)
   243  	}
   244  	return
   245  }
   246  
   247  func ArrayIntVal(v interface{}) (ivals []int, err error) {
   248  	if v == nil {
   249  		return nil, ErrNil
   250  	}
   251  	var ival int
   252  	if vals, ok := v.([]interface{}); ok {
   253  		for _, v := range vals {
   254  			ival, err = IntVal(v)
   255  			if err != nil {
   256  				return
   257  			}
   258  			ivals = append(ivals, ival)
   259  		}
   260  		return
   261  	}
   262  	if sval, ok := v.(string); ok {
   263  		for _, val := range strings.Split(sval, ",") {
   264  			ival, err = IntVal(val)
   265  			if err != nil {
   266  				return
   267  			}
   268  			ivals = append(ivals, ival)
   269  		}
   270  		return
   271  	}
   272  	if sval, ok := v.(*string); ok {
   273  		if sval == nil {
   274  			return nil, ErrNil
   275  		}
   276  		for _, val := range strings.Split(*sval, ",") {
   277  			ival, err = IntVal(val)
   278  			if err != nil {
   279  				return
   280  			}
   281  			ivals = append(ivals, ival)
   282  		}
   283  		return
   284  	}
   285  	vals := reflect.ValueOf(v)
   286  	if vals.Kind() != reflect.Slice {
   287  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
   288  		return
   289  	}
   290  	for i := 0; i < vals.Len(); i++ {
   291  		ival, err = IntVal(vals.Index(i).Interface())
   292  		if err != nil {
   293  			return
   294  		}
   295  		ivals = append(ivals, ival)
   296  	}
   297  	return
   298  }
   299  
   300  func ArrayInt64Val(v interface{}) (ivals []int64, err error) {
   301  	if v == nil {
   302  		return nil, ErrNil
   303  	}
   304  	var ival int64
   305  	if vals, ok := v.([]interface{}); ok {
   306  		for _, v := range vals {
   307  			ival, err = Int64Val(v)
   308  			if err != nil {
   309  				return
   310  			}
   311  			ivals = append(ivals, ival)
   312  		}
   313  		return
   314  	}
   315  	if sval, ok := v.(string); ok {
   316  		for _, val := range strings.Split(sval, ",") {
   317  			ival, err = Int64Val(val)
   318  			if err != nil {
   319  				return
   320  			}
   321  			ivals = append(ivals, ival)
   322  		}
   323  		return
   324  	}
   325  	if sval, ok := v.(*string); ok {
   326  		if sval == nil {
   327  			return nil, ErrNil
   328  		}
   329  		for _, val := range strings.Split(*sval, ",") {
   330  			ival, err = Int64Val(val)
   331  			if err != nil {
   332  				return
   333  			}
   334  			ivals = append(ivals, ival)
   335  		}
   336  		return
   337  	}
   338  	vals := reflect.ValueOf(v)
   339  	if vals.Kind() != reflect.Slice {
   340  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
   341  		return
   342  	}
   343  	for i := 0; i < vals.Len(); i++ {
   344  		ival, err = Int64Val(vals.Index(i).Interface())
   345  		if err != nil {
   346  			return
   347  		}
   348  		ivals = append(ivals, ival)
   349  	}
   350  	return
   351  }
   352  
   353  func ArrayUint64Val(v interface{}) (ivals []uint64, err error) {
   354  	if v == nil {
   355  		return nil, ErrNil
   356  	}
   357  	var ival uint64
   358  	if vals, ok := v.([]interface{}); ok {
   359  		for _, v := range vals {
   360  			ival, err = Uint64Val(v)
   361  			if err != nil {
   362  				return
   363  			}
   364  			ivals = append(ivals, ival)
   365  		}
   366  		return
   367  	}
   368  	if sval, ok := v.(string); ok {
   369  		for _, val := range strings.Split(sval, ",") {
   370  			ival, err = Uint64Val(val)
   371  			if err != nil {
   372  				return
   373  			}
   374  			ivals = append(ivals, ival)
   375  		}
   376  		return
   377  	}
   378  	if sval, ok := v.(*string); ok {
   379  		if sval == nil {
   380  			return nil, ErrNil
   381  		}
   382  		for _, val := range strings.Split(*sval, ",") {
   383  			ival, err = Uint64Val(val)
   384  			if err != nil {
   385  				return
   386  			}
   387  			ivals = append(ivals, ival)
   388  		}
   389  		return
   390  	}
   391  	vals := reflect.ValueOf(v)
   392  	if vals.Kind() != reflect.Slice {
   393  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
   394  		return
   395  	}
   396  	for i := 0; i < vals.Len(); i++ {
   397  		ival, err = Uint64Val(vals.Index(i).Interface())
   398  		if err != nil {
   399  			return
   400  		}
   401  		ivals = append(ivals, ival)
   402  	}
   403  	return
   404  }
   405  
   406  func ArrayFloat64Val(v interface{}) (ivals []float64, err error) {
   407  	if v == nil {
   408  		return nil, ErrNil
   409  	}
   410  	var ival float64
   411  	if vals, ok := v.([]interface{}); ok {
   412  		for _, v := range vals {
   413  			ival, err = Float64Val(v)
   414  			if err != nil {
   415  				return
   416  			}
   417  			ivals = append(ivals, ival)
   418  		}
   419  		return
   420  	}
   421  	if sval, ok := v.(string); ok {
   422  		for _, val := range strings.Split(sval, ",") {
   423  			ival, err = Float64Val(val)
   424  			if err != nil {
   425  				return
   426  			}
   427  			ivals = append(ivals, ival)
   428  		}
   429  		return
   430  	}
   431  	if sval, ok := v.(*string); ok {
   432  		if sval == nil {
   433  			return nil, ErrNil
   434  		}
   435  		for _, val := range strings.Split(*sval, ",") {
   436  			ival, err = Float64Val(val)
   437  			if err != nil {
   438  				return
   439  			}
   440  			ivals = append(ivals, ival)
   441  		}
   442  		return
   443  	}
   444  	vals := reflect.ValueOf(v)
   445  	if vals.Kind() != reflect.Slice {
   446  		err = fmt.Errorf("incompactable kind(%v)", vals.Kind())
   447  		return
   448  	}
   449  	for i := 0; i < vals.Len(); i++ {
   450  		ival, err = Float64Val(vals.Index(i).Interface())
   451  		if err != nil {
   452  			return
   453  		}
   454  		ivals = append(ivals, ival)
   455  	}
   456  	return
   457  }
   458  
   459  //ArrayHaving will return true if the array element having one is in objs
   460  func ArrayHaving(ary interface{}, objs ...interface{}) bool {
   461  	switch reflect.TypeOf(ary).Kind() {
   462  	case reflect.Slice:
   463  		s := reflect.ValueOf(ary)
   464  		for i := 0; i < s.Len(); i++ {
   465  			for _, obj := range objs {
   466  				if obj == s.Index(i).Interface() {
   467  					return true
   468  				}
   469  			}
   470  		}
   471  		return false
   472  	default:
   473  		return false
   474  	}
   475  }
   476  
   477  func JSON(v interface{}) string {
   478  	data, err := json.Marshal(v)
   479  	if err != nil {
   480  		return err.Error()
   481  	}
   482  	return string(data)
   483  }
   484  
   485  func XML(v interface{}) string {
   486  	data, err := xml.Marshal(v)
   487  	if err != nil {
   488  		return err.Error()
   489  	}
   490  	return string(data)
   491  }
   492  
   493  //UnmarshalJSON will read bytes from reader and unmarshal to object
   494  func UnmarshalJSON(r io.Reader, v interface{}) (data []byte, err error) {
   495  	data, err = ioutil.ReadAll(r)
   496  	if err == nil || err == io.EOF {
   497  		err = json.Unmarshal(data, v)
   498  	}
   499  	return
   500  }
   501  
   502  //UnmarshalXML will read bytes from reader and unmarshal to object
   503  func UnmarshalXML(r io.Reader, v interface{}) (data []byte, err error) {
   504  	data, err = ioutil.ReadAll(r)
   505  	if err == nil || err == io.EOF {
   506  		err = xml.Unmarshal(data, v)
   507  	}
   508  	return
   509  }
   510  
   511  // Int8Ptr -
   512  func Int8Ptr(arg int8) *int8 {
   513  	return &arg
   514  }
   515  
   516  // Uint8Ptr -
   517  func Uint8Ptr(arg uint8) *uint8 {
   518  	return &arg
   519  }
   520  
   521  // Int16Ptr -
   522  func Int16Ptr(arg int16) *int16 {
   523  	return &arg
   524  }
   525  
   526  // Uint16Ptr -
   527  func Uint16Ptr(arg uint16) *uint16 {
   528  	return &arg
   529  }
   530  
   531  // IntPtr -
   532  func IntPtr(arg int) *int {
   533  	return &arg
   534  }
   535  
   536  // UintPtr -
   537  func UintPtr(arg uint) *uint {
   538  	return &arg
   539  }
   540  
   541  // Int32Ptr -
   542  func Int32Ptr(arg int32) *int32 {
   543  	return &arg
   544  }
   545  
   546  // Uint32Ptr -
   547  func Uint32Ptr(arg uint32) *uint32 {
   548  	return &arg
   549  }
   550  
   551  // Int64Ptr -
   552  func Int64Ptr(arg int64) *int64 {
   553  	return &arg
   554  }
   555  
   556  // Uint64Ptr -
   557  func Uint64Ptr(arg uint64) *uint64 {
   558  	return &arg
   559  }
   560  
   561  // Float32Ptr -
   562  func Float32Ptr(arg float32) *float32 {
   563  	return &arg
   564  }
   565  
   566  // Float64Ptr -
   567  func Float64Ptr(arg float64) *float64 {
   568  	return &arg
   569  }
   570  
   571  // StringPtr -
   572  func StringPtr(arg string) *string {
   573  	return &arg
   574  }
   575  
   576  //Join all slice to string
   577  func Join(v interface{}, sep string) string {
   578  	vtype := reflect.TypeOf(v)
   579  	if vtype.Kind() != reflect.Slice {
   580  		panic("not slice")
   581  	}
   582  	vval := reflect.ValueOf(v)
   583  	if vval.Len() < 1 {
   584  		return ""
   585  	}
   586  	val := fmt.Sprintf("%v", reflect.Indirect(vval.Index(0)).Interface())
   587  	for i := 1; i < vval.Len(); i++ {
   588  		val += fmt.Sprintf("%v%v", sep, reflect.Indirect(vval.Index(i)).Interface())
   589  	}
   590  	return val
   591  }
   592  
   593  const (
   594  	JoinPolicyNotSliceEmpty  = 1 << 0
   595  	JoinPolicyNotSliceString = 1 << 1
   596  	JoinPolicyNilSkip        = 1 << 5
   597  	JoinPolicyNilString      = 1 << 6
   598  	JoinPolicyDefault        = JoinPolicyNotSliceEmpty | JoinPolicyNilSkip
   599  )
   600  
   601  func JoinSafe(v interface{}, sep string, policy int) string {
   602  	vtype := reflect.TypeOf(v)
   603  	if vtype.Kind() != reflect.Slice {
   604  		if policy&JoinPolicyNotSliceString == JoinPolicyNotSliceString {
   605  			return fmt.Sprintf("%v", v)
   606  		} else {
   607  			return ""
   608  		}
   609  	}
   610  	vval := reflect.ValueOf(v)
   611  	if vval.Len() < 1 {
   612  		return ""
   613  	}
   614  	stringVal := func(v reflect.Value) (string, bool) {
   615  		if v.Kind() == reflect.Ptr && v.IsNil() {
   616  			if policy&JoinPolicyNilString == JoinPolicyNilString {
   617  				return fmt.Sprintf("%v", v), true
   618  			} else {
   619  				return "", false
   620  			}
   621  		}
   622  		v = reflect.Indirect(v)
   623  		return fmt.Sprintf("%v", v.Interface()), true
   624  	}
   625  	val := ""
   626  	for i := 0; i < vval.Len(); i++ {
   627  		s, ok := stringVal(vval.Index(i))
   628  		if !ok {
   629  			continue
   630  		}
   631  		if len(val) > 0 {
   632  			val += fmt.Sprintf("%v%v", sep, s)
   633  		} else {
   634  			val = s
   635  		}
   636  	}
   637  	return val
   638  }
   639  
   640  func IndirectString(val interface{}) string {
   641  	if val == nil {
   642  		return "nil"
   643  	}
   644  	rval := reflect.ValueOf(val)
   645  	if rval.Kind() == reflect.Ptr && rval.IsNil() {
   646  		return "nil"
   647  	}
   648  	return fmt.Sprintf("%v", reflect.Indirect(rval).Interface())
   649  }