Documentation ¶
Overview ¶
Example (Customizations) ¶
package main import ( "fmt" "time" v "github.com/RussellLuo/validating/v3" ) func mapNonzero(field *v.Field) v.Errors { value, ok := field.Value.(map[string]time.Time) if !ok { var want map[string]time.Time return v.NewUnsupportedErrors("mapNonzero", field, want) } if len(value) == 0 { return v.NewInvalidErrors(field, "is zero valued") } return nil } type MyValidator struct{} func (mv MyValidator) Validate(field *v.Field) v.Errors { return mapNonzero(field) } func main() { var value map[string]time.Time errs := v.Validate(v.Schema{ v.F("value", value): v.Func(mapNonzero), }) fmt.Printf("errs from the func-validator: %+v\n", errs) errs = v.Validate(v.Schema{ v.F("value", value): MyValidator{}, }) fmt.Printf("errs from the struct-validator: %+v\n", errs) }
Output: errs from the func-validator: value: INVALID(is zero valued) errs from the struct-validator: value: INVALID(is zero valued)
Example (NestedStruct) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) type Address struct { Country, Province, City string } type Person struct { Name string Age int Address Address } func main() { p := Person{} err := v.Validate(v.Schema{ v.F("name", p.Name): v.LenString(1, 5), v.F("age", p.Age): v.Gte(10), v.F("address", p.Address): v.Nested(func(addr Address) v.Validator { return v.Schema{ v.F("country", addr.Country): v.Nonzero[string](), v.F("province", addr.Province): v.Nonzero[string](), v.F("city", addr.City): v.Nonzero[string](), } }), }) fmt.Printf("err: %+v\n", err) //err: name: INVALID(has an invalid length), age: INVALID(is lower than the given value), address.country: INVALID(is zero valued), address.province: INVALID(is zero valued), address.city: INVALID(is zero valued) }
Output:
Example (NestedStructMap) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) type Member struct { Name string } type Person1 struct { Name string Age int Family map[string]*Member } func makeSchema1(p *Person1) v.Schema { return v.Schema{ v.F("name", p.Name): v.LenString(1, 5), v.F("age", p.Age): v.Nonzero[int](), v.F("family", p.Family): v.EachMap[map[string]*Member](v.Nested(func(member *Member) v.Validator { return v.Schema{ v.F("name", member.Name): v.LenString(10, 15).Msg("is too long"), } })), } } // The equivalent implementation using Map. // //nolint:golint,unused func makeSchema1_Map(p *Person1) v.Schema { return v.Schema{ v.F("name", p.Name): v.LenString(1, 5), v.F("age", p.Age): v.Nonzero[int](), v.F("family", p.Family): v.Map(func(m map[string]*Member) map[string]v.Validator { schemas := make(map[string]v.Validator) for relation, member := range m { schemas[relation] = v.Schema{ v.F("name", member.Name): v.LenString(10, 15).Msg("is too long"), } } return schemas }), } } func main() { p1 := Person1{} err := v.Validate(makeSchema1(&p1)) fmt.Printf("err of p1: %+v\n", err) p2 := Person1{Family: map[string]*Member{ "father": {"father's name"}, "mother": {"mother's name is long"}, }} err = v.Validate(makeSchema1(&p2)) fmt.Printf("err of p2: %+v\n", err) //err of p1: name: INVALID(has an invalid length), age: INVALID(is zero valued) //err of p2: name: INVALID(has an invalid length), age: INVALID(is zero valued), family[mother].name: INVALID(is too long) }
Output:
Example (NestedStructPointer) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) type Address2 struct { Country, Province, City string } type Person2 struct { Name string Age int Address *Address2 } func makeSchema2(p *Person2) v.Schema { return v.Schema{ v.F("name", p.Name): v.LenString(1, 5), v.F("age", p.Age): v.Lte(50), v.F("address", p.Address): v.All( v.Nonzero[*Address2]().Msg("is nil"), v.Nested(func(addr *Address2) v.Validator { return v.Schema{ v.F("country", addr.Country): v.Nonzero[string](), v.F("province", addr.Province): v.Nonzero[string](), v.F("city", addr.City): v.Nonzero[string](), } }), ), } } func main() { p1 := Person2{} err := v.Validate(makeSchema2(&p1)) fmt.Printf("err of p1: %+v\n", err) p2 := Person2{Age: 60, Address: &Address2{}} err = v.Validate(makeSchema2(&p2)) fmt.Printf("err of p2: %+v\n", err) //err of p1: name: INVALID(has an invalid length), address: INVALID(is nil) //err of p2: name: INVALID(has an invalid length), age: INVALID(is greater than the given value), address.country: INVALID(is zero valued), address.province: INVALID(is zero valued), address.city: INVALID(is zero valued) }
Output:
Example (NestedStructSchemaInside) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) type Address3 struct { Country, Province, City string } func (a *Address3) Schema() v.Schema { return v.Schema{ v.F("country", a.Country): v.Nonzero[string](), v.F("province", a.Province): v.Nonzero[string](), v.F("city", a.City): v.Nonzero[string](), } } type Person3 struct { Name string Age int Address Address3 } func (p *Person3) Schema() v.Schema { return v.Schema{ v.F("name", p.Name): v.LenString(1, 5), v.F("age", p.Age): v.Gte(10), v.F("address", p.Address): p.Address.Schema(), } } func main() { p := Person3{} err := v.Validate(p.Schema()) fmt.Printf("err: %+v\n", err) //err: name: INVALID(has an invalid length), age: INVALID(is lower than the given value), address.country: INVALID(is zero valued), address.province: INVALID(is zero valued), address.city: INVALID(is zero valued) }
Output:
Example (NestedStructSlice) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) type Phone struct { Number, Remark string } type Person4 struct { Name string Age int Phones []*Phone } func makeSchema4(p *Person4) v.Schema { return v.Schema{ v.F("name", p.Name): v.LenString(1, 5), v.F("age", p.Age): v.Nonzero[int](), v.F("phones", p.Phones): v.EachSlice[[]*Phone](v.Nested(func(phone *Phone) v.Validator { return v.Schema{ v.F("number", phone.Number): v.Nonzero[string](), v.F("remark", phone.Remark): v.LenString(5, 7), } })), } } // The equivalent implementation using Slice. // //nolint:golint,unused func makeSchema4_Slice(p *Person4) v.Schema { return v.Schema{ v.F("name", p.Name): v.LenString(1, 5), v.F("age", p.Age): v.Nonzero[int](), v.F("phones", p.Phones): v.Slice(func(s []*Phone) (schemas []v.Validator) { for _, phone := range s { schemas = append(schemas, v.Schema{ v.F("number", phone.Number): v.Nonzero[string](), v.F("remark", phone.Remark): v.LenString(5, 7), }) } return }), } } func main() { p1 := Person4{} err := v.Validate(makeSchema4(&p1)) fmt.Printf("err of p1: %+v\n", err) p2 := Person4{Phones: []*Phone{ {"13011112222", "private"}, {"13033334444", "business"}, }} err = v.Validate(makeSchema4(&p2)) fmt.Printf("err of p2: %+v\n", err) //err of p1: name: INVALID(has an invalid length), age: INVALID(is zero valued) //err of p2: name: INVALID(has an invalid length), age: INVALID(is zero valued), phones[1].remark: INVALID(has an invalid length) }
Output:
Example (SimpleMap) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) func main() { ages := map[string]int{ "foo": 0, "bar": 1, } err := v.Validate(v.Value(ages, v.EachMap[map[string]int](v.Nonzero[int]()))) fmt.Printf("%+v\n", err) }
Output: [foo]: INVALID(is zero valued)
Example (SimpleSlice) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) func main() { names := []string{"", "foo"} err := v.Validate(v.Value(names, v.EachSlice[[]string](v.Nonzero[string]()))) fmt.Printf("%+v\n", err) }
Output: [0]: INVALID(is zero valued)
Example (SimpleStringIsIP) ¶
package main import ( "fmt" "net" v "github.com/RussellLuo/validating/v3" ) func main() { isIP := func(value string) bool { return net.ParseIP(value) != nil } value := "192.168.0." err := v.Validate(v.Value(value, v.Is(isIP).Msg("invalid IP"))) fmt.Printf("%+v\n", err) }
Output: INVALID(invalid IP)
Example (SimpleStruct) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) type Person5 struct { Name string Age int } func main() { p := Person5{Age: 1} err := v.Validate(v.Schema{ v.F("name", p.Name): v.LenString(1, 5).Msg("length is not between 1 and 5"), v.F("age", p.Age): v.Nonzero[int](), }) fmt.Printf("%+v\n", err) }
Output: name: INVALID(length is not between 1 and 5)
Example (SimpleValue) ¶
package main import ( "fmt" v "github.com/RussellLuo/validating/v3" ) func main() { err := v.Validate(v.Value(0, v.Range(1, 5))) fmt.Printf("%+v\n", err) }
Output: INVALID(is not between the given range)
Index ¶
- Constants
- Variables
- type AnyValidator
- type Error
- type Errors
- type Field
- type Func
- type MessageValidator
- func Eq[T comparable](value T) (mv *MessageValidator)
- func Gt[T constraints.Ordered](value T) (mv *MessageValidator)
- func Gte[T constraints.Ordered](value T) (mv *MessageValidator)
- func In[T comparable](values ...T) (mv *MessageValidator)
- func Is[T any](f func(T) bool) (mv *MessageValidator)
- func LenSlice[T ~[]E, E any](min, max int) (mv *MessageValidator)
- func LenString(min, max int) (mv *MessageValidator)
- func Lt[T constraints.Ordered](value T) (mv *MessageValidator)
- func Lte[T constraints.Ordered](value T) (mv *MessageValidator)
- func Match(re *regexp.Regexp) (mv *MessageValidator)
- func Ne[T comparable](value T) (mv *MessageValidator)
- func Nin[T comparable](values ...T) (mv *MessageValidator)
- func Nonzero[T comparable]() (mv *MessageValidator)
- func Not(validator Validator) (mv *MessageValidator)
- func Range[T constraints.Ordered](min, max T) (mv *MessageValidator)
- func RuneCount(min, max int) (mv *MessageValidator)
- func Zero[T comparable]() (mv *MessageValidator)
- type Schema
- type Validator
- func All(validators ...Validator) Validator
- func Array[T ~[]E, E any](f func(T) []Validator) Validator
- func EachMap[T map[K]V, K comparable, V any](validator Validator) Validator
- func EachSlice[T ~[]E, E any](validator Validator) Validator
- func Map[T map[K]V, K comparable, V any](f func(T) map[K]Validator) Validator
- func Nested[T any](f func(T) Validator) Validator
- func Slice[T ~[]E, E any](f func(T) []Validator) Validator
- func ZeroOr[T comparable](validator Validator) Validator
Examples ¶
Constants ¶
const ( ErrUnsupported = "UNSUPPORTED" ErrInvalid = "INVALID" )
Variables ¶
var And = All
And is an alias of All.
var Or = Any
Or is an alias of Any.
Functions ¶
This section is empty.
Types ¶
type AnyValidator ¶
type AnyValidator struct {
// contains filtered or unexported fields
}
AnyValidator is a validator that allows users to change the returned errors by calling LastError().
func Any ¶
func Any(validators ...Validator) *AnyValidator
Any is a composite validator factory used to create a validator, which will succeed as long as any sub-validator succeeds.
func (*AnyValidator) LastError ¶
func (av *AnyValidator) LastError() *AnyValidator
LastError makes AnyValidator return the error from the last validator if all inner validators fail.
func (*AnyValidator) Validate ¶
func (av *AnyValidator) Validate(field *Field) Errors
Validate delegates the actual validation to its inner validators.
type Errors ¶
type Errors []Error
func NewInvalidErrors ¶
func NewUnsupportedErrors ¶
type Func ¶
Func is an adapter to allow the use of ordinary functions as validators. If f is a function with the appropriate signature, Func(f) is a Validator that calls f.
type MessageValidator ¶
MessageValidator is a validator that allows users to customize the INVALID error message by calling Msg().
func Eq ¶
func Eq[T comparable](value T) (mv *MessageValidator)
Eq is a leaf validator factory used to create a validator, which will succeed when the field's value equals the given value.
func Gt ¶
func Gt[T constraints.Ordered](value T) (mv *MessageValidator)
Gt is a leaf validator factory used to create a validator, which will succeed when the field's value is greater than the given value.
func Gte ¶
func Gte[T constraints.Ordered](value T) (mv *MessageValidator)
Gte is a leaf validator factory used to create a validator, which will succeed when the field's value is greater than or equal to the given value.
func In ¶
func In[T comparable](values ...T) (mv *MessageValidator)
In is a leaf validator factory used to create a validator, which will succeed when the field's value is equal to one of the given values.
func Is ¶
func Is[T any](f func(T) bool) (mv *MessageValidator)
Is is a leaf validator factory used to create a validator, which will succeed when the predicate function f returns true for the field's value.
func LenSlice ¶
func LenSlice[T ~[]E, E any](min, max int) (mv *MessageValidator)
LenSlice is a leaf validator factory used to create a validator, which will succeed when the length of the slice field is between min and max.
func LenString ¶
func LenString(min, max int) (mv *MessageValidator)
LenString is a leaf validator factory used to create a validator, which will succeed when the length of the string field is between min and max.
func Lt ¶
func Lt[T constraints.Ordered](value T) (mv *MessageValidator)
Lt is a leaf validator factory used to create a validator, which will succeed when the field's value is lower than the given value.
func Lte ¶
func Lte[T constraints.Ordered](value T) (mv *MessageValidator)
Lte is a leaf validator factory used to create a validator, which will succeed when the field's value is lower than or equal to the given value.
func Match ¶
func Match(re *regexp.Regexp) (mv *MessageValidator)
Match is a leaf validator factory used to create a validator, which will succeed when the field's value matches the given regular expression.
func Ne ¶
func Ne[T comparable](value T) (mv *MessageValidator)
Ne is a leaf validator factory used to create a validator, which will succeed when the field's value does not equal the given value.
func Nin ¶
func Nin[T comparable](values ...T) (mv *MessageValidator)
Nin is a leaf validator factory used to create a validator, which will succeed when the field's value is not equal to any of the given values.
func Nonzero ¶
func Nonzero[T comparable]() (mv *MessageValidator)
Nonzero is a leaf validator factory used to create a validator, which will succeed when the field's value is nonzero.
func Not ¶
func Not(validator Validator) (mv *MessageValidator)
Not is a composite validator factory used to create a validator, which will succeed when the given validator fails.
func Range ¶
func Range[T constraints.Ordered](min, max T) (mv *MessageValidator)
Range is a leaf validator factory used to create a validator, which will succeed when the field's value is between min and max.
func RuneCount ¶
func RuneCount(min, max int) (mv *MessageValidator)
RuneCount is a leaf validator factory used to create a validator, which will succeed when the number of runes in the field's value is between min and max.
func Zero ¶
func Zero[T comparable]() (mv *MessageValidator)
Zero is a leaf validator factory used to create a validator, which will succeed when the field's value is zero.
func (*MessageValidator) Msg ¶
func (mv *MessageValidator) Msg(msg string) *MessageValidator
Msg sets the INVALID error message.
func (*MessageValidator) Validate ¶
func (mv *MessageValidator) Validate(field *Field) Errors
Validate delegates the actual validation to its inner validator.
type Schema ¶
Schema is a field mapping, which defines the corresponding validator for each field.
type Validator ¶
Validator is an interface for representing a validating's validator.
func All ¶
All is a composite validator factory used to create a validator, which will succeed only when all sub-validators succeed.
func EachMap ¶
func EachMap[T map[K]V, K comparable, V any](validator Validator) Validator
EachMap is a composite validator factory used to create a validator, which will apply the given validator to each element (i.e. the map value) of the map field.
Usually, for simplicity, it's recommended to use EachMap. If you have more complex validation rules for map elements, such as different validation for each value or validation specific to keys, then you should use Map.
func EachSlice ¶
EachSlice is a composite validator factory used to create a validator, which will apply the given validator to each element of the slice field.
Usually, for simplicity, it's recommended to use EachSlice. If you have more complex validation rules for slice elements, such as different validation for each element, then you should use Slice.
func Map ¶
func Map[T map[K]V, K comparable, V any](f func(T) map[K]Validator) Validator
Map is a composite validator factory used to create a validator, which will do the validation per the schemas associated with a map.
func Nested ¶
Nested is a composite validator factory used to create a validator, which will delegate the actual validation to the validator returned by f.
func Slice ¶
Slice is a composite validator factory used to create a validator, which will do the validation per the schemas associated with a slice.
func ZeroOr ¶
func ZeroOr[T comparable](validator Validator) Validator
ZeroOr is a composite validator factory used to create a validator, which will succeed if the field's value is zero, or if the given validator succeeds.
ZeroOr will return the error from the given validator if it fails.