Passed
Push — main ( da04d5...f09b9b )
by Rushan
02:09 queued 11s
created

generic/number.go   A

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
cc 32
eloc 75
dl 0
loc 122
rs 9.84
c 0
b 0
f 0
ccs 45
cts 45
cp 1
crap 32

11 Methods

Rating   Name   Duplication   Size   Complexity  
A generic.NewNumber 0 11 3
A generic.NewNumberFromInt 0 5 1
A generic.NewNumberFromFloat 0 5 1
A generic.Number.String 0 6 2
A generic.Number.IsLessThan 0 9 5
A generic.Number.IsNil 0 2 1
A generic.Number.IsGreaterThan 0 9 5
A generic.MustNewNumber 0 6 2
A generic.Number.IsEqualTo 0 9 5
A generic.numberFromValue 0 15 4
A generic.Number.IsZero 0 8 3
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