Repository navigation
Expand file tree
/
Copy pathenvify.go
More file actions
72 lines (64 loc) · 1.87 KB
/
Copy pathenvify.go
File metadata and controls
72 lines (64 loc) · 1.87 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
package conf
import "unicode"
// envify returns the environment variable name for the flag named s.
//
// Effectively, envify calculates the SCREAMING_SNAKE_CASE rendition of s.
func envify(s string) string {
in := []rune(s)
var out []rune
// Scan for words, starting from the end. A reverse search is convenient
// here because it's easier to tell how to separate "JSONData" into
// "JSON_DATA" when working backwards.
//
// When searching forward, you have to look ahead to see if an upper is
// followed by a lower. When searching backward, you just have to allow a
// lower word to be terminated by an upper.
//
// This idea is copied from segmentio/conf's snakecase.go
i := len(in) - 1
for i >= 0 {
if unicode.IsLower(in[i]) {
// Scan for a sequence of lowers.
for i >= 0 && unicode.IsLower(in[i]) {
out = append(out, unicode.ToUpper(in[i]))
i--
}
// Insert the next letter, if it's an upper.
if i >= 0 && unicode.IsUpper(in[i]) {
out = append(out, in[i])
i--
}
// Separate this word from the next, unless the next char is already
// a separator.
if i >= 0 && !unicode.IsPunct(in[i]) {
out = append(out, '_')
}
} else if unicode.IsUpper(in[i]) {
// Scan for a sequence of uppers.
for i >= 0 && unicode.IsUpper(in[i]) {
out = append(out, in[i])
i--
}
// Separate this word from the next, unless the next char is already
// a separator.
if i >= 0 && !unicode.IsPunct(in[i]) {
out = append(out, '_')
}
} else if unicode.IsPunct(in[i]) {
// Replace this separator with an ASCII underscore.
out = append(out, '_')
i--
} else {
// Some non-letter, non-separator character. Just leave it as-is.
out = append(out, in[i])
i--
}
}
// Reverse out, since we did a backwards search.
for i, j := 0, len(out)-1; i < j; {
out[i], out[j] = out[j], out[i]
i++
j--
}
return string(out)
}