-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.go
More file actions
215 lines (182 loc) · 3.88 KB
/
utils.go
File metadata and controls
215 lines (182 loc) · 3.88 KB
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
package gogenutils
import (
"regexp"
"strings"
"unicode"
)
var (
fieldNameRE = regexp.MustCompile("[^A-Za-z0-9]+")
jsonFieldNameRE = regexp.MustCompile("[^a-z0-9_]+|_$")
)
// FieldName returns a go struct field name from a text string
func FieldName(s string) string {
s = PascalCase(s)
s = fieldNameRE.ReplaceAllString(s, "")
return s
}
// JSONFieldName returns the lowercase, underscore se
func JSONFieldName(s string) string {
s = SnakeCase(s)
s = jsonFieldNameRE.ReplaceAllString(s, "")
s = strings.Replace(s, "__", "_", -1)
// Strip excess
return s
}
// CamelCase returns the camelCase version of a text string
func CamelCase(s string) string {
return camelAndPascalCase(s, true)
}
// PascalCase returns the PascalCase version of a text string
func PascalCase(s string) string {
return camelAndPascalCase(s, false)
}
func camelAndPascalCase(s string, isCamel bool) string {
var (
prev = ' '
isFirst = true
)
s = strings.Map(
func(r rune) rune {
defer func() {
prev = r
}()
if isFirst {
isFirst = false
if isCamel {
return unicode.ToLower(r)
} else {
return unicode.ToTitle(r)
}
}
if isSeparator(prev) {
return unicode.ToTitle(r)
}
return r
},
s)
s = strings.Replace(s, " ", "", -1)
s = strings.Replace(s, "_", "", -1)
return s
}
// SnakeCase returns the snake_case version of a text string
func SnakeCase(s string) string {
return strings.Map(
func(r rune) rune {
if isSeparator(r) {
return '_'
}
return unicode.ToLower(r)
},
s)
}
func isSeparator(r rune) bool {
return !unicode.IsLetter(r) && !unicode.IsNumber(r)
}
// PascalCaseToSnakeCase converts from PascalCase to snake_case
func PascalCaseToSnakeCase(s string) string {
var result string
var words []string
var lastPos int
rs := []rune(s)
for i := 0; i < len(rs); i++ {
if i > 0 && isWordBreak(rs, i) {
// Scan ahead looking for an initialism
if initialism := startsWithInitialism(s[lastPos:]); initialism != "" {
words = append(words, initialism)
// Move the pointer fowards
i += len(initialism) - 1
lastPos = i
continue
}
// Not an initialism, so break the previous word
words = append(words, s[lastPos:i])
lastPos = i
}
}
// append the last word
if s[lastPos:] != "" {
words = append(words, s[lastPos:])
}
for k, word := range words {
if k > 0 {
result += "_"
}
result += strings.ToLower(word)
}
return result
}
func isWordBreak(rs []rune, i int) bool {
if unicode.IsUpper(rs[i]) {
return true
}
if (i == 0 || !unicode.IsDigit(rs[i-1])) && unicode.IsDigit(rs[i]) {
return true
}
return false
}
// startsWithInitialism returns the initialism if the given string begins with it
func startsWithInitialism(s string) string {
// the longest initialism is 5 char, the shortest 2
for i := 5; i > 0; i-- {
if len(s) >= i && commonInitialisms[s[:i]] {
return s[:i]
}
}
// Is this probably an initialism?
rs := []rune(s)
var end int
for end = 0; end < 5; end++ {
if len(rs) <= end {
break
}
if !isWordBreak(rs, end) {
break
}
}
if end > 2 {
return string(rs[:end-1])
}
return ""
}
// commonInitialisms, taken from
// https://github.com/golang/lint/blob/206c0f020eba0f7fbcfbc467a5eb808037df2ed6/lint.go#L731
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}