Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 102 additions & 68 deletions validator/transformers.go
Original file line number Diff line number Diff line change
@@ -1,105 +1,139 @@
package validator

import (
"reflect"
"strconv"
"strings"

"golang.org/x/text/cases"
"golang.org/x/text/language"
)

// ToLower transforms a string to lowercase.
func ToLower(value interface{}) interface{} {
if str, ok := value.(string); ok {
return strings.ToLower(str)
// applyToArrayOrValue is a helper function to handle both single values and arrays
func applyToArrayOrValue(value any, transform func(any) any) any {
// Use reflection to check if the value is a slice/array
v := reflect.ValueOf(value)
if v.Kind() == reflect.Slice {
// Create a new slice to store transformed values
result := make([]any, v.Len())
for i := 0; i < v.Len(); i++ {
result[i] = transform(v.Index(i).Interface())
}
return result
}
return value
// If not a slice, apply transformation directly
return transform(value)
}

// ToUpper transforms a string to uppercase.
func ToUpper(value interface{}) interface{} {
if str, ok := value.(string); ok {
return strings.ToUpper(str)
}
return value
// ToLower transforms a string or array of strings to lowercase
func ToLower(value any) any {
return applyToArrayOrValue(value, func(v any) any {
if str, ok := v.(string); ok {
return strings.ToLower(str)
}
return v
})
}

// TrimSpace trims leading and trailing whitespace from a string.
func Trim(value interface{}) interface{} {
if str, ok := value.(string); ok {
return strings.TrimSpace(str)
}
return value
// ToUpper transforms a string or array of strings to uppercase
func ToUpper(value any) any {
return applyToArrayOrValue(value, func(v any) any {
if str, ok := v.(string); ok {
return strings.ToUpper(str)
}
return v
})
}

// RemoveSpecialChars removes special characters from a string.
func RemoveSpecialChars(value interface{}) interface{} {
if str, ok := value.(string); ok {
var result strings.Builder
for _, char := range str {
if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') || char == ' ' {
result.WriteRune(char)
// Trim trims leading and trailing whitespace from a string or array of strings
func Trim(value any) any {
return applyToArrayOrValue(value, func(v any) any {
if str, ok := v.(string); ok {
return strings.TrimSpace(str)
}
return v
})
}

// RemoveSpecialChars removes special characters from a string or array of strings
func RemoveSpecialChars(value any) any {
return applyToArrayOrValue(value, func(v any) any {
if str, ok := v.(string); ok {
var result strings.Builder
for _, char := range str {
if (char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9') || char == ' ' {
result.WriteRune(char)
}
}
return result.String()
}
return result.String()
}
return value
return v
})
}

// ToTitleCase converts a string to title case.
func ToTitleCase(value interface{}) interface{} {
if str, ok := value.(string); ok {
// Create a title caser for the English language
caser := cases.Title(language.French)
return caser.String(strings.ToLower(str))
}
return value
// ToTitleCase converts a string or array of strings to title case
func ToTitleCase(value any) any {
return applyToArrayOrValue(value, func(v any) any {
if str, ok := v.(string); ok {
caser := cases.Title(language.French)
return caser.String(strings.ToLower(str))
}
return v
})
}

// ToInt converts a string or float to an integer.
func ToInt(value interface{}) interface{} {
switch v := value.(type) {
case string:
if i, err := strconv.Atoi(v); err == nil {
return i
// ToInt converts a string/float or array of strings/floats to integer(s)
func ToInt(value any) any {
return applyToArrayOrValue(value, func(v any) any {
switch val := v.(type) {
case string:
if i, err := strconv.Atoi(val); err == nil {
return i
}
case float64:
return int(val)
}
case float64:
return int(v)
}
return value
return v
})
}

// ToFloat converts a string or integer to a float.
func ToFloat(value interface{}) interface{} {
switch v := value.(type) {
case string:
if f, err := strconv.ParseFloat(v, 64); err == nil {
return f
// ToFloat converts a string/integer or array of strings/integers to float(s)
func ToFloat(value any) any {
return applyToArrayOrValue(value, func(v any) any {
switch val := v.(type) {
case string:
if f, err := strconv.ParseFloat(val, 64); err == nil {
return f
}
case int:
return float64(val)
}
case int:
return float64(v)
}
return value
return v
})
}

// Truncate truncates a string to a specified maximum length.
// Truncate truncates a string or array of strings to a specified maximum length
func Truncate(maxLength int) Transformer {
return func(value interface{}) interface{} {
if str, ok := value.(string); ok {
if len(str) > maxLength {
return str[:maxLength]
return func(value any) any {
return applyToArrayOrValue(value, func(v any) any {
if str, ok := v.(string); ok {
if len(str) > maxLength {
return str[:maxLength]
}
}
}
return value
return v
})
}
}

// Replace replaces occurrences of a substring with another string.
// Replace replaces occurrences of a substring with another string in a string or array of strings
func Replace(old, new string) Transformer {
return func(value interface{}) interface{} {
if str, ok := value.(string); ok {
return strings.ReplaceAll(str, old, new)
}
return value
return func(value any) any {
return applyToArrayOrValue(value, func(v any) any {
if str, ok := v.(string); ok {
return strings.ReplaceAll(str, old, new)
}
return v
})
}
}
Loading
Loading