Comparable values¶
eq.Of converts a field of any comparable type — an enum of a named type, a bool, a number, a string — to the configurator of equality rules. eq.Ptr converts a pointer to such a field, eq.Slice — a slice of them:
type Status string
const (
Active Status = "active"
Blocked Status = "blocked"
)
b.Field(&u.Status).As(eq.Of).Required().OneOf(Active, Blocked) // the arguments are Status
b.Field(&u.Agreed).As(eq.Of).Equal(true) // a bool
b.Field(&u.Role).As(eq.Ptr).OneOf(Admin, Editor) // a nil Role is skipped
b.Slice(&u.Roles).As(eq.Slice).Unique()
For strings and numbers str.Of and num.Of have more rules, eq.Of is for the types without their own configurator. eq.Of of a pointer field compares the pointers, use eq.Ptr to compare the values.
Rules¶
| Rule | Fails when | Message |
|---|---|---|
Required() |
eq.Of: the value is zero; eq.Ptr: the value is absent |
Should be fulfilled |
OneOf(values...) |
the value isn't one of values |
Only %v values is allowed |
NotOneOf(values...) |
the value is one of values |
Values %v are not allowed |
Equal(v) |
the value isn't v |
Should be %v |
NotEqual(v) |
the value is v |
Cannot be %v |
EqualField(&m.X) |
the value isn't equal to the value of the field X, see Rules on other fields |
Should be equal to %s |
NotEqualField(&m.X) |
the value is equal to the value of the field X |
Cannot be equal to %s |
Custom(fn) |
fn returns errors |
your messages, see Custom rules |
When(fn) |
— | the next rules are applied only if fn returns true, see Conditions |
eq.Slice has the rules of the slice itself, Each with the rules above for the elements, OneOf for every element and Unique:
| Rule | Fails when | Message |
|---|---|---|
Unique() |
the slice has duplicate elements, the error value is the first duplicate | Should contain unique values |
Unique compares the elements pairwise without allocations for slices up to 32 elements, and by a map for longer ones.
Example¶
package main
import (
"context"
"fmt"
"github.com/insei/valigo"
"github.com/insei/valigo/rules/eq"
)
type Plan string
const (
Free Plan = "free"
Pro Plan = "pro"
)
type SignUp struct {
Plan Plan
Terms bool
Features []string
}
func main() {
v := valigo.New()
valigo.Configure[SignUp](v, func(b valigo.Configurator[SignUp], s *SignUp) {
b.Field(&s.Plan).As(eq.Of).Required().OneOf(Free, Pro)
b.Field(&s.Terms).As(eq.Of).Equal(true)
b.Slice(&s.Features).As(eq.Slice).MaxLen(5).Unique()
})
for _, err := range v.Validate(context.Background(), &SignUp{Plan: "gold", Features: []string{"sso", "api", "sso"}}) {
fmt.Println(err)
}
}
Output: