...
1
2
3
4
5
6 package strs
7
8 import (
9 "go/token"
10 "strings"
11 "unicode"
12 "unicode/utf8"
13
14 "google.golang.org/protobuf/internal/flags"
15 "google.golang.org/protobuf/reflect/protoreflect"
16 )
17
18
19 func EnforceUTF8(fd protoreflect.FieldDescriptor) bool {
20 if flags.ProtoLegacy {
21 if fd, ok := fd.(interface{ EnforceUTF8() bool }); ok {
22 return fd.EnforceUTF8()
23 }
24 }
25 return fd.Syntax() == protoreflect.Proto3
26 }
27
28
29
30
31
32 func GoCamelCase(s string) string {
33
34
35
36
37 var b []byte
38 for i := 0; i < len(s); i++ {
39 c := s[i]
40 switch {
41 case c == '.' && i+1 < len(s) && isASCIILower(s[i+1]):
42
43 case c == '.':
44 b = append(b, '_')
45 case c == '_' && (i == 0 || s[i-1] == '.'):
46
47
48 b = append(b, 'X')
49 case c == '_' && i+1 < len(s) && isASCIILower(s[i+1]):
50
51 case isASCIIDigit(c):
52 b = append(b, c)
53 default:
54
55
56 if isASCIILower(c) {
57 c -= 'a' - 'A'
58 }
59 b = append(b, c)
60
61
62 for ; i+1 < len(s) && isASCIILower(s[i+1]); i++ {
63 b = append(b, s[i+1])
64 }
65 }
66 }
67 return string(b)
68 }
69
70
71 func GoSanitized(s string) string {
72
73
74 s = strings.Map(func(r rune) rune {
75 if unicode.IsLetter(r) || unicode.IsDigit(r) {
76 return r
77 }
78 return '_'
79 }, s)
80
81
82
83 r, _ := utf8.DecodeRuneInString(s)
84 if token.Lookup(s).IsKeyword() || !unicode.IsLetter(r) {
85 return "_" + s
86 }
87 return s
88 }
89
90
91
92 func JSONCamelCase(s string) string {
93 var b []byte
94 var wasUnderscore bool
95 for i := 0; i < len(s); i++ {
96 c := s[i]
97 if c != '_' {
98 if wasUnderscore && isASCIILower(c) {
99 c -= 'a' - 'A'
100 }
101 b = append(b, c)
102 }
103 wasUnderscore = c == '_'
104 }
105 return string(b)
106 }
107
108
109
110 func JSONSnakeCase(s string) string {
111 var b []byte
112 for i := 0; i < len(s); i++ {
113 c := s[i]
114 if isASCIIUpper(c) {
115 b = append(b, '_')
116 c += 'a' - 'A'
117 }
118 b = append(b, c)
119 }
120 return string(b)
121 }
122
123
124
125 func MapEntryName(s string) string {
126 var b []byte
127 upperNext := true
128 for _, c := range s {
129 switch {
130 case c == '_':
131 upperNext = true
132 case upperNext:
133 b = append(b, byte(unicode.ToUpper(c)))
134 upperNext = false
135 default:
136 b = append(b, byte(c))
137 }
138 }
139 b = append(b, "Entry"...)
140 return string(b)
141 }
142
143
144
145 func EnumValueName(s string) string {
146 var b []byte
147 upperNext := true
148 for _, c := range s {
149 switch {
150 case c == '_':
151 upperNext = true
152 case upperNext:
153 b = append(b, byte(unicode.ToUpper(c)))
154 upperNext = false
155 default:
156 b = append(b, byte(unicode.ToLower(c)))
157 upperNext = false
158 }
159 }
160 return string(b)
161 }
162
163
164
165
166 func TrimEnumPrefix(s, prefix string) string {
167 s0 := s
168 for len(s) > 0 && len(prefix) > 0 {
169 if s[0] == '_' {
170 s = s[1:]
171 continue
172 }
173 if unicode.ToLower(rune(s[0])) != rune(prefix[0]) {
174 return s0
175 }
176 s, prefix = s[1:], prefix[1:]
177 }
178 if len(prefix) > 0 {
179 return s0
180 }
181 s = strings.TrimLeft(s, "_")
182 if len(s) == 0 {
183 return s0
184 }
185 return s
186 }
187
188 func isASCIILower(c byte) bool {
189 return 'a' <= c && c <= 'z'
190 }
191 func isASCIIUpper(c byte) bool {
192 return 'A' <= c && c <= 'Z'
193 }
194 func isASCIIDigit(c byte) bool {
195 return '0' <= c && c <= '9'
196 }
197
View as plain text