Files
opencloud/vendor/github.com/gookit/goutil/strutil/format.go
PC Kitty d97217f22c Update github.com/gookit/goutil to v0.7.4 for FreeBSD compatibility
The goutil that OpenCloud currently uses is one version from the release that adds FreeBSD support, this now compiles successfully on FreeBSD.
2026-04-28 18:03:17 +02:00

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)
}