-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconverter.go
110 lines (98 loc) · 2.22 KB
/
converter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package collect
import (
"errors"
"fmt"
"golang.org/x/exp/constraints"
"math"
"strconv"
)
func StringToNumber[T constraints.Integer | constraints.Float](s string) (result T, _ error) {
switch any(result).(type) {
// Signed
case int:
n, err := strconv.Atoi(s)
return T(n), err
case int8:
n, err := strconv.ParseInt(s, 10, 8)
return T(n), err
case int16:
n, err := strconv.ParseInt(s, 10, 16)
return T(n), err
case int32:
n, err := strconv.ParseInt(s, 10, 32)
return T(n), err
case int64:
n, err := strconv.ParseInt(s, 10, 64)
return T(n), err
// Unsigned
case uint:
n, err := strconv.ParseUint(s, 10, 0)
return T(n), err
case uint8:
n, err := strconv.ParseUint(s, 10, 8)
return T(n), err
case uint16:
n, err := strconv.ParseUint(s, 10, 16)
return T(n), err
case uint32:
n, err := strconv.ParseUint(s, 10, 32)
return T(n), err
case uint64:
n, err := strconv.ParseUint(s, 10, 64)
return T(n), err
case uintptr:
return result, errors.New("conversion failed")
// Float
case float32:
n, err := strconv.ParseFloat(s, 32)
return T(n), err
case float64:
n, err := strconv.ParseFloat(s, 64)
return T(n), err
}
return
}
func OffsetToIndex(actual, offset int, args ...int) (int, int) {
length := actual
if len(args) >= 1 {
length = args[0]
}
if actual == 0 || (offset == 0 && length < 0) {
return 0, 0
}
// negative offset
if offset < 0 {
offset += actual
}
if offset >= actual || offset < 0 {
return 0, 0
} else if length == 0 {
return offset, offset
}
// negative length
if length < 0 {
if offset+length < 0 {
offset, length = 0, offset+1
} else {
offset, length = offset+length+1, -length
}
}
length = int(math.Min(float64(length), float64(actual-offset)))
return offset, offset + length
}
func NumberFrom[N constraints.Integer | constraints.Float, T ~[]E, E any](c *SliceCollection[T, E]) *NumberCollection[[]N, N] {
if c.Empty() {
return &NumberCollection[[]N, N]{}
}
z := c.All()
items := make([]N, len(z), cap(z))
for key, item := range z {
switch v := (interface{})(item).(type) {
case string:
items[key], _ = StringToNumber[N](v)
default:
items[key], _ = StringToNumber[N](fmt.Sprintf("%d", v))
}
}
return UseNumber[[]N, N](items)
}