107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
package validation
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
type StringField struct {
|
|
Field
|
|
Value string
|
|
}
|
|
|
|
func newStringField(key string, g Getter) *StringField {
|
|
return &StringField{
|
|
Value: g.Get(key),
|
|
Field: newField(key, g),
|
|
}
|
|
}
|
|
|
|
// Required enforces a non empty string
|
|
func (s *StringField) Required() *StringField {
|
|
if s.Value == "" {
|
|
s.getter.AddCheck(newFailedCheck(
|
|
"Field not provided",
|
|
fmt.Sprintf("%s is required", s.Key),
|
|
))
|
|
}
|
|
return s
|
|
}
|
|
|
|
// Optional will skip all validations if value is empty
|
|
func (s *StringField) Optional() *StringField {
|
|
if s.Value == "" {
|
|
s.optional = true
|
|
}
|
|
return s
|
|
}
|
|
|
|
// MaxLength enforces a maximum string length
|
|
func (s *StringField) MaxLength(length int) *StringField {
|
|
if len(s.Value) > length && !s.optional {
|
|
s.getter.AddCheck(newFailedCheck(
|
|
"Input too long",
|
|
fmt.Sprintf("%s is too long, max %v chars", s.Key, length),
|
|
))
|
|
}
|
|
return s
|
|
}
|
|
|
|
// MinLength enforces a minimum string length
|
|
func (s *StringField) MinLength(length int) *StringField {
|
|
if len(s.Value) < length && !s.optional {
|
|
s.getter.AddCheck(newFailedCheck(
|
|
"Input too short",
|
|
fmt.Sprintf("%s is too short, min %v chars", s.Key, length),
|
|
))
|
|
}
|
|
return s
|
|
}
|
|
|
|
// AlphaNumeric enforces the string contains only letters and numbers
|
|
func (s *StringField) AlphaNumeric() *StringField {
|
|
if s.optional {
|
|
return s
|
|
}
|
|
for _, r := range s.Value {
|
|
if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
|
|
s.getter.AddCheck(newFailedCheck(
|
|
"Invalid characters",
|
|
fmt.Sprintf("%s must contain only letters and numbers.", s.Key),
|
|
))
|
|
return s
|
|
}
|
|
}
|
|
return s
|
|
}
|
|
|
|
func (s *StringField) AllowedValues(allowed []string) *StringField {
|
|
if !slices.Contains(allowed, s.Value) && !s.optional {
|
|
s.getter.AddCheck(newFailedCheck(
|
|
"Value not allowed",
|
|
fmt.Sprintf("%s must be one of: %s", s.Key, strings.Join(allowed, ",")),
|
|
))
|
|
}
|
|
return s
|
|
}
|
|
|
|
// ToUpper transforms the string to uppercase
|
|
func (s *StringField) ToUpper() *StringField {
|
|
s.Value = strings.ToUpper(s.Value)
|
|
return s
|
|
}
|
|
|
|
// ToLower transforms the string to lowercase
|
|
func (s *StringField) ToLower() *StringField {
|
|
s.Value = strings.ToLower(s.Value)
|
|
return s
|
|
}
|
|
|
|
// TrimSpace removes leading and trailing whitespace
|
|
func (s *StringField) TrimSpace() *StringField {
|
|
s.Value = strings.TrimSpace(s.Value)
|
|
return s
|
|
}
|