mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-07-19 03:54:11 -04:00
The goutil that OpenCloud currently uses is one version from the release that adds FreeBSD support, this now compiles successfully on FreeBSD.
414 lines
11 KiB
Go
414 lines
11 KiB
Go
package strutil
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"unsafe"
|
|
|
|
"github.com/gookit/goutil/internal/comfunc"
|
|
"github.com/gookit/goutil/mathutil"
|
|
)
|
|
|
|
var (
|
|
// ErrDateLayout error
|
|
ErrDateLayout = errors.New("invalid date layout string")
|
|
// ErrInvalidParam error
|
|
ErrInvalidParam = errors.New("invalid input for parse time")
|
|
|
|
// some regex for convert string.
|
|
toSnakeReg = regexp.MustCompile("[A-Z][a-z]")
|
|
toCamelRegs = map[string]*regexp.Regexp{
|
|
" ": regexp.MustCompile(" +[a-zA-Z]"),
|
|
"-": regexp.MustCompile("-+[a-zA-Z]"),
|
|
"_": regexp.MustCompile("_+[a-zA-Z]"),
|
|
}
|
|
)
|
|
|
|
// Internal func refers:
|
|
// strconv.QuoteRune()
|
|
// strconv.QuoteToASCII()
|
|
// strconv.AppendQuote()
|
|
// strconv.AppendQuoteRune()
|
|
|
|
// Quote alias of strings.Quote
|
|
func Quote(s string) string { return strconv.Quote(s) }
|
|
|
|
// Unquote remove start and end quotes by single-quote or double-quote
|
|
//
|
|
// tip: strconv.Unquote cannot unquote single-quote
|
|
func Unquote(s string) string {
|
|
ln := len(s)
|
|
if ln < 2 {
|
|
return s
|
|
}
|
|
|
|
qs, qe := s[0], s[ln-1]
|
|
|
|
var valid bool
|
|
if qs == '"' && qe == '"' {
|
|
valid = true
|
|
} else if qs == '\'' && qe == '\'' {
|
|
valid = true
|
|
}
|
|
|
|
if valid {
|
|
s = s[1 : ln-1] // exclude quotes
|
|
}
|
|
// strconv.Unquote cannot unquote single-quote
|
|
// if ns, err := strconv.Unquote(s); err == nil {
|
|
// return ns
|
|
// }
|
|
return s
|
|
}
|
|
|
|
// Join alias of strings.Join
|
|
func Join(sep string, ss ...string) string { return strings.Join(ss, sep) }
|
|
|
|
// JoinList alias of strings.Join
|
|
func JoinList(sep string, ss []string) string { return strings.Join(ss, sep) }
|
|
|
|
// JoinComma quick join strings by comma
|
|
func JoinComma(ss []string) string { return strings.Join(ss, ",") }
|
|
|
|
// JoinAny type to string
|
|
func JoinAny(sep string, parts ...any) string {
|
|
ss := make([]string, 0, len(parts))
|
|
for _, part := range parts {
|
|
ss = append(ss, QuietString(part))
|
|
}
|
|
|
|
return strings.Join(ss, sep)
|
|
}
|
|
|
|
// Implode alias of strings.Join
|
|
func Implode(sep string, ss ...string) string { return strings.Join(ss, sep) }
|
|
|
|
/*************************************************************
|
|
* region value to string
|
|
*************************************************************/
|
|
|
|
// String convert value to string, return error on failed
|
|
func String(val any) (string, error) { return ToStringWith(val) }
|
|
|
|
// ToString convert value to string, return error on failed
|
|
func ToString(val any) (string, error) { return ToStringWith(val) }
|
|
|
|
// StringOrErr convert value to string, return error on failed
|
|
func StringOrErr(val any) (string, error) { return ToStringWith(val) }
|
|
|
|
// QuietString convert value to string, will ignore error. same as SafeString()
|
|
func QuietString(val any) string { return SafeString(val) }
|
|
|
|
// SafeString convert value to string. Will ignore error
|
|
func SafeString(in any) string {
|
|
s, _ := AnyToString(in, false)
|
|
return s
|
|
}
|
|
|
|
// StringOrPanic convert value to string, will panic on error
|
|
func StringOrPanic(val any) string { return MustString(val) }
|
|
|
|
// MustString convert value to string. will panic on error
|
|
func MustString(val any) string {
|
|
s, err := ToStringWith(val)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return s
|
|
}
|
|
|
|
// StringOrDefault convert any value to string, return default value on failed
|
|
func StringOrDefault(val any, defVal string) string { return StringOr(val, defVal) }
|
|
|
|
// StringOr convert any value to string, return default value on failed
|
|
func StringOr(val any, defVal string) string {
|
|
s, err := ToStringWith(val)
|
|
if err != nil {
|
|
return defVal
|
|
}
|
|
return s
|
|
}
|
|
|
|
// AnyToString convert any value to string.
|
|
//
|
|
// For defaultAsErr:
|
|
//
|
|
// - False will use fmt.Sprint convert unsupported type
|
|
// - True will return error on convert fail.
|
|
func AnyToString(val any, defaultAsErr bool) (s string, err error) {
|
|
var optFn comfunc.ConvOptionFn
|
|
if !defaultAsErr {
|
|
optFn = comfunc.WithUserConvFn(comfunc.StrBySprintFn)
|
|
}
|
|
return comfunc.ToStringWith(val, optFn)
|
|
}
|
|
|
|
// ToStringWith try to convert value to string. can with some option func, more see comfunc.ConvOption.
|
|
func ToStringWith(in any, optFns ...comfunc.ConvOptionFn) (string, error) {
|
|
return comfunc.ToStringWith(in, optFns...)
|
|
}
|
|
|
|
/*************************************************************
|
|
* region string value to bool
|
|
*************************************************************/
|
|
|
|
// ToBool convert string to bool
|
|
func ToBool(s string) (bool, error) {
|
|
return comfunc.StrToBool(strings.TrimSpace(s))
|
|
}
|
|
|
|
// QuietBool convert to bool, will ignore error
|
|
func QuietBool(s string) bool { return SafeBool(s) }
|
|
|
|
// SafeBool convert to bool and will ignore error
|
|
func SafeBool(s string) bool {
|
|
val, _ := comfunc.StrToBool(strings.TrimSpace(s))
|
|
return val
|
|
}
|
|
|
|
// MustBool convert to bool and will panic on error
|
|
func MustBool(s string) bool {
|
|
val, err := ToBool(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return val
|
|
}
|
|
|
|
// Bool parse string to bool. like strconv.ParseBool()
|
|
func Bool(s string) (bool, error) {
|
|
return comfunc.StrToBool(strings.TrimSpace(s))
|
|
}
|
|
|
|
/*************************************************************
|
|
* region string value to int
|
|
*************************************************************/
|
|
|
|
// Int convert string to int, alias of ToInt()
|
|
func Int(s string) (int, error) {
|
|
return strconv.Atoi(strings.TrimSpace(s))
|
|
}
|
|
|
|
// ToInt convert string to int, return error on fail
|
|
func ToInt(s string) (int, error) {
|
|
return strconv.Atoi(strings.TrimSpace(s))
|
|
}
|
|
|
|
// IntOrDefault convert string to int, return default value on fail
|
|
func IntOrDefault(s string, defVal int) int {
|
|
return IntOr(s, defVal)
|
|
}
|
|
|
|
// IntOr convert string to int, return default value on fail
|
|
func IntOr(s string, defVal int) int {
|
|
val, err := ToInt(s)
|
|
if err != nil {
|
|
return defVal
|
|
}
|
|
return val
|
|
}
|
|
|
|
// SafeInt convert string to int, will ignore error
|
|
func SafeInt(s string) int {
|
|
val, _ := ToInt(s)
|
|
return val
|
|
}
|
|
|
|
// QuietInt convert string to int, will ignore error
|
|
func QuietInt(s string) int { return SafeInt(s) }
|
|
|
|
// MustInt convert string to int, will panic on error
|
|
func MustInt(s string) int { return IntOrPanic(s) }
|
|
|
|
// IntOrPanic convert value to int, will panic on error
|
|
func IntOrPanic(s string) int {
|
|
val, err := ToInt(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return val
|
|
}
|
|
|
|
/*************************************************************
|
|
* region convert string to int64
|
|
*************************************************************/
|
|
|
|
// Int64 convert string to int, will ignore error
|
|
func Int64(s string) int64 { return SafeInt64(s) }
|
|
|
|
// QuietInt64 convert string to int, will ignore error
|
|
func QuietInt64(s string) int64 { return SafeInt64(s) }
|
|
|
|
// SafeInt64 convert string to int, will ignore error
|
|
func SafeInt64(s string) int64 {
|
|
val, _ := Int64OrErr(s)
|
|
return val
|
|
}
|
|
|
|
// ToInt64 convert string to int, return error on fail
|
|
func ToInt64(s string) (int64, error) {
|
|
return strconv.ParseInt(s, 10, 0)
|
|
}
|
|
|
|
// Int64OrDefault convert string to int, return default value on fail
|
|
func Int64OrDefault(s string, defVal int64) int64 {
|
|
return Int64Or(s, defVal)
|
|
}
|
|
|
|
// Int64Or convert string to int, return default value on fail
|
|
func Int64Or(s string, defVal int64) int64 {
|
|
val, err := ToInt64(s)
|
|
if err != nil {
|
|
return defVal
|
|
}
|
|
return val
|
|
}
|
|
|
|
// Int64OrErr convert string to int, return error on fail
|
|
func Int64OrErr(s string) (int64, error) {
|
|
return strconv.ParseInt(s, 10, 0)
|
|
}
|
|
|
|
// MustInt64 convert value to int, will panic on error
|
|
func MustInt64(s string) int64 { return Int64OrPanic(s) }
|
|
|
|
// Int64OrPanic convert value to int, will panic on error
|
|
func Int64OrPanic(s string) int64 {
|
|
val, err := strconv.ParseInt(s, 10, 0)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return val
|
|
}
|
|
|
|
/*************************************************************
|
|
* region string value to uint
|
|
*************************************************************/
|
|
|
|
// Uint convert string to uint, will ignore error
|
|
func Uint(s string) uint64 { return SafeUint(s) }
|
|
|
|
// SafeUint convert string to uint, will ignore error
|
|
func SafeUint(s string) uint64 {
|
|
val, _ := UintOrErr(s)
|
|
return val
|
|
}
|
|
|
|
// ToUint convert string to uint, return error on fail. alias of UintOrErr()
|
|
func ToUint(s string) (uint64, error) {
|
|
return strconv.ParseUint(s, 10, 0)
|
|
}
|
|
|
|
// UintOrErr convert string to uint, return error on fail
|
|
func UintOrErr(s string) (uint64, error) {
|
|
return strconv.ParseUint(s, 10, 0)
|
|
}
|
|
|
|
// MustUint convert value to uint, will panic on error. alias of UintOrPanic()
|
|
func MustUint(s string) uint64 { return UintOrPanic(s) }
|
|
|
|
// UintOrPanic convert value to uint, will panic on error
|
|
func UintOrPanic(s string) uint64 {
|
|
val, err := UintOrErr(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return val
|
|
}
|
|
|
|
// UintOrDefault convert string to uint, return default value on fail
|
|
func UintOrDefault(s string, defVal uint64) uint64 {
|
|
return UintOr(s, defVal)
|
|
}
|
|
|
|
// UintOr convert string to uint, return default value on fail
|
|
func UintOr(s string, defVal uint64) uint64 {
|
|
val, err := UintOrErr(s)
|
|
if err != nil {
|
|
return defVal
|
|
}
|
|
return val
|
|
}
|
|
|
|
/*************************************************************
|
|
* region string value to byte
|
|
* refer from https://github.com/valyala/fastjson/blob/master/util.go
|
|
*************************************************************/
|
|
|
|
// Byte2str convert bytes to string
|
|
func Byte2str(b []byte) string {
|
|
return *(*string)(unsafe.Pointer(&b))
|
|
}
|
|
|
|
// Byte2string convert bytes to string
|
|
func Byte2string(b []byte) string {
|
|
return *(*string)(unsafe.Pointer(&b))
|
|
}
|
|
|
|
// ToBytes convert string to bytes
|
|
func ToBytes(s string) (b []byte) {
|
|
strh := (*reflect.StringHeader)(unsafe.Pointer(&s))
|
|
|
|
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
|
sh.Data = strh.Data
|
|
sh.Len = strh.Len
|
|
sh.Cap = strh.Len
|
|
return b
|
|
}
|
|
|
|
/*************************************************************
|
|
* region string to int/string slice, time.Time
|
|
*************************************************************/
|
|
|
|
// Ints alias of the ToIntSlice(). default sep is comma(,)
|
|
func Ints(s string, sep ...string) []int {
|
|
ints, _ := ToIntSlice(s, sep...)
|
|
return ints
|
|
}
|
|
|
|
// ToInts alias of the ToIntSlice(). default sep is comma(,)
|
|
func ToInts(s string, sep ...string) ([]int, error) { return ToIntSlice(s, sep...) }
|
|
|
|
// ToIntSlice split string to slice and convert item to int.
|
|
//
|
|
// Default sep is comma
|
|
func ToIntSlice(s string, sep ...string) (ints []int, err error) {
|
|
ss := ToSlice(s, sep...)
|
|
for _, item := range ss {
|
|
iVal, err := mathutil.ToInt(item)
|
|
if err != nil {
|
|
return []int{}, err
|
|
}
|
|
|
|
ints = append(ints, iVal)
|
|
}
|
|
return
|
|
}
|
|
|
|
// ToArray alias of the ToSlice()
|
|
func ToArray(s string, sep ...string) []string { return ToSlice(s, sep...) }
|
|
|
|
// Strings alias of the ToSlice()
|
|
func Strings(s string, sep ...string) []string { return ToSlice(s, sep...) }
|
|
|
|
// ToStrings alias of the ToSlice()
|
|
func ToStrings(s string, sep ...string) []string { return ToSlice(s, sep...) }
|
|
|
|
// ToSlice split string to array.
|
|
func ToSlice(s string, sep ...string) []string {
|
|
if len(sep) > 0 {
|
|
return Split(s, sep[0])
|
|
}
|
|
return Split(s, ",")
|
|
}
|
|
|
|
// ToDuration parses a duration string. such as "300ms", "-1.5h" or "2h45m".
|
|
// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
|
func ToDuration(s string) (time.Duration, error) {
|
|
return comfunc.ToDuration(s)
|
|
}
|