forked from digisan/go-generics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
type.go
164 lines (140 loc) · 2.96 KB
/
type.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package gogenerics
import (
"fmt"
"log"
"net"
"net/mail"
"net/url"
"reflect"
"strconv"
)
func KindOf(v any) string {
return reflect.ValueOf(v).Kind().String()
}
// slowest
// func TypeOf1(v any) string {
// return fmt.Sprintf("%T", v)
// }
// 2nd fast
// func TypeOf(v any) string {
// return reflect.TypeOf(v).String()
// }
// fastest, but cannot cover all, e.g. pointer type
func TypeOf(v any) string {
switch v.(type) {
case string:
return "string"
case int:
return "int"
case float64:
return "float64"
case bool:
return "bool"
case uint:
return "uint"
case int8:
return "int8"
case int16:
return "int16"
case int32:
return "int32"
case int64:
return "int64"
case uint8:
return "uint8"
case uint16:
return "uint16"
case uint32:
return "uint32"
case uint64:
return "uint64"
case float32:
return "float32"
case complex64:
return "complex64"
case complex128:
return "complex128"
default:
return reflect.TypeOf(v).String()
}
}
type Integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type UInteger interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}
func IsArrOrSlc(v any) bool {
if v == nil {
return false
}
return In(reflect.TypeOf(v).Kind(), reflect.Slice, reflect.Array)
}
func LenOfMustArrOrSlc(v any) int {
if v == nil {
log.Fatalf("[%v] is NOT Slice or Array Type", v)
}
return reflect.ValueOf(v).Len()
}
// IsInt : Check v is valid int numeric style
func IsInt(v any) bool {
_, err := strconv.ParseInt(fmt.Sprint(v), 10, 64)
return err == nil
}
// IsUint : Check v is valid uint numeric style
func IsUint(v any) bool {
_, err := strconv.ParseUint(fmt.Sprint(v), 10, 64)
return err == nil
}
// IsNumeric : Check v is valid numeric style
func IsNumeric(v any) bool {
_, err := strconv.ParseFloat(fmt.Sprint(v), 64)
return err == nil
}
// IsContinuous : check numbers is continuous int slice
func IsContinuous[T Integer](numbers ...T) (ok bool, rtMin T, rtMax T) {
if len(numbers) == 0 {
return false, *new(T), *new(T)
}
if len(numbers) == 1 {
return true, numbers[0], numbers[0]
}
s, e := numbers[0], numbers[len(numbers)-1]
if s < e {
return reflect.DeepEqual(IterToSlc(s, e+1), numbers), s, e
}
return reflect.DeepEqual(IterToSlc(s, e-1), numbers), e, s
}
// nil-pointer could be non-nil any
func IsNil(i any) bool {
return i == nil || reflect.ValueOf(i).Kind() == 0 || reflect.ValueOf(i).IsNil() || fmt.Sprint(i) == "<nil>"
}
// check string format is email
func IsEmail(s string) bool {
_, err := mail.ParseAddress(s)
return err == nil
}
// check string is valid IP
func IsIP(s string) bool {
return net.ParseIP(s) != nil
}
func IsURL(s string) bool {
_, err := url.ParseRequestURI(s)
return err == nil
}
func IsDateTime(s string) bool {
_, ok := TryToDateTime(s)
return ok
}
func IsDateUS(s string) bool {
_, ok := TryToDateUS(s)
return ok
}
func IsDateUK(s string) bool {
_, ok := TryToDateUK(s)
return ok
}
func IsTime(s string) bool {
_, ok := TryToTime(s)
return ok
}