/
utils.go
82 lines (72 loc) · 1.52 KB
/
utils.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
package utils
import (
"bytes"
"errors"
"fmt"
"reflect"
"strings"
)
// Abs return the absolute value
func Abs(v int64) int64 {
if v >= 0 {
return v
}
return -v
}
// Split the string.
// if empty return an empty slice instead of nil
func Split(str string, sep string) (r []string) {
p := strings.Split(str, sep)
if len(p) == 1 && p[0] == "" {
r = []string{}
return
}
r = make([]string, 0, len(p))
for _, v := range p {
v = strings.TrimSpace(v)
if len(v) > 0 {
r = append(r, v)
}
}
return
}
// TrimUntil trim the prefix until find the stop character
func TrimUntil(s string, stop string) string {
p := strings.SplitN(s, stop, 2)
n := len(p)
return p[n-1]
}
// RepeatWithSep repeat the `s` `count` times, and separated by `sep`
func RepeatWithSep(s string, sep string, count int) string {
if count < 0 {
panic("negative RepeatWithSep count")
} else if count > 0 && len(s)*count/count != len(s) {
panic("RepeatWithSep count causes overflow")
}
b := make([]byte, len(s)*count+len(sep)*(count-1))
bp := copy(b, s)
bp += copy(b[bp:], sep)
for bp < len(b) {
copy(b[bp:], b[:bp])
bp *= 2
}
return string(b)
}
// JoinSlice join the slice to string with separator `sep`
func JoinSlice(slice any, sep string) string {
var (
v = reflect.ValueOf(slice)
b bytes.Buffer
)
if v.Kind() != reflect.Slice {
panic(errors.New("not slice"))
}
for i := 0; i < v.Len(); i++ {
b.WriteString(fmt.Sprint(v.Index(i)))
b.WriteString(sep)
}
if b.Len() > 0 {
b.Truncate(b.Len() - len(sep))
}
return b.String()
}