Commit 1c83dc241fe9999ce1d6e48bdf454e30891d896c
1 parent
3173b06a41
Exists in
master
GUID and timer
Showing
3 changed files
with
111 additions
and
0 deletions
Show diff stats
guid.go
File was created | 1 | package webutility | |
2 | |||
3 | import ( | ||
4 | "crypto/rand" | ||
5 | "fmt" | ||
6 | ) | ||
7 | |||
8 | // GUID ... | ||
9 | func GUID() (string, error) { | ||
10 | b := make([]byte, 16) | ||
11 | _, err := rand.Read(b) | ||
12 | if err != nil { | ||
13 | return "", err | ||
14 | } | ||
15 | id := fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) | ||
16 | return id, nil | ||
17 | } | ||
18 |
string_util.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "strconv" | 5 | "strconv" |
6 | "strings" | 6 | "strings" |
7 | "unicode" | 7 | "unicode" |
8 | ) | 8 | ) |
9 | 9 | ||
10 | const sanitisationPatern = "\"';&*<>=\\`:" | 10 | const sanitisationPatern = "\"';&*<>=\\`:" |
11 | 11 | ||
12 | // SanitiseString removes characters from s found in patern and returns new modified string. | 12 | // SanitiseString removes characters from s found in patern and returns new modified string. |
13 | func SanitiseString(s string) string { | 13 | func SanitiseString(s string) string { |
14 | return ReplaceAny(s, sanitisationPatern, "") | 14 | return ReplaceAny(s, sanitisationPatern, "") |
15 | } | 15 | } |
16 | 16 | ||
17 | // IsWrappedWith ... | 17 | // IsWrappedWith ... |
18 | func IsWrappedWith(src, begin, end string) bool { | 18 | func IsWrappedWith(src, begin, end string) bool { |
19 | return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end) | 19 | return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end) |
20 | } | 20 | } |
21 | 21 | ||
22 | // ParseInt64Arr ... | 22 | // ParseInt64Arr ... |
23 | func ParseInt64Arr(s, sep string) (arr []int64) { | 23 | func ParseInt64Arr(s, sep string) (arr []int64) { |
24 | s = strings.TrimSpace(s) | 24 | s = strings.TrimSpace(s) |
25 | if s != "" { | 25 | if s != "" { |
26 | parts := strings.Split(s, sep) | 26 | parts := strings.Split(s, sep) |
27 | arr = make([]int64, len(parts)) | 27 | arr = make([]int64, len(parts)) |
28 | for i, p := range parts { | 28 | for i, p := range parts { |
29 | num := StringToInt64(p) | 29 | num := StringToInt64(p) |
30 | arr[i] = num | 30 | arr[i] = num |
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
34 | return arr | 34 | return arr |
35 | } | 35 | } |
36 | 36 | ||
37 | // Int64SliceToString ... | 37 | // Int64SliceToString ... |
38 | func Int64SliceToString(arr []int64) (s string) { | 38 | func Int64SliceToString(arr []int64) (s string) { |
39 | if len(arr) == 0 { | 39 | if len(arr) == 0 { |
40 | return "" | 40 | return "" |
41 | } | 41 | } |
42 | 42 | ||
43 | s += fmt.Sprintf("%d", arr[0]) | 43 | s += fmt.Sprintf("%d", arr[0]) |
44 | for i := 1; i < len(arr); i++ { | 44 | for i := 1; i < len(arr); i++ { |
45 | s += fmt.Sprintf(",%d", arr[i]) | 45 | s += fmt.Sprintf(",%d", arr[i]) |
46 | } | 46 | } |
47 | 47 | ||
48 | return s | 48 | return s |
49 | } | 49 | } |
50 | 50 | ||
51 | // CombineStrings ... | 51 | // CombineStrings ... |
52 | func CombineStrings(s1, s2, s3 string) string { | 52 | func CombineStrings(s1, s2, s3 string) string { |
53 | s1 = strings.TrimSpace(s1) | 53 | s1 = strings.TrimSpace(s1) |
54 | s2 = strings.TrimSpace(s2) | 54 | s2 = strings.TrimSpace(s2) |
55 | 55 | ||
56 | if s1 != "" && s2 != "" { | 56 | if s1 != "" && s2 != "" { |
57 | s1 += s3 + s2 | 57 | s1 += s3 + s2 |
58 | } else { | 58 | } else { |
59 | s1 += s2 | 59 | s1 += s2 |
60 | } | 60 | } |
61 | 61 | ||
62 | return s1 | 62 | return s1 |
63 | } | 63 | } |
64 | 64 | ||
65 | // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string. | 65 | // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string. |
66 | func ReplaceAny(s, patern, r string) (n string) { | 66 | func ReplaceAny(s, patern, r string) (n string) { |
67 | n = s | 67 | n = s |
68 | for _, c := range patern { | 68 | for _, c := range patern { |
69 | n = strings.Replace(n, string(c), r, -1) | 69 | n = strings.Replace(n, string(c), r, -1) |
70 | } | 70 | } |
71 | return n | 71 | return n |
72 | } | 72 | } |
73 | 73 | ||
74 | // StringToBool ... | 74 | // StringToBool ... |
75 | func StringToBool(s string) bool { | 75 | func StringToBool(s string) bool { |
76 | res, _ := strconv.ParseBool(s) | 76 | res, _ := strconv.ParseBool(s) |
77 | return res | 77 | return res |
78 | } | 78 | } |
79 | 79 | ||
80 | // BoolToString ... | 80 | // BoolToString ... |
81 | func BoolToString(b bool) string { | 81 | func BoolToString(b bool) string { |
82 | return fmt.Sprintf("%b", b) | 82 | return fmt.Sprintf("%b", b) |
83 | } | 83 | } |
84 | 84 | ||
85 | // StringSliceContains ... | 85 | // StringSliceContains ... |
86 | func StringSliceContains(slice []string, s string) bool { | 86 | func StringSliceContains(slice []string, s string) bool { |
87 | for i := range slice { | 87 | for i := range slice { |
88 | if slice[i] == s { | 88 | if slice[i] == s { |
89 | return true | 89 | return true |
90 | } | 90 | } |
91 | } | 91 | } |
92 | return false | 92 | return false |
93 | } | 93 | } |
94 | 94 | ||
95 | func SplitString(s, sep string) (res []string) { | 95 | func SplitString(s, sep string) (res []string) { |
96 | parts := strings.Split(s, sep) | 96 | parts := strings.Split(s, sep) |
97 | for _, p := range parts { | 97 | for _, p := range parts { |
98 | if p != "" { | 98 | if p != "" { |
99 | res = append(res, p) | 99 | res = append(res, p) |
100 | } | 100 | } |
101 | } | 101 | } |
102 | return res | 102 | return res |
103 | } | 103 | } |
104 | 104 | ||
105 | // StringAt ... | 105 | // StringAt ... |
106 | func StringAt(s string, index int) string { | 106 | func StringAt(s string, index int) string { |
107 | if len(s)-1 < index || index < 0 { | 107 | if len(s)-1 < index || index < 0 { |
108 | return "" | 108 | return "" |
109 | } | 109 | } |
110 | 110 | ||
111 | return string(s[index]) | 111 | return string(s[index]) |
112 | } | 112 | } |
113 | 113 | ||
114 | // SplitText ... | 114 | // SplitText ... |
115 | func SplitText(s string, maxLen int) (lines []string) { | 115 | func SplitText(s string, maxLen int) (lines []string) { |
116 | runes := []rune(s) | 116 | runes := []rune(s) |
117 | 117 | ||
118 | i, start, sep, l := 0, 0, 0, 0 | 118 | i, start, sep, l := 0, 0, 0, 0 |
119 | for i = 0; i < len(runes); i++ { | 119 | for i = 0; i < len(runes); i++ { |
120 | c := runes[i] | 120 | c := runes[i] |
121 | 121 | ||
122 | if unicode.IsSpace(c) { | 122 | if unicode.IsSpace(c) { |
123 | sep = i | 123 | sep = i |
124 | } | 124 | } |
125 | 125 | ||
126 | if c == '\n' { | 126 | if c == '\n' { |
127 | if start != sep { | 127 | if start != sep { |
128 | lines = append(lines, string(runes[start:sep])) | 128 | lines = append(lines, string(runes[start:sep])) |
129 | } | 129 | } |
130 | start = i | 130 | start = i |
131 | sep = i | 131 | sep = i |
132 | l = 0 | 132 | l = 0 |
133 | } else if l >= maxLen { | 133 | } else if l >= maxLen { |
134 | if start != sep { | 134 | if start != sep { |
135 | lines = append(lines, string(runes[start:sep])) | 135 | lines = append(lines, string(runes[start:sep])) |
136 | sep = i | 136 | sep = i |
137 | start = i - 1 | 137 | start = i - 1 |
138 | l = 0 | 138 | l = 0 |
139 | } | 139 | } |
140 | } else { | 140 | } else { |
141 | l++ | 141 | l++ |
142 | } | 142 | } |
143 | } | 143 | } |
144 | if start != i-1 { | 144 | if start != i-1 { |
145 | lines = append(lines, string(runes[start:i-1])) | 145 | lines = append(lines, string(runes[start:i-1])) |
146 | } | 146 | } |
147 | 147 | ||
148 | return lines | 148 | return lines |
149 | } | 149 | } |
150 | 150 | ||
151 | func CutTextWithThreeDots(txt string, maxLen int) string { | ||
152 | if len(txt) < maxLen || len(txt) <= 3 { | ||
153 | return txt | ||
154 | } | ||
155 | |||
156 | return txt[:maxLen-3] + "..." | ||
157 | } | ||
158 | |||
151 | const threeDots = "\u2056\u2056\u2056" | 159 | const threeDots = "\u2056\u2056\u2056" |
152 | 160 | ||
153 | func LimitTextWithThreeDots(txt string, maxLen int) string { | 161 | func LimitTextWithThreeDots(txt string, maxLen int) string { |
154 | if len(txt) <= maxLen { | 162 | if len(txt) <= maxLen { |
155 | return txt | 163 | return txt |
156 | } | 164 | } |
157 | 165 | ||
158 | return txt[:maxLen] + threeDots | 166 | return txt[:maxLen] + threeDots |
159 | } | 167 | } |
160 | 168 | ||
169 | func LimitMSWordTextWithThreeDots(txt string, maxLen int) string { | ||
170 | if len(txt) <= maxLen { | ||
171 | return txt | ||
172 | } | ||
173 | |||
174 | return txt[:maxLen] + "..." | ||
175 | } | ||
176 | |||
161 | // SplitStringAtWholeWords ... | 177 | // SplitStringAtWholeWords ... |
162 | func SplitStringAtWholeWords(s string, maxLen int) (res []string) { | 178 | func SplitStringAtWholeWords(s string, maxLen int) (res []string) { |
163 | parts := strings.Split(s, " ") | 179 | parts := strings.Split(s, " ") |
164 | 180 | ||
165 | res = append(res, parts[0]) | 181 | res = append(res, parts[0]) |
166 | i := 0 | 182 | i := 0 |
167 | for j := 1; j < len(parts); j++ { | 183 | for j := 1; j < len(parts); j++ { |
168 | p := strings.TrimSpace(parts[j]) | 184 | p := strings.TrimSpace(parts[j]) |
169 | if len(p) > maxLen { | 185 | if len(p) > maxLen { |
170 | // TODO(marko): check if maxLen is >= 3 | 186 | // TODO(marko): check if maxLen is >= 3 |
171 | p = p[0 : maxLen-3] | 187 | p = p[0 : maxLen-3] |
172 | p += "..." | 188 | p += "..." |
173 | } | 189 | } |
174 | if len(res[i])+len(p)+1 <= maxLen { | 190 | if len(res[i])+len(p)+1 <= maxLen { |
175 | res[i] += " " + p | 191 | res[i] += " " + p |
176 | } else { | 192 | } else { |
177 | res = append(res, p) | 193 | res = append(res, p) |
178 | i++ | 194 | i++ |
179 | } | 195 | } |
180 | } | 196 | } |
181 | 197 | ||
182 | return res | 198 | return res |
183 | } | 199 | } |
184 | 200 |
timer.go
File was created | 1 | package webutility | |
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "time" | ||
6 | ) | ||
7 | |||
8 | // Timer ... | ||
9 | type Timer struct { | ||
10 | name string | ||
11 | running bool | ||
12 | started time.Time | ||
13 | stopped time.Time | ||
14 | lastDuration time.Duration | ||
15 | } | ||
16 | |||
17 | // NewTimer ... | ||
18 | func NewTimer(name string) *Timer { | ||
19 | t := &Timer{name: name} | ||
20 | t.Reset() | ||
21 | return t | ||
22 | } | ||
23 | |||
24 | // Start ... | ||
25 | func (t *Timer) Start() time.Time { | ||
26 | t.running = true | ||
27 | t.started = time.Now() | ||
28 | return t.started | ||
29 | } | ||
30 | |||
31 | // Stop ... | ||
32 | func (t *Timer) Stop() time.Duration { | ||
33 | t.running = false | ||
34 | t.stopped = time.Now() | ||
35 | t.lastDuration = t.stopped.Sub(t.started) | ||
36 | return t.lastDuration | ||
37 | } | ||
38 | |||
39 | // LastRunDuration ... | ||
40 | func (t *Timer) LastRunDuration() time.Duration { | ||
41 | return t.lastDuration | ||
42 | } | ||
43 | |||
44 | // Clear ... | ||
45 | func (t *Timer) Clear() { | ||
46 | t.started = time.Now() | ||
47 | t.stopped = time.Now() | ||
48 | t.lastDuration = 0 | ||
49 | } | ||
50 | |||
51 | // Reset ... | ||
52 | func (t *Timer) Reset() { | ||
53 | t.Stop() | ||
54 | t.Start() | ||
55 | } | ||
56 | |||
57 | // Elapsed ... | ||
58 | func (t *Timer) Elapsed() time.Duration { | ||
59 | if t.running { | ||
60 | return time.Now().Sub(t.started) | ||
61 | } | ||
62 | return 0 | ||
63 | } | ||
64 | |||
65 | // Print ... | ||
66 | func (t *Timer) Print(s string) { | ||
67 | status := "RUNNING" | ||
68 | if !t.running { | ||
69 | status = "STOPPED" | ||
70 | } | ||
71 | fmt.Printf("timer[%s][%s]: %v %s\n", t.name, status, t.Elapsed(), s) | ||
72 | } | ||
73 | |||
74 | // Lap ... | ||
75 | func (t *Timer) Lap(s string) { | ||
76 | t.Print(s) | ||
77 | t.Reset() | ||
78 | } | ||
79 |