blob: 64eb4246267616a0cc53e02ed8060c9d63c53503 [file] [log] [blame]
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()
}