mirror of
https://github.com/aykhans/go-utils.git
synced 2025-10-16 02:35:58 +00:00
first commit
This commit is contained in:
186
parser/string.go
Normal file
186
parser/string.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ParseStringSupportedTypes defines the type constraint for types that can be
|
||||
// parsed from strings using the ParseString family of functions.
|
||||
type ParseStringSupportedTypes interface {
|
||||
string |
|
||||
int | int8 | int16 | int32 | int64 |
|
||||
uint | uint8 | uint16 | uint32 | uint64 |
|
||||
float64 |
|
||||
bool | time.Duration | url.URL
|
||||
}
|
||||
|
||||
// ParseString parses a string value into the specified type T.
|
||||
// It uses the appropriate parsing function based on the target type.
|
||||
//
|
||||
// The function supports all types defined in ParseStringSupportedTypes.
|
||||
// For integers, it parses base-10 numbers with appropriate bit sizes.
|
||||
// For booleans, it accepts: "1", "t", "T", "TRUE", "true", "True", "0", "f", "F", "FALSE", "false", "False".
|
||||
// For durations, it accepts strings like "300ms", "1.5h", "2h45m".
|
||||
// For URLs, it parses according to RFC 3986.
|
||||
//
|
||||
// Returns an error if the string cannot be parsed into the target type.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// num, err := ParseString[int]("42")
|
||||
// duration, err := ParseString[time.Duration]("5s")
|
||||
// isValid, err := ParseString[bool]("true")
|
||||
//
|
||||
//nolint:forcetypeassert
|
||||
func ParseString[T ParseStringSupportedTypes](rawValue string) (T, error) { //nolint:forcetypeassert
|
||||
var value T
|
||||
|
||||
switch any(value).(type) {
|
||||
case string:
|
||||
value = any(rawValue).(T)
|
||||
case int:
|
||||
i, err := strconv.Atoi(rawValue)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(i).(T)
|
||||
case int8:
|
||||
i, err := strconv.ParseInt(rawValue, 10, 8)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(int8(i)).(T)
|
||||
case int16:
|
||||
i, err := strconv.ParseInt(rawValue, 10, 16)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(int16(i)).(T)
|
||||
case int32:
|
||||
i, err := strconv.ParseInt(rawValue, 10, 32)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(int32(i)).(T)
|
||||
case int64:
|
||||
i, err := strconv.ParseInt(rawValue, 10, 64)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(i).(T)
|
||||
case uint:
|
||||
u, err := strconv.ParseUint(rawValue, 10, 0)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(uint(u)).(T)
|
||||
case uint8:
|
||||
u, err := strconv.ParseUint(rawValue, 10, 8)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(uint8(u)).(T)
|
||||
case uint16:
|
||||
u, err := strconv.ParseUint(rawValue, 10, 16)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(uint16(u)).(T)
|
||||
case uint32:
|
||||
u, err := strconv.ParseUint(rawValue, 10, 32)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(uint32(u)).(T)
|
||||
case uint64:
|
||||
u, err := strconv.ParseUint(rawValue, 10, 64)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(u).(T)
|
||||
case float64:
|
||||
f, err := strconv.ParseFloat(rawValue, 64)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(f).(T)
|
||||
case bool:
|
||||
b, err := strconv.ParseBool(rawValue)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(b).(T)
|
||||
case time.Duration:
|
||||
d, err := time.ParseDuration(rawValue)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(d).(T)
|
||||
case url.URL:
|
||||
u, err := url.Parse(rawValue)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
value = any(*u).(T)
|
||||
default:
|
||||
return value, fmt.Errorf("unsupported type: %T", value)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// ParseStringOrZero parses a string value into the specified type T.
|
||||
// If parsing fails, it returns the zero value for type T instead of an error.
|
||||
//
|
||||
// This is useful when you want a simple conversion that falls back to a
|
||||
// default zero value on error.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// num := ParseStringOrZero[int]("invalid") // returns 0
|
||||
// num := ParseStringOrZero[int]("42") // returns 42
|
||||
func ParseStringOrZero[T ParseStringSupportedTypes](rawValue string) T {
|
||||
parsedValue, _ := ParseString[T](rawValue)
|
||||
return parsedValue
|
||||
}
|
||||
|
||||
// ParseStringWithDefault parses a string value into the specified type T.
|
||||
// If parsing fails, it returns the provided default value along with the error.
|
||||
//
|
||||
// Unlike ParseString, this ensures a usable value is always returned,
|
||||
// but still provides error information for logging or handling.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// num, err := ParseStringWithDefault("invalid", 10)
|
||||
// // returns: 10, error
|
||||
// num, err := ParseStringWithDefault("42", 10)
|
||||
// // returns: 42, nil
|
||||
func ParseStringWithDefault[T ParseStringSupportedTypes](rawValue string, dft T) (T, error) {
|
||||
parsedValue, err := ParseString[T](rawValue)
|
||||
if err != nil {
|
||||
return dft, err
|
||||
}
|
||||
return parsedValue, nil
|
||||
}
|
||||
|
||||
// ParseStringOrDefault parses a string value into the specified type T.
|
||||
// If parsing fails, it returns the provided default value and suppresses the error.
|
||||
//
|
||||
// This is the most convenient option when you want a fallback value
|
||||
// and don't need to handle the error explicitly.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// num := ParseStringOrDefault("invalid", 10) // returns 10
|
||||
// num := ParseStringOrDefault("42", 10) // returns 42
|
||||
func ParseStringOrDefault[T ParseStringSupportedTypes](rawValue string, dft T) T {
|
||||
parsedValue, err := ParseString[T](rawValue)
|
||||
if err != nil {
|
||||
return dft
|
||||
}
|
||||
return parsedValue
|
||||
}
|
Reference in New Issue
Block a user