package strutil

import (
	
	
	
	
	
	
	

	
	
)

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 ( string) string { return strconv.Quote() }

// Unquote remove start and end quotes by single-quote or double-quote
//
// tip: strconv.Unquote cannot unquote single-quote
func ( string) string {
	 := len()
	if  < 2 {
		return 
	}

	,  := [0], [-1]

	var  bool
	if  == '"' &&  == '"' {
		 = true
	} else if  == '\'' &&  == '\'' {
		 = true
	}

	if  {
		 = [1 : -1] // exclude quotes
	}
	// strconv.Unquote cannot unquote single-quote
	// if ns, err := strconv.Unquote(s); err == nil {
	// 	return ns
	// }
	return 
}

// Join alias of strings.Join
func ( string,  ...string) string { return strings.Join(, ) }

// JoinList alias of strings.Join
func ( string,  []string) string { return strings.Join(, ) }

// JoinComma quick join strings by comma
func ( []string) string { return strings.Join(, ",") }

// JoinAny type to string
func ( string,  ...any) string {
	 := make([]string, 0, len())
	for ,  := range  {
		 = append(, QuietString())
	}

	return strings.Join(, )
}

// Implode alias of strings.Join
func ( string,  ...string) string { return strings.Join(, ) }

/*************************************************************
 * region value to string
 *************************************************************/

// String convert value to string, return error on failed
func ( any) (string, error) { return ToStringWith() }

// ToString convert value to string, return error on failed
func ( any) (string, error) { return ToStringWith() }

// StringOrErr convert value to string, return error on failed
func ( any) (string, error) { return ToStringWith() }

// QuietString convert value to string, will ignore error. same as SafeString()
func ( any) string { return SafeString() }

// SafeString convert value to string. Will ignore error
func ( any) string {
	,  := AnyToString(, false)
	return 
}

// StringOrPanic convert value to string, will panic on error
func ( any) string { return MustString() }

// MustString convert value to string. will panic on error
func ( any) string {
	,  := ToStringWith()
	if  != nil {
		panic()
	}
	return 
}

// StringOrDefault convert any value to string, return default value on failed
func ( any,  string) string { return StringOr(, ) }

// StringOr convert any value to string, return default value on failed
func ( any,  string) string {
	,  := ToStringWith()
	if  != nil {
		return 
	}
	return 
}

// AnyToString convert any value to string.
//
// For defaultAsErr:
//
//   - False  will use fmt.Sprint convert unsupported type
//   - True   will return error on convert fail.
func ( any,  bool) ( string,  error) {
	var  comfunc.ConvOptionFn
	if ! {
		 = comfunc.WithUserConvFn(comfunc.StrBySprintFn)
	}
	return comfunc.ToStringWith(, )
}

// ToStringWith try to convert value to string. can with some option func, more see comfunc.ConvOption.
func ( any,  ...comfunc.ConvOptionFn) (string, error) {
	return comfunc.ToStringWith(, ...)
}

/*************************************************************
 * region string value to bool
 *************************************************************/

// ToBool convert string to bool
func ( string) (bool, error) {
	return comfunc.StrToBool(strings.TrimSpace())
}

// QuietBool convert to bool, will ignore error
func ( string) bool { return SafeBool() }

// SafeBool convert to bool and will ignore error
func ( string) bool {
	,  := comfunc.StrToBool(strings.TrimSpace())
	return 
}

// MustBool convert to bool and will panic on error
func ( string) bool {
	,  := ToBool()
	if  != nil {
		panic()
	}
	return 
}

// Bool parse string to bool. like strconv.ParseBool()
func ( string) (bool, error) {
	return comfunc.StrToBool(strings.TrimSpace())
}

/*************************************************************
 * region string value to int
 *************************************************************/

// Int convert string to int, alias of ToInt()
func ( string) (int, error) {
	return strconv.Atoi(strings.TrimSpace())
}

// ToInt convert string to int, return error on fail
func ( string) (int, error) {
	return strconv.Atoi(strings.TrimSpace())
}

// IntOrDefault convert string to int, return default value on fail
func ( string,  int) int {
	return IntOr(, )
}

// IntOr convert string to int, return default value on fail
func ( string,  int) int {
	,  := ToInt()
	if  != nil {
		return 
	}
	return 
}

// SafeInt convert string to int, will ignore error
func ( string) int {
	,  := ToInt()
	return 
}

// QuietInt convert string to int, will ignore error
func ( string) int { return SafeInt() }

// MustInt convert string to int, will panic on error
func ( string) int { return IntOrPanic() }

