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>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user