| package vdlutil |
| |
| import ( |
| "bytes" |
| "unicode" |
| "unicode/utf8" |
| ) |
| |
| // ToCamelCase converts ThisString to thisString. |
| // TODO(toddw): Remove this function, replace calls with FirstRuneToLower. |
| func ToCamelCase(s string) string { |
| return FirstRuneToLower(s) |
| } |
| |
| // FirstRuneToLower returns s with its first rune in lowercase. |
| func FirstRuneToLower(s string) string { |
| if s == "" { |
| return "" |
| } |
| r, n := utf8.DecodeRuneInString(s) |
| return string(unicode.ToLower(r)) + s[n:] |
| } |
| |
| // FirstRuneToUpper returns s with its first rune in uppercase. |
| func FirstRuneToUpper(s string) string { |
| if s == "" { |
| return "" |
| } |
| r, n := utf8.DecodeRuneInString(s) |
| return string(unicode.ToUpper(r)) + s[n:] |
| } |
| |
| // FirstRuneToExportCase returns s with its first rune in uppercase if export is |
| // true, otherwise in lowercase. |
| func FirstRuneToExportCase(s string, export bool) string { |
| if export { |
| return FirstRuneToUpper(s) |
| } |
| return FirstRuneToLower(s) |
| } |
| |
| // toConstCase converts ThisString to THIS_STRING. For adding '_', we follow the |
| // following algorithm. For any sequence of three characters, c[n-1], c[n], |
| // c[n+1], we add an underscore before c[n] if: |
| // 1) c[n-1] is a digit and c[n] is a letter, or |
| // 2) c[n-1] is a letter and c[n] is a digit, or |
| // 3) c[n-1] is lowercase, and c[n] is uppercase, or |
| // 4) c[n-1] is uppercase, c[n] is uppercase, and c[n+1] is lowercase. |
| func ToConstCase(s string) string { |
| var buf bytes.Buffer |
| var size int |
| var prev, cur, next rune |
| next, size = utf8.DecodeRuneInString(s) |
| for next != utf8.RuneError { |
| s = s[size:] |
| prev, cur = cur, next |
| next, size = utf8.DecodeRuneInString(s) |
| // We avoid checking boundary conditions because, for a rune r that is zero or utf8.RuneError: |
| // unicode.Is{Letter,Digit,Lower,Upper}(r) == false |
| if unicode.IsDigit(prev) && unicode.IsLetter(cur) || // Rule (1) |
| unicode.IsLetter(prev) && unicode.IsDigit(cur) || // Rule (2) |
| unicode.IsLower(prev) && unicode.IsUpper(cur) || // Rule (3) |
| unicode.IsUpper(prev) && unicode.IsUpper(cur) && unicode.IsLower(next) { // Rule (4) |
| buf.WriteRune('_') |
| } |
| buf.WriteRune(unicode.ToUpper(cur)) |
| } |
| return buf.String() |
| } |