github.com/sandwich-go/boost@v1.3.29/xstrings/camel_case.go (about) 1 package xstrings 2 3 import "strings" 4 5 // IsASCIILower Is c an ASCII lower-case letter? 6 func IsASCIILower(c byte) bool { 7 return 'a' <= c && c <= 'z' 8 } 9 10 // IsASCIIDigit Is c an ASCII digit? 11 func IsASCIIDigit(c byte) bool { 12 return '0' <= c && c <= '9' 13 } 14 15 // CamelCase returns the CamelCased name. 16 // If there is an interior underscore followed by a lower case letter, 17 // drop the underscore and convert the letter to upper case. 18 // There is a remote possibility of this rewrite causing a name collision, 19 // but it's so remote we're prepared to pretend it's nonexistent - since the 20 // C++ generator lowercases names, it's extremely unlikely to have two fields 21 // with different capitalizations. 22 // In short, _my_field_name_2 becomes XMyFieldName_2. 23 func CamelCase(s string) string { 24 if s == "" { 25 return "" 26 } 27 t := make([]byte, 0, 32) 28 i := 0 29 if s[0] == '_' { 30 // Need a capital letter; drop the '_'. 31 t = append(t, 'X') 32 i++ 33 } 34 // Invariant: if the next letter is lower case, it must be converted 35 // to upper case. 36 // That is, we process a word at a time, where words are marked by _ or 37 // upper case letter. Digits are treated as words. 38 for ; i < len(s); i++ { 39 c := s[i] 40 if c == '_' && i+1 < len(s) && IsASCIILower(s[i+1]) { 41 continue // Skip the underscore in s. 42 } 43 if IsASCIIDigit(c) { 44 t = append(t, c) 45 continue 46 } 47 // Assume we have a letter now - if not, it's a bogus identifier. 48 // The next word is a sequence of characters that must start upper case. 49 if IsASCIILower(c) { 50 c ^= ' ' // Make it a capital letter. 51 } 52 t = append(t, c) // Guaranteed not lower case. 53 // Accept lower case sequence that follows. 54 for i+1 < len(s) && IsASCIILower(s[i+1]) { 55 i++ 56 t = append(t, s[i]) 57 } 58 } 59 return string(t) 60 } 61 62 // CamelCaseSlice is like CamelCase, but the argument is a slice of strings to 63 // be joined with "_". 64 func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) }