blob: 1145857c2751f06e7bac8b93bc77096e60e7865e [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package vdlutil implements utilities used by many VDL components. It should
// have a small set of dependencies.
package vdlutil
import (
"bytes"
"unicode"
"unicode/utf8"
)
// 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()
}