Files
oslstats/internal/validation/stringfield.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
}