github.com/yaoapp/kun@v0.9.0/num/number.go (about)

     1  package num
     2  
     3  import (
     4  	"database/sql/driver"
     5  	"encoding/json"
     6  	"fmt"
     7  	"regexp"
     8  	"strconv"
     9  )
    10  
    11  // Number type of numberic
    12  type Number struct {
    13  	value interface{}
    14  }
    15  
    16  // Make create a empty instance
    17  func Make() *Number {
    18  	return &Number{value: nil}
    19  }
    20  
    21  // Of make a new number
    22  func Of(value interface{}) *Number {
    23  	return &Number{value: value}
    24  }
    25  
    26  // Set set <value> to <v>, and returns the old value.
    27  func (n *Number) Set(value interface{}) (old interface{}) {
    28  	old = n.value
    29  	n.value = value
    30  	return old
    31  }
    32  
    33  // ToFixed the return value is the type of float64 and keeps the given decimal places
    34  func (n Number) ToFixed(places int) string {
    35  	format := fmt.Sprintf("%%.%df", places)
    36  	return fmt.Sprintf(format, n.Float64())
    37  }
    38  
    39  // Float is alias of Float64 converts and returns as float64
    40  func (n Number) Float() float64 {
    41  	return n.Float64()
    42  }
    43  
    44  // Float64 converts and returns as float64
    45  func (n Number) Float64() float64 {
    46  	if n.value == nil {
    47  		return 0.0
    48  	}
    49  
    50  	switch n.value.(type) {
    51  	case float64:
    52  		return n.value.(float64)
    53  	case float32:
    54  		return float64(n.value.(float32))
    55  	case complex128:
    56  		return real(n.value.(complex128))
    57  	case complex64:
    58  		return float64(real(n.value.(complex64)))
    59  	}
    60  
    61  	value, err := strconv.ParseFloat(fmt.Sprintf("%v", n.value), 64)
    62  	if err != nil {
    63  		panic(err.Error())
    64  	}
    65  	return value
    66  }
    67  
    68  // Float32 converts and returns as float32
    69  func (n Number) Float32() float32 {
    70  	if n.value == nil {
    71  		return 0.0
    72  	}
    73  
    74  	switch n.value.(type) {
    75  	case float64:
    76  		return float32(n.value.(float64))
    77  	case float32:
    78  		return n.value.(float32)
    79  	}
    80  
    81  	value, err := strconv.ParseFloat(fmt.Sprintf("%v", n.value), 32)
    82  	if err != nil {
    83  		panic(err.Error())
    84  	}
    85  	return float32(value)
    86  }
    87  
    88  // Complex is alias of Complex128 converts and returns as complex128
    89  func (n Number) Complex() complex128 {
    90  	return n.Complex128()
    91  }
    92  
    93  // Complex128 converts and returns as complex128
    94  func (n Number) Complex128() complex128 {
    95  	value, ok := n.value.(complex128)
    96  	if ok {
    97  		return value
    98  	}
    99  
   100  	value64, ok := n.value.(complex64)
   101  	if ok {
   102  		return complex128(value64)
   103  	}
   104  
   105  	valueStr, ok := n.value.(string)
   106  	if ok {
   107  		// 1.56+2.48i
   108  		re := regexp.MustCompile(`[ \()]*([0-9\.]+)[ ]*\+[ ]*([0-9\.]+)i[ \)]*`)
   109  		matched := re.FindStringSubmatch(valueStr)
   110  		if len(matched) > 0 {
   111  			return complex(Of(matched[1]).Float64(), Of(matched[2]).Float64())
   112  		}
   113  
   114  		// (1.56,2.48i)
   115  		re = regexp.MustCompile(`\([ ]*([0-9\.]+)[ ]*,[ ]*([0-9\.]+)[ ]*\)`)
   116  		matched = re.FindStringSubmatch(valueStr)
   117  		if len(matched) > 0 {
   118  			return complex(Of(matched[1]).Float64(), Of(matched[2]).Float64())
   119  		}
   120  	}
   121  	return complex(n.Float64(), 0)
   122  }
   123  
   124  // Complex64 converts and returns as Complex64
   125  func (n Number) Complex64() complex64 {
   126  	value, ok := n.value.(complex64)
   127  	if ok {
   128  		return value
   129  	}
   130  
   131  	value128, ok := n.value.(complex128)
   132  	if ok {
   133  		return complex64(value128)
   134  	}
   135  
   136  	valueStr, ok := n.value.(string)
   137  	if ok {
   138  		// 1.56+2.48i
   139  		re := regexp.MustCompile(`[ \()]*([0-9\.]+)[ ]*\+[ ]*([0-9\.]+)i[ \)]*`)
   140  		matched := re.FindStringSubmatch(valueStr)
   141  		if len(matched) > 0 {
   142  			return complex(Of(matched[1]).Float32(), Of(matched[2]).Float32())
   143  		}
   144  
   145  		// (1.56,2.48i)
   146  		re = regexp.MustCompile(`\([ ]*([0-9\.]+)[ ]*,[ ]*([0-9\.]+)[ ]*\)`)
   147  		matched = re.FindStringSubmatch(valueStr)
   148  		if len(matched) > 0 {
   149  			return complex(Of(matched[1]).Float32(), Of(matched[2]).Float32())
   150  		}
   151  	}
   152  	return complex(n.Float32(), 0.0)
   153  }
   154  
   155  // Int64 the return value is the type of int64 and remove the decimal
   156  func (n Number) Int64() int64 {
   157  	value, ok := n.value.(int64)
   158  	if ok {
   159  		return value
   160  	}
   161  	return int64(n.Int())
   162  }
   163  
   164  // Int32 the return value is the type of int32 and remove the decimal
   165  func (n Number) Int32() int32 {
   166  	value, ok := n.value.(int32)
   167  	if ok {
   168  		return value
   169  	}
   170  	return int32(n.Int())
   171  }
   172  
   173  // Int16 the return value is the type of int16 and remove the decimal
   174  func (n Number) Int16() int16 {
   175  	value, ok := n.value.(int16)
   176  	if ok {
   177  		return value
   178  	}
   179  	return int16(n.Int())
   180  }
   181  
   182  // Int8 converts and returns as Int8
   183  func (n Number) Int8() int8 {
   184  	value, ok := n.value.(int8)
   185  	if ok {
   186  		return value
   187  	}
   188  	return int8(n.Int())
   189  }
   190  
   191  // Int converts and returns as Int
   192  func (n Number) Int() int {
   193  	if n.value == nil {
   194  		return 0
   195  	}
   196  
   197  	value, ok := n.value.(int)
   198  	if ok {
   199  		return value
   200  	}
   201  
   202  	value, _ = strconv.Atoi(fmt.Sprintf("%.0f", n.Float64()))
   203  	return value
   204  }
   205  
   206  // Uint64 the return value is the type of uint64 and remove the decimal
   207  func (n Number) Uint64() uint64 {
   208  	value, ok := n.value.(uint64)
   209  	if ok {
   210  		return value
   211  	}
   212  	return uint64(n.Int())
   213  }
   214  
   215  // Uint32 the return value is the type of uint32 and remove the decimal
   216  func (n Number) Uint32() uint32 {
   217  	value, ok := n.value.(uint32)
   218  	if ok {
   219  		return value
   220  	}
   221  	return uint32(n.Int())
   222  }
   223  
   224  // Uint16 the return value is the type of uint16 and remove the decimal
   225  func (n Number) Uint16() uint16 {
   226  	value, ok := n.value.(uint16)
   227  	if ok {
   228  		return value
   229  	}
   230  	return uint16(n.Int())
   231  }
   232  
   233  // Uint8 the return value is the type of uint8 and remove the decimal
   234  func (n Number) Uint8() uint8 {
   235  	value, ok := n.value.(uint8)
   236  	if ok {
   237  		return value
   238  	}
   239  	return uint8(n.Int())
   240  }
   241  
   242  // Uint the return value is the type of uint and remove the decimal
   243  func (n Number) Uint() uint {
   244  	value, ok := n.value.(uint)
   245  	if ok {
   246  		return value
   247  	}
   248  	return uint(n.Int())
   249  }
   250  
   251  // Uintptr the return value is the type of uintptr
   252  func (n Number) Uintptr() uintptr {
   253  	value, ok := n.value.(uintptr)
   254  	if ok {
   255  		return value
   256  	}
   257  	return uintptr(n.Int())
   258  }
   259  
   260  // IsSet checks whether <v> is not nil.
   261  func (n Number) IsSet() bool {
   262  	return n.value != nil
   263  }
   264  
   265  // IsNil checks whether <v> is nil.
   266  func (n Number) IsNil() bool {
   267  	return n.value == nil
   268  }
   269  
   270  // IsInt checks whether <v> is type of int.
   271  func (n Number) IsInt() bool {
   272  	switch n.value.(type) {
   273  	case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
   274  		return true
   275  	default:
   276  		return false
   277  	}
   278  }
   279  
   280  // IsFloat checks whether <v> is type of float.
   281  func (n Number) IsFloat() bool {
   282  	switch n.value.(type) {
   283  	case float32, float64:
   284  		return true
   285  	default:
   286  		return false
   287  	}
   288  }
   289  
   290  // IsComplex checks whether <v> is type of complex.
   291  func (n Number) IsComplex() bool {
   292  	switch n.value.(type) {
   293  	case complex128, complex64:
   294  		return true
   295  	default:
   296  		return false
   297  	}
   298  }
   299  
   300  // Scan for db scan
   301  func (n *Number) Scan(src interface{}) error {
   302  	*n = *Of(src)
   303  	return nil
   304  }
   305  
   306  // Value for db driver value
   307  func (n *Number) Value() (driver.Value, error) {
   308  	return n.value, nil
   309  }
   310  
   311  // MarshalJSON for json marshalJSON
   312  func (n *Number) MarshalJSON() ([]byte, error) {
   313  	return json.Marshal(n.value)
   314  }
   315  
   316  // UnmarshalJSON for json marshalJSON
   317  func (n *Number) UnmarshalJSON(data []byte) error {
   318  	var v float64
   319  	err := json.Unmarshal(data, &v)
   320  	if err != nil {
   321  		return err
   322  	}
   323  	*n = *Of(v)
   324  	return nil
   325  }