Use Specific Rules
Choose the most specific rule for your needs rather than generic ones.
// Goodr.MinN(18), r.MaxN(120)
// Less specificCustomAgeRule()
This reference documents all built-in validation rules available in Souuup. Rules are organized by the type of data they validate.
String rules are found in the r
package and work with string
values.
r.MinS(n int) StringRule
Validates that a string has at least n
characters.
// Minimum 3 charactersnameField := u.Field("John", r.MinS(3))
Parameters:
n
- Minimum length (inclusive)Error Message: "length is X, but needs to be at least N"
r.MaxS(n int) StringRule
Validates that a string has at most n
characters.
// Maximum 20 charactersusernameField := u.Field("johndoe", r.MaxS(20))
Parameters:
n
- Maximum length (inclusive)Error Message: "length is X, but needs to be at most N"
r.LenS(n int) StringRule
Validates that a string has exactly n
characters.
// Exactly 6 characters (e.g., for PIN codes)pinField := u.Field("123456", r.LenS(6))
Parameters:
n
- Exact length requiredError Message: "length is X, but needs to be exactly N"
r.ContainsS(substr string) StringRule
Validates that a string contains the specified substring.
// Must contain "@" symbol
Parameters:
substr
- Substring that must be presentError Message: "\"value\" does not contain \"substr\", but needs to"
r.InS(set []string) StringRule
Validates that a string is one of the values in the provided set.
// Must be one of the allowed sizessizeField := u.Field("medium", r.InS([]string{"small", "medium", "large"}))
Parameters:
set
- Slice of allowed string valuesError Message: "\"value\" is not in [allowed values], but should be"
r.NotInS(set []string) StringRule
Validates that a string is NOT one of the values in the provided set.
// Must not be a forbidden wordusernameField := u.Field("john", r.NotInS([]string{"admin", "root", "system"}))
Parameters:
set
- Slice of forbidden string valuesError Message: "\"value\" is in [forbidden values], but shouldn't be"
Numeric rules work with any type that implements the Numeric
constraint (integers and floats).
r.MinN[T Numeric](n T) NumericRule[T]
Validates that a numeric value is at least n
.
// Age must be at least 18ageField := u.Field(25, r.MinN(18))
// Price must be at least 0.01priceField := u.Field(19.99, r.MinN(0.01))
Parameters:
n
- Minimum value (inclusive)Error Message: "value is X, but needs to be at least N"
r.MaxN[T Numeric](n T) NumericRule[T]
Validates that a numeric value is at most n
.
// Age must not exceed 120ageField := u.Field(25, r.MaxN(120))
Parameters:
n
- Maximum value (inclusive)Error Message: "value is X, but needs to be at most N"
r.Gt[T Numeric](n T) NumericRule[T]
Validates that a numeric value is greater than n
(exclusive).
// Price must be greater than 0priceField := u.Field(19.99, r.Gt(0.0))
Parameters:
n
- Value that must be exceededError Message: "value is X, but needs to be greater than N"
r.Gte[T Numeric](n T) NumericRule[T]
Validates that a numeric value is greater than or equal to n
. This is an alias for MinN
.
// Score must be at least 0scoreField := u.Field(85, r.Gte(0))
Parameters:
n
- Minimum value (inclusive)Error Message: "value is X, but needs to be at least N"
r.Lt[T Numeric](n T) NumericRule[T]
Validates that a numeric value is less than n
(exclusive).
// Percentage must be less than 100percentField := u.Field(85.5, r.Lt(100.0))
Parameters:
n
- Value that must not be reachedError Message: "value is X, but needs to be less than N"
r.Lte[T Numeric](n T) NumericRule[T]
Validates that a numeric value is less than or equal to n
. This is an alias for MaxN
.
// Score must not exceed 100scoreField := u.Field(85, r.Lte(100))
Parameters:
n
- Maximum value (inclusive)Error Message: "value is X, but needs to be at most N"
r.NeqN[T Numeric](n T) NumericRule[T]
Validates that a numeric value is not equal to n
.
// Quantity cannot be 0quantityField := u.Field(5, r.NeqN(0))
Parameters:
n
- Value that is not allowedError Message: "value is X, but needs to not equal to N"
Slice rules validate arrays/slices and their elements.
r.MinLen[T any](n int) SliceRule[T]
Validates that a slice has at least n
elements.
// Must have at least 1 interestinterestsField := u.Field([]string{"coding", "music"}, r.MinLen[string](1))
Parameters:
n
- Minimum number of elementsError Message: "length is X, but needs to be at least N"
r.MaxLen[T any](n int) SliceRule[T]
Validates that a slice has at most n
elements.
// Can have at most 5 tagstagsField := u.Field([]string{"go", "validation"}, r.MaxLen[string](5))
Parameters:
n
- Maximum number of elementsError Message: "length is X, but needs to be at most N"
r.ExactLen[T any](n int) SliceRule[T]
Validates that a slice has exactly n
elements.
// Must have exactly 3 coordinatescoordsField := u.Field([]float64{1.0, 2.0, 3.0}, r.ExactLen[float64](3))
Parameters:
n
- Exact number of elements requiredError Message: "length is X, but needs to be exactly N"
r.Every[T any](rule Rule[T]) SliceRule[T]
Validates that every element in the slice passes the given rule.
// Every interest must be at least 3 charactersinterestsField := u.Field([]string{"coding", "music"}, r.Every(r.MinS(3)))
// Every score must be between 0 and 100scoresField := u.Field([]int{85, 92, 78}, r.Every(r.MinN(0)), r.Every(r.MaxN(100)))
Parameters:
rule
- The rule that every element must satisfyError Message: "X elements failed validation\n [index]: error message"
r.Some[T any](rule Rule[T]) SliceRule[T]
Validates that at least one element in the slice passes the given rule.
// At least one score must be above 90scoresField := u.Field([]int{85, 95, 78}, r.Some(r.Gt(90)))
Parameters:
rule
- The rule that at least one element must satisfyError Message: "all X elements failed validation\n [index]: error message"
r.None[T any](rule Rule[T]) SliceRule[T]
Validates that no element in the slice passes the given rule.
// No score should be negativescoresField := u.Field([]int{85, 92, 78}, r.None(r.Lt(0)))
Parameters:
rule
- The rule that no element should satisfyError Message: "X elements unexpectedly passed validation (expected none to pass rule)\n [index]: failed"
r.Contains[T comparable](member T) SliceRule[T]
Validates that a slice contains the specified element.
// Team must include a goalkeeperpositionsField := u.Field([]string{"GK", "DEF", "MID"}, r.Contains("GK"))
Parameters:
member
- Element that must be present in the sliceError Message: "[slice] does not contain member, but needs to"
Rules that work with any comparable type.
r.NotZero[T comparable](FieldState[T]) error
Validates that a value is not the zero value for its type. This is the primary way to mark fields as required.
// String must not be emptynameField := u.Field("John", r.NotZero)
// Number must not be 0ageField := u.Field(25, r.NotZero)
// Boolean must be truetermsField := u.Field(true, r.NotZero)
Error Message: "value is required but has zero value"
r.SameAs[T comparable](other T) Rule[T]
Validates that a value equals another value. Commonly used for password confirmation.
// Password confirmation must matchconfirmField := u.Field(confirmPassword, r.SameAs(originalPassword))
Parameters:
other
- The value that this field must equalError Message: "X does not match Y"
You can apply multiple rules to a single field. All rules must pass for validation to succeed:
// Username with multiple constraintsusernameField := u.Field("johndoe", r.NotZero, // Required r.MinS(3), // At least 3 characters r.MaxS(20), // At most 20 characters CustomUsernameRule, // Custom validation)
All rules are type-safe through Go generics:
// These will compilestringField := u.Field("hello", r.MinS(3)) // ✅intField := u.Field(42, r.MinN(0)) // ✅sliceField := u.Field([]string{"a"}, r.MinLen[string](1)) // ✅
// These will NOT compilestringField := u.Field("hello", r.MinN(0)) // ❌ Type mismatchintField := u.Field(42, r.MinS(3)) // ❌ Type mismatch
All built-in rules provide clear, actionable error messages that specify:
// Input: age = 15, rule: r.MinN(18)// Error: "value is 15, but needs to be at least 18"
// Input: name = "Jo", rule: r.MinS(3)// Error: "length is 2, but needs to be at least 3"
// Input: tags = ["a", "bb", "c"], rule: r.Every(r.MinS(2))// Error: "2 elements failed validation// [0]: length is 1, but needs to be at least 2// [2]: length is 1, but needs to be at least 2"
Use Specific Rules
Choose the most specific rule for your needs rather than generic ones.
// Goodr.MinN(18), r.MaxN(120)
// Less specificCustomAgeRule()
Combine Rules Logically
Apply rules in logical order, from most basic to most specific.
// Good orderr.NotZero, // Required firstr.MinS(8), // Then lengthStrongPassword, // Then complexity
Leverage Type Safety
Let the type system catch mistakes at compile time.
// Compiler ensures rule matches field typeu.Field(userAge, r.MinN(18)) // ✅ Correctu.Field(userAge, r.MinS(18)) // ❌ Won't compile
Read Error Messages
Built-in rules provide detailed error messages to help debug validation failures.
{ "age": { "errors": ["value is 15, but needs to be at least 18"] }}
Custom Rules
Learn how to create your own validation rules for domain-specific requirements.
Examples
See real-world examples of using these rules in various scenarios.
Core API
Explore the core validation framework functions and types.