-
Notifications
You must be signed in to change notification settings - Fork 10
/
convert.go
153 lines (143 loc) · 3.87 KB
/
convert.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
// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
// 🤖 Github Repository: https://github.com/gofiber/fiber
// 📌 API Documentation: https://docs.gofiber.io
package utils
import (
"fmt"
"reflect"
"strconv"
"strings"
"time"
"unsafe"
)
// UnsafeString returns a string pointer without allocation
func UnsafeString(b []byte) string {
// the new way is slower `return unsafe.String(unsafe.SliceData(b), len(b))`
// unsafe.Pointer variant: 0.3538 ns/op vs unsafe.String variant: 0.5410 ns/op
// #nosec G103
return *(*string)(unsafe.Pointer(&b))
}
// UnsafeBytes returns a byte pointer without allocation.
func UnsafeBytes(s string) []byte {
// #nosec G103
return unsafe.Slice(unsafe.StringData(s), len(s))
}
// CopyString copies a string to make it immutable
func CopyString(s string) string {
// #nosec G103
return string(UnsafeBytes(s))
}
// #nosec G103
// CopyBytes copies a slice to make it immutable
func CopyBytes(b []byte) []byte {
tmp := make([]byte, len(b))
copy(tmp, b)
return tmp
}
const (
uByte = 1 << (10 * iota)
uKilobyte
uMegabyte
uGigabyte
uTerabyte
uPetabyte
uExabyte
)
// ByteSize returns a human-readable byte string of the form 10M, 12.5K, and so forth.
// The unit that results in the smallest number greater than or equal to 1 is always chosen.
func ByteSize(bytes uint64) string {
unit := ""
value := float64(bytes)
switch {
case bytes >= uExabyte:
unit = "EB"
value /= uExabyte
case bytes >= uPetabyte:
unit = "PB"
value /= uPetabyte
case bytes >= uTerabyte:
unit = "TB"
value /= uTerabyte
case bytes >= uGigabyte:
unit = "GB"
value /= uGigabyte
case bytes >= uMegabyte:
unit = "MB"
value /= uMegabyte
case bytes >= uKilobyte:
unit = "KB"
value /= uKilobyte
case bytes >= uByte:
unit = "B"
default:
return "0B"
}
result := strconv.FormatFloat(value, 'f', 1, 64)
result = strings.TrimSuffix(result, ".0")
return result + unit
}
// ToString Change arg to string
func ToString(arg any, timeFormat ...string) string {
switch v := arg.(type) {
case int:
return strconv.Itoa(v)
case int8:
return strconv.FormatInt(int64(v), 10)
case int16:
return strconv.FormatInt(int64(v), 10)
case int32:
return strconv.FormatInt(int64(v), 10)
case int64:
return strconv.FormatInt(v, 10)
case uint:
return strconv.Itoa(int(v))
case uint8:
return strconv.FormatInt(int64(v), 10)
case uint16:
return strconv.FormatInt(int64(v), 10)
case uint32:
return strconv.FormatInt(int64(v), 10)
case uint64:
return strconv.FormatInt(int64(v), 10)
case string:
return v
case []byte:
return string(v)
case bool:
return strconv.FormatBool(v)
case float32:
return strconv.FormatFloat(float64(v), 'f', -1, 32)
case float64:
return strconv.FormatFloat(v, 'f', -1, 64)
case time.Time:
if len(timeFormat) > 0 {
return v.Format(timeFormat[0])
}
return v.Format("2006-01-02 15:04:05")
case reflect.Value:
return ToString(v.Interface(), timeFormat...)
case fmt.Stringer:
return v.String()
default:
// Check if the type is a pointer by using reflection
rv := reflect.ValueOf(arg)
if rv.Kind() == reflect.Ptr && !rv.IsNil() {
// Dereference the pointer and recursively call ToString
return ToString(rv.Elem().Interface(), timeFormat...)
} else if rv.Kind() == reflect.Slice || rv.Kind() == reflect.Array {
// handle slices
var buf strings.Builder
buf.WriteString("[") //nolint: revive,errcheck // no need to check error
for i := 0; i < rv.Len(); i++ {
if i > 0 {
buf.WriteString(" ") //nolint: revive,errcheck // no need to check error
}
buf.WriteString(ToString(rv.Index(i).Interface())) //nolint: revive,errcheck // no need to check error
}
buf.WriteString("]") //nolint: revive,errcheck // no need to check error
return buf.String()
}
// For types not explicitly handled, use fmt.Sprint to generate a string representation
return fmt.Sprint(arg)
}
}