| 1 |  |  | package generic | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | import ( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | 	"fmt" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | 	"reflect" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | 	"strconv" | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | type Number struct { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | 	int   int64 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | 	float float64 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | 	isInt bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | 	isNil bool | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | func NewNumber(value interface{}) (*Number, error) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 | 1 |  | 	v := reflect.ValueOf(value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 | 1 |  | 	if v.Kind() == reflect.Ptr { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 | 1 |  | 		if v.IsNil() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 | 1 |  | 			return &Number{isNil: true}, nil | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | 		} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 | 1 |  | 		return numberFromValue(v.Elem()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 | 1 |  | 	return numberFromValue(v) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  | func NewNumberFromInt(value int64) Number { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 | 1 |  | 	return Number{ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  | 		int:   value, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  | 		float: float64(value), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | 		isInt: true, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  | } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  | func NewNumberFromFloat(value float64) Number { | 
            
                                                                        
                            
            
                                    
            
            
                | 38 | 1 |  | 	return Number{ | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  | 		int:   int64(value), | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  | 		float: value, | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  | 		isInt: false, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  | func MustNewNumber(value interface{}) Number { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 | 1 |  | 	n, err := NewNumber(value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 | 1 |  | 	if err != nil { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 | 1 |  | 		panic(err) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 | 1 |  | 	return *n | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  | func numberFromValue(v reflect.Value) (*Number, error) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 | 1 |  | 	switch v.Kind() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  | 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 | 1 |  | 		i := v.Int() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 | 1 |  | 		return &Number{int: i, float: float64(i), isInt: true}, nil | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  | 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 | 1 |  | 		i := int64(v.Uint()) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 | 1 |  | 		return &Number{int: i, float: float64(i), isInt: true}, nil | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  | 	case reflect.Float32, reflect.Float64: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 | 1 |  | 		f := v.Float() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 | 1 |  | 		i := int64(f) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 | 1 |  | 		return &Number{int: i, float: f, isInt: f == float64(i)}, nil | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 | 1 |  | 	return nil, NotNumericError{value: v} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  | func (n Number) IsNil() bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 | 1 |  | 	return n.isNil | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  | func (n Number) IsZero() bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 | 1 |  | 	if n.isNil { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 | 1 |  | 		return false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 | 1 |  | 	if n.isInt { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 | 1 |  | 		return n.int == 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 | 1 |  | 	return n.float == 0 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  | func (n Number) IsEqualTo(v Number) bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 | 1 |  | 	if n.isNil || v.isNil { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 | 1 |  | 		return false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 | 1 |  | 	if n.isInt && v.isInt { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 | 1 |  | 		return n.int == v.int | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 | 1 |  | 	return n.float == v.float | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  | func (n Number) IsGreaterThan(v Number) bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 | 1 |  | 	if n.isNil || v.isNil { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 | 1 |  | 		return false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 | 1 |  | 	if n.isInt && v.isInt { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 | 1 |  | 		return n.int > v.int | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 | 1 |  | 	return n.float > v.float | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  | func (n Number) IsLessThan(v Number) bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 | 1 |  | 	if n.isNil || v.isNil { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 | 1 |  | 		return false | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 | 1 |  | 	if n.isInt && v.isInt { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 | 1 |  | 		return n.int < v.int | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 | 1 |  | 	return n.float < v.float | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  | } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  | func (n Number) String() string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 | 1 |  | 	if n.isInt { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 | 1 |  | 		return strconv.FormatInt(n.int, 10) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  | 	} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 | 1 |  | 	return fmt.Sprint(n.float) | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 123 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 124 |  |  |  |