Created
February 13, 2025 17:20
-
-
Save zeroidentidad/b940d0501ff9a90b46fd4d20744816d8 to your computer and use it in GitHub Desktop.
Revisions
-
zeroidentidad created this gist
Feb 13, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,157 @@ package validate import ( "fmt" "regexp" ) type Errors map[string][]string func (e Errors) Add(field string, msg string) { AddError(field, e, msg) } var EmailRx = regexp.MustCompile(`^\S+@\S+$`) type Lengthable[Q any, U comparable] interface { []Q | map[U]Q } type NumericComparable interface { int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 } // Validate records the provided error, if not nil, inside the errors list // marked against the provided field. func AddError(field string, errors Errors, msg string) { errors[field] = append(errors[field], msg) } // StringLength Checks that a string has either an exact count of characters, // or fits within the specified range of m to n (inclusive). func IsStringLength( field string, errors Errors, v string, m int, n int, ) { var msg string if m == n { msg = fmt.Sprintf("Must be exactly %d characters long", m) } else { msg = fmt.Sprintf("Must be between %d and %d characters long", m, n) } if len(v) < m || len(v) > n { AddError(field, errors, msg) } } // IsStringMinLength Checks that a string is at least the listed size. func IsStringMinLength( field string, errors Errors, v string, m int, ) { if len(v) < m { AddError(field, errors, fmt.Sprintf("Must be at least %d characters long", m)) } } // NumberBetween Checks that the integer typed variable is exactly m == n in // size, or between m and n inclusive. func IsNumberBetween[T NumericComparable]( field string, errors Errors, v T, m T, n T, ) { var msg string if m == n { msg = fmt.Sprintf("Must be exactly %d, but was %d", m, v) } else { msg = fmt.Sprintf("Must be between %d and %d, but was %d", m, n, v) } if v < m || v > n { AddError(field, errors, msg) } } func IsNotEmpty( field string, errors Errors, v string, ) { if len(v) == 0 { AddError(field, errors, "Must not be empty") } } // Size checks that an array or map has either exactly m == n entries, or // between m and n entries (inclusive) func IsSize[T Lengthable[Q, U], Q any, U comparable]( field string, errors Errors, v T, m int, n int, ) { var msg string if m == n { msg = fmt.Sprintf("Must have exactly %d entries, but had %d", m, len(v)) } else { msg = fmt.Sprintf("Must have between %d and %d entries, but had %d", m, n, len(v)) } if len(v) < m || len(v) > n { AddError(field, errors, msg) } } // MinSize checks that an array or map has at least n entries func IsMinSize[T Lengthable[Q, U], Q any, U comparable]( field string, errors Errors, v T, n int, ) { entry := "entry" if n > 1 { entry = "entries" } var msg string msg = fmt.Sprintf("Must have a minimum of %d %s, but had %d", n, entry, len(v)) if len(v) < n { AddError(field, errors, msg) } } // Regex Confirms that value matches the provided regex func IsRegex( field string, errors Errors, v string, rx *regexp.Regexp, message string, ) { if !rx.MatchString(v) { AddError(field, errors, message) } } // Email Confirms that value matches our provided email regex. For a custom // email regex, use Regex. func IsEmail( field string, errors Errors, v string, ) { IsRegex(field, errors, v, EmailRx, "Email address is invalid") }