CI / test (pull_request) Successful in 43s
Closes #3. - doc.go: package overview -- what a validator is, All vs Collect, errors are sentinels, how this compares to validator/v10 (tags+reflection), ozzo-validation (Rule interface) and govalidator (IsX helpers), and when to pick something else. - README.md: rewritten from three lines to a positioning intro, a "why this and not X" table, a building-blocks table, and a "not a fit if" note. - example_test.go: runnable Example (compose built-ins + a closure), Example_collectAll (errors.Is over a joined error), Example_errorsIs (sentinel matching, Err as match-anything). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
package validate_test
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"code.aneur.in/go/validate"
|
|
)
|
|
|
|
// A validator is any func(T) error. Compose the built-ins with your own
|
|
// closures using All (stop at the first failure) or Collect (report all).
|
|
func Example() {
|
|
username := validate.All(
|
|
validate.MinLength(3),
|
|
validate.MaxLength(16),
|
|
validate.Chars("abcdefghijklmnopqrstuvwxyz0123456789_"),
|
|
func(s string) error {
|
|
if strings.HasPrefix(s, "_") {
|
|
return errors.New("must not start with an underscore")
|
|
}
|
|
return nil
|
|
},
|
|
)
|
|
|
|
fmt.Println(username("ok_name"))
|
|
fmt.Println(username("_nope"))
|
|
fmt.Println(username("Nope"))
|
|
// Output:
|
|
// <nil>
|
|
// must not start with an underscore
|
|
// contains disallowed characters
|
|
}
|
|
|
|
// Collect runs every validator and joins the failures; errors.Is still
|
|
// matches each one.
|
|
func Example_collectAll() {
|
|
password := validate.Collect(
|
|
validate.MinLength(8),
|
|
validate.Chars("abcdefghijklmnopqrstuvwxyz"),
|
|
)
|
|
|
|
err := password("Ab1")
|
|
fmt.Println(err)
|
|
fmt.Println(errors.Is(err, validate.ErrMustBeLonger))
|
|
fmt.Println(errors.Is(err, validate.ErrDisallowedChars))
|
|
// Output:
|
|
// must contain at least 8 characters
|
|
// contains disallowed characters
|
|
// true
|
|
// true
|
|
}
|
|
|
|
// Errors are plain sentinels, so errors.Is works with no library-specific
|
|
// machinery. Err matches any error from this package.
|
|
func Example_errorsIs() {
|
|
err := validate.Email("not-an-email")
|
|
|
|
fmt.Println(err)
|
|
fmt.Println(errors.Is(err, validate.ErrInvalidEmail))
|
|
fmt.Println(errors.Is(err, validate.Err))
|
|
// Output:
|
|
// invalid email address
|
|
// true
|
|
// true
|
|
}
|