mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-02 21:23:20 -04:00
The goutil that OpenCloud currently uses is one version from the release that adds FreeBSD support, this now compiles successfully on FreeBSD.
237 lines
4.8 KiB
Go
237 lines
4.8 KiB
Go
package strutil
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
/*************************************************************
|
|
* change string case
|
|
*************************************************************/
|
|
|
|
// methods aliases
|
|
var (
|
|
UpWords = UpperWord
|
|
LoFirst = LowerFirst
|
|
UpFirst = UpperFirst
|
|
|
|
Snake = SnakeCase
|
|
)
|
|
|
|
// Title alias of the strings.ToTitle()
|
|
func Title(s string) string { return strings.ToTitle(s) }
|
|
|
|
// Lower alias of the strings.ToLower()
|
|
func Lower(s string) string { return strings.ToLower(s) }
|
|
|
|
// Lowercase alias of the strings.ToLower()
|
|
func Lowercase(s string) string { return strings.ToLower(s) }
|
|
|
|
// Upper alias of the strings.ToUpper()
|
|
func Upper(s string) string { return strings.ToUpper(s) }
|
|
|
|
// Uppercase alias of the strings.ToUpper()
|
|
func Uppercase(s string) string { return strings.ToUpper(s) }
|
|
|
|
// UpperWord Change the first character of each word to uppercase
|
|
func UpperWord(s string) string {
|
|
if len(s) == 0 {
|
|
return s
|
|
}
|
|
|
|
if len(s) == 1 {
|
|
return strings.ToUpper(s)
|
|
}
|
|
|
|
inWord := true
|
|
buf := make([]byte, 0, len(s))
|
|
|
|
i := 0
|
|
rs := []rune(s)
|
|
if RuneIsLower(rs[i]) {
|
|
buf = append(buf, []byte(string(unicode.ToUpper(rs[i])))...)
|
|
} else {
|
|
buf = append(buf, []byte(string(rs[i]))...)
|
|
}
|
|
|
|
for j := i + 1; j < len(rs); j++ {
|
|
if !RuneIsWord(rs[i]) && RuneIsWord(rs[j]) {
|
|
inWord = false
|
|
}
|
|
|
|
if RuneIsLower(rs[j]) && !inWord {
|
|
buf = append(buf, []byte(string(unicode.ToUpper(rs[j])))...)
|
|
inWord = true
|
|
} else {
|
|
buf = append(buf, []byte(string(rs[j]))...)
|
|
}
|
|
|
|
if RuneIsWord(rs[j]) {
|
|
inWord = true
|
|
}
|
|
|
|
i++
|
|
}
|
|
|
|
return string(buf)
|
|
}
|
|
|
|
// LowerFirst lower first char
|
|
func LowerFirst(s string) string {
|
|
if len(s) == 0 {
|
|
return s
|
|
}
|
|
|
|
rs := []rune(s)
|
|
f := rs[0]
|
|
|
|
if 'A' <= f && f <= 'Z' {
|
|
return string(unicode.ToLower(f)) + string(rs[1:])
|
|
}
|
|
return s
|
|
}
|
|
|
|
// UpperFirst upper first char
|
|
func UpperFirst(s string) string {
|
|
if len(s) == 0 {
|
|
return s
|
|
}
|
|
|
|
rs := []rune(s)
|
|
f := rs[0]
|
|
|
|
if 'a' <= f && f <= 'z' {
|
|
return string(unicode.ToUpper(f)) + string(rs[1:])
|
|
}
|
|
return s
|
|
}
|
|
|
|
// SnakeCase convert. eg "RangePrice" -> "range_price"
|
|
func SnakeCase(s string, sep ...string) string {
|
|
sepChar := "_"
|
|
if len(sep) > 0 {
|
|
sepChar = sep[0]
|
|
}
|
|
|
|
str := toSnakeReg.ReplaceAllStringFunc(s, func(s string) string {
|
|
return sepChar + LowerFirst(s)
|
|
})
|
|
|
|
return strings.TrimLeft(str, sepChar)
|
|
}
|
|
|
|
// Camel alias of the CamelCase
|
|
func Camel(s string, sep ...string) string { return CamelCase(s, sep...) }
|
|
|
|
// CamelCase convert string to camel case.
|
|
//
|
|
// Support:
|
|
//
|
|
// "range_price" -> "rangePrice"
|
|
// "range price" -> "rangePrice"
|
|
// "range-price" -> "rangePrice"
|
|
func CamelCase(s string, sep ...string) string {
|
|
sepChar := "_"
|
|
if len(sep) > 0 {
|
|
sepChar = sep[0]
|
|
}
|
|
|
|
// Not contains sep char
|
|
if !strings.Contains(s, sepChar) {
|
|
return s
|
|
}
|
|
|
|
// Get regexp instance
|
|
rgx, ok := toCamelRegs[sepChar]
|
|
if !ok {
|
|
rgx = regexp.MustCompile(regexp.QuoteMeta(sepChar) + "+[a-zA-Z]")
|
|
}
|
|
|
|
return rgx.ReplaceAllStringFunc(s, func(s string) string {
|
|
s = strings.TrimLeft(s, sepChar)
|
|
return UpperFirst(s)
|
|
})
|
|
}
|
|
|
|
//
|
|
// Indent format multi line text
|
|
// from package: github.com/kr/text
|
|
//
|
|
|
|
// Indent inserts prefix at the beginning of each non-empty line of s. The
|
|
// end-of-line marker is NL.
|
|
func Indent(s, prefix string) string {
|
|
return string(IndentBytes([]byte(s), []byte(prefix)))
|
|
}
|
|
|
|
// IndentBytes inserts prefix at the beginning of each non-empty line of b.
|
|
// The end-of-line marker is NL.
|
|
func IndentBytes(b, prefix []byte) []byte {
|
|
if len(b) == 0 {
|
|
return b
|
|
}
|
|
|
|
bol := true
|
|
res := make([]byte, 0, len(b)+len(prefix)*4)
|
|
|
|
for _, c := range b {
|
|
if bol && c != '\n' {
|
|
res = append(res, prefix...)
|
|
}
|
|
res = append(res, c)
|
|
bol = c == '\n'
|
|
}
|
|
return res
|
|
}
|
|
|
|
// Replaces replace multi strings
|
|
//
|
|
// pairs: {old1: new1, old2: new2, ...}
|
|
//
|
|
// Can also use:
|
|
//
|
|
// strings.NewReplacer("old1", "new1", "old2", "new2").Replace(str)
|
|
func Replaces(str string, pairs map[string]string) string {
|
|
return NewReplacer(pairs).Replace(str)
|
|
}
|
|
|
|
// ReplaceVars replaces simple variables in a string. format: {varName}
|
|
//
|
|
// Usage:
|
|
// strutil.ReplaceVars("{name}, age is {age}", map[string]string{
|
|
// "name": "Joe",
|
|
// "age": "18"
|
|
// })
|
|
func ReplaceVars(s string, vars map[string]string) string {
|
|
if !ContainsByte(s, '{') {
|
|
return s
|
|
}
|
|
|
|
// format var name to {name}
|
|
pairs := make(map[string]string)
|
|
for k, v := range vars {
|
|
vName := "{" + k + "}"
|
|
pairs[vName] = v
|
|
}
|
|
return NewReplacer(pairs).Replace(s)
|
|
}
|
|
|
|
// NewReplacer instance
|
|
func NewReplacer(pairs map[string]string) *strings.Replacer {
|
|
ss := make([]string, len(pairs)*2)
|
|
for old, newVal := range pairs {
|
|
ss = append(ss, old, newVal)
|
|
}
|
|
return strings.NewReplacer(ss...)
|
|
}
|
|
|
|
// WrapTag for given string.
|
|
func WrapTag(s, tag string) string {
|
|
if s == "" {
|
|
return s
|
|
}
|
|
return fmt.Sprintf("<%s>%s</%s>", tag, s, tag)
|
|
}
|