// IntOrPanic convert value to int, will panic on error
func ( string) int {
	,  := ToInt()
	if  != nil {
		panic()
	}
	return 
}

/*************************************************************
 * region convert string to int64
 *************************************************************/

// Int64 convert string to int, will ignore error
func ( string) int64 { return SafeInt64() }

// QuietInt64 convert string to int, will ignore error
func ( string) int64 { return SafeInt64() }

// SafeInt64 convert string to int, will ignore error
func ( string) int64 {
	,  := Int64OrErr()
	return 
}

// ToInt64 convert string to int, return error on fail
func ( string) (int64, error) {
	return strconv.ParseInt(, 10, 0)
}

// Int64OrDefault convert string to int, return default value on fail
func ( string,  int64) int64 {
	return Int64Or(, )
}

// Int64Or convert string to int, return default value on fail
func ( string,  int64) int64 {
	,  := ToInt64()
	if  != nil {
		return 
	}
	return 
}

// Int64OrErr convert string to int, return error on fail
func ( string) (int64, error) {
	return strconv.ParseInt(, 10, 0)
}

// MustInt64 convert value to int, will panic on error
func ( string) int64 { return Int64OrPanic() }

// Int64OrPanic convert value to int, will panic on error
func ( string) int64 {
	,  := strconv.ParseInt(, 10, 0)
	if  != nil {
		panic()
	}
	return 
}

/*************************************************************
 * region string value to uint
 *************************************************************/

// Uint convert string to uint, will ignore error
func ( string) uint64 { return SafeUint() }

// SafeUint convert string to uint, will ignore error
func ( string) uint64 {
	,  := UintOrErr()
	return 
}

// ToUint convert string to uint, return error on fail. alias of UintOrErr()
func ( string) (uint64, error) {
	return strconv.ParseUint(, 10, 0)
}

// UintOrErr convert string to uint, return error on fail
func ( string) (uint64, error) {
	return strconv.ParseUint(, 10, 0)
}

// MustUint convert value to uint, will panic on error. alias of UintOrPanic()
func ( string) uint64 { return UintOrPanic() }

// UintOrPanic convert value to uint, will panic on error
func ( string) uint64 {
	,  := UintOrErr()
	if  != nil {
		panic()
	}
	return 
}

// UintOrDefault convert string to uint, return default value on fail
func ( string,  uint64) uint64 {
	return UintOr(, )
}

// UintOr convert string to uint, return default value on fail
func ( string,  uint64) uint64 {
	,  := UintOrErr()
	if  != nil {
		return 
	}
	return 
}

/*************************************************************
 * region string value to byte
 * refer from https://github.com/valyala/fastjson/blob/master/util.go
 *************************************************************/

// Byte2str convert bytes to string
func ( []byte) string {
	return *(*string)(unsafe.Pointer(&))
}

// Byte2string convert bytes to string
func ( []byte) string {
	return *(*string)(unsafe.Pointer(&))
}

// ToBytes convert string to bytes
func ( string) ( []byte) {
	 := (*reflect.StringHeader)(unsafe.Pointer(&))

	 := (*reflect.SliceHeader)(unsafe.Pointer(&))
	.Data = .Data
	.Len = .Len
	.Cap = .Len
	return 
}

/*************************************************************
 * region string to int/string slice, time.Time
 *************************************************************/

// Ints alias of the ToIntSlice(). default sep is comma(,)
func ( string,  ...string) []int {
	,  := ToIntSlice(, ...)
	return 
}

// ToInts alias of the ToIntSlice(). default sep is comma(,)
func ( string,  ...string) ([]int, error) { return ToIntSlice(, ...) }

// ToIntSlice split string to slice and convert item to int.
//
// Default sep is comma
func ( string,  ...string) ( []int,  error) {
	 := ToSlice(, ...)
	for ,  := range  {
		,  := mathutil.ToInt()
		if  != nil {
			return []int{}, 
		}

		 = append(, )
	}
	return
}

// ToArray alias of the ToSlice()
func ( string,  ...string) []string { return ToSlice(, ...) }

// Strings alias of the ToSlice()
func ( string,  ...string) []string { return ToSlice(, ...) }

// ToStrings alias of the ToSlice()
func ( string,  ...string) []string { return ToSlice(, ...) }

// ToSlice split string to array.
func ( string,  ...string) []string {
	if len() > 0 {
		return Split(, [0])
	}
	return Split(, ",")
}

// 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 ( string) (time.Duration, error) {
	return comfunc.ToDuration()
}