github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/ztype/to.go (about)

     1  // Package ztype provides Variable Type Related Operations
     2  package ztype
     3  
     4  import (
     5  	"bytes"
     6  	// "encoding/json"
     7  	"encoding/json"
     8  	"errors"
     9  	"reflect"
    10  	"strconv"
    11  	"strings"
    12  	"time"
    13  
    14  	"github.com/sohaha/zlsgo/zreflect"
    15  	"github.com/sohaha/zlsgo/zstring"
    16  	"github.com/sohaha/zlsgo/ztime"
    17  )
    18  
    19  type appString interface {
    20  	String() string
    21  }
    22  
    23  // ToByte To []byte
    24  func ToBytes(i interface{}) []byte {
    25  	s := ToString(i)
    26  	return zstring.String2Bytes(s)
    27  }
    28  
    29  // ToString To String
    30  func ToString(i interface{}) string {
    31  	if i == nil {
    32  		return ""
    33  	}
    34  	switch value := i.(type) {
    35  	case int:
    36  		return strconv.Itoa(value)
    37  	case int8:
    38  		return strconv.Itoa(int(value))
    39  	case int16:
    40  		return strconv.Itoa(int(value))
    41  	case int32:
    42  		return strconv.Itoa(int(value))
    43  	case int64:
    44  		return strconv.Itoa(int(value))
    45  	case uint:
    46  		return strconv.FormatUint(uint64(value), 10)
    47  	case uint8:
    48  		return strconv.FormatUint(uint64(value), 10)
    49  	case uint16:
    50  		return strconv.FormatUint(uint64(value), 10)
    51  	case uint32:
    52  		return strconv.FormatUint(uint64(value), 10)
    53  	case uint64:
    54  		return strconv.FormatUint(value, 10)
    55  	case float32:
    56  		return strconv.FormatFloat(float64(value), 'f', -1, 32)
    57  	case float64:
    58  		return strconv.FormatFloat(value, 'f', -1, 64)
    59  	case bool:
    60  		return strconv.FormatBool(value)
    61  	case string:
    62  		return value
    63  	case []byte:
    64  		return zstring.Bytes2String(value)
    65  	default:
    66  		if f, ok := value.(appString); ok {
    67  			return f.String()
    68  		}
    69  		return toJsonString(value)
    70  	}
    71  }
    72  
    73  func toJsonString(value interface{}) string {
    74  	jsonContent, _ := json.Marshal(value)
    75  	jsonContent = bytes.Trim(jsonContent, `"`)
    76  	return zstring.Bytes2String(jsonContent)
    77  }
    78  
    79  // ToBool To Bool
    80  func ToBool(i interface{}) bool {
    81  	if v, ok := i.(bool); ok {
    82  		return v
    83  	}
    84  	if s := ToString(i); s != "" && s != "0" && s != "false" {
    85  		return true
    86  	}
    87  	return false
    88  }
    89  
    90  // ToInt To int
    91  func ToInt(i interface{}) int {
    92  	if v, ok := i.(int); ok {
    93  		return v
    94  	}
    95  	return int(ToInt64(i))
    96  }
    97  
    98  // ToInt8 To int8
    99  func ToInt8(i interface{}) int8 {
   100  	if v, ok := i.(int8); ok {
   101  		return v
   102  	}
   103  	return int8(ToInt64(i))
   104  }
   105  
   106  // ToInt16 To int16
   107  func ToInt16(i interface{}) int16 {
   108  	if v, ok := i.(int16); ok {
   109  		return v
   110  	}
   111  	return int16(ToInt64(i))
   112  }
   113  
   114  // ToInt32 To int32
   115  func ToInt32(i interface{}) int32 {
   116  	if v, ok := i.(int32); ok {
   117  		return v
   118  	}
   119  	return int32(ToInt64(i))
   120  }
   121  
   122  // ToInt64 To int64
   123  func ToInt64(i interface{}) int64 {
   124  	if i == nil {
   125  		return 0
   126  	}
   127  	if v, ok := i.(int64); ok {
   128  		return v
   129  	}
   130  	switch value := i.(type) {
   131  	case int:
   132  		return int64(value)
   133  	case int8:
   134  		return int64(value)
   135  	case int16:
   136  		return int64(value)
   137  	case int32:
   138  		return int64(value)
   139  	case uint:
   140  		return int64(value)
   141  	case uint8:
   142  		return int64(value)
   143  	case uint16:
   144  		return int64(value)
   145  	case uint32:
   146  		return int64(value)
   147  	case uint64:
   148  		return int64(value)
   149  	case float32:
   150  		return int64(value)
   151  	case float64:
   152  		return int64(value)
   153  	case bool:
   154  		if value {
   155  			return 1
   156  		}
   157  		return 0
   158  	default:
   159  		s := ToString(value)
   160  		if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
   161  			if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil {
   162  				return v
   163  			}
   164  		}
   165  		if len(s) > 1 && s[0] == '0' {
   166  			if v, e := strconv.ParseInt(s[1:], 8, 64); e == nil {
   167  				return v
   168  			}
   169  		}
   170  		if v, e := strconv.ParseInt(s, 10, 64); e == nil {
   171  			return v
   172  		}
   173  		return int64(ToFloat64(value))
   174  	}
   175  }
   176  
   177  // ToUint To uint
   178  func ToUint(i interface{}) uint {
   179  	if v, ok := i.(uint); ok {
   180  		return v
   181  	}
   182  	return uint(ToUint64(i))
   183  }
   184  
   185  // ToUint8 To uint8
   186  func ToUint8(i interface{}) uint8 {
   187  	if v, ok := i.(uint8); ok {
   188  		return v
   189  	}
   190  	return uint8(ToUint64(i))
   191  }
   192  
   193  // ToUint16 To uint16
   194  func ToUint16(i interface{}) uint16 {
   195  	if v, ok := i.(uint16); ok {
   196  		return v
   197  	}
   198  	return uint16(ToUint64(i))
   199  }
   200  
   201  // ToUint32 To uint32
   202  func ToUint32(i interface{}) uint32 {
   203  	if v, ok := i.(uint32); ok {
   204  		return v
   205  	}
   206  	return uint32(ToUint64(i))
   207  }
   208  
   209  // ToUint64 To uint64
   210  func ToUint64(i interface{}) uint64 {
   211  	if i == nil {
   212  		return 0
   213  	}
   214  	switch value := i.(type) {
   215  	case int:
   216  		return uint64(value)
   217  	case int8:
   218  		return uint64(value)
   219  	case int16:
   220  		return uint64(value)
   221  	case int32:
   222  		return uint64(value)
   223  	case int64:
   224  		return uint64(value)
   225  	case uint:
   226  		return uint64(value)
   227  	case uint8:
   228  		return uint64(value)
   229  	case uint16:
   230  		return uint64(value)
   231  	case uint32:
   232  		return uint64(value)
   233  	case uint64:
   234  		return value
   235  	case float32:
   236  		return uint64(value)
   237  	case float64:
   238  		return uint64(value)
   239  	case bool:
   240  		if value {
   241  			return 1
   242  		}
   243  		return 0
   244  	default:
   245  		s := ToString(value)
   246  		if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
   247  			if v, e := strconv.ParseUint(s[2:], 16, 64); e == nil {
   248  				return v
   249  			}
   250  		}
   251  		if len(s) > 1 && s[0] == '0' {
   252  			if v, e := strconv.ParseUint(s[1:], 8, 64); e == nil {
   253  				return v
   254  			}
   255  		}
   256  		if v, e := strconv.ParseUint(s, 10, 64); e == nil {
   257  			return v
   258  		}
   259  		return uint64(ToFloat64(value))
   260  	}
   261  }
   262  
   263  // ToFloat32 To float32
   264  func ToFloat32(i interface{}) float32 {
   265  	if i == nil {
   266  		return 0
   267  	}
   268  	if v, ok := i.(float32); ok {
   269  		return v
   270  	}
   271  	v, _ := strconv.ParseFloat(strings.TrimSpace(ToString(i)), 64)
   272  	return float32(v)
   273  }
   274  
   275  // ToFloat64 To float64
   276  func ToFloat64(i interface{}) float64 {
   277  	if i == nil {
   278  		return 0
   279  	}
   280  	if v, ok := i.(float64); ok {
   281  		return v
   282  	}
   283  	v, _ := strconv.ParseFloat(strings.TrimSpace(ToString(i)), 64)
   284  	return v
   285  }
   286  
   287  // ToTime To time.Time
   288  func ToTime(i interface{}, format ...string) (time.Time, error) {
   289  	switch val := i.(type) {
   290  	case time.Time:
   291  		return val, nil
   292  	case int, int32, int64, uint, uint32, uint64:
   293  		i := ToInt64(i)
   294  		if i <= 9999999999 {
   295  			return ztime.Unix(i), nil
   296  		}
   297  		if i <= 9999999999999 {
   298  			i = i * 1000
   299  		}
   300  		return ztime.UnixMicro(i), nil
   301  	default:
   302  		if i := ToInt64(i); i > 0 {
   303  			return ToTime(i)
   304  		}
   305  		v := ToString(i)
   306  		return ztime.Parse(v, format...)
   307  	}
   308  }
   309  
   310  // ToStruct map or struct to struct
   311  func ToStruct(v interface{}, outVal interface{}) error {
   312  	val := zreflect.ValueOf(outVal)
   313  	if reflect.Indirect(val).Kind() != reflect.Struct {
   314  		return errors.New("result must be a struct")
   315  	}
   316  	return conv.to("", v, val)
   317  }