| English | 中文 |
|---|
hvalid is a lightweight validation library written in Go. It defines a rule type and ships common rules, so you can check data quickly.
- Generics. Check numbers, text, slices, maps, times, and defined types such as
type Age int. A struct is checked by a rule you write for that struct. - Small call. Pass the field name once to
Validate, then pass the rules. A rule does not carry the field name. - Extensible. A custom rule has the same type as a built-in rule, so both can be passed to
Validate. - Clear errors. Failure returns one error. It names the field and lists every reason.
A failed check looks like this:
name: value length too short
count: must be greater than or equal to 1; must be less than or equal to 10
go get github.com/lyonnee/hvalidimport "github.com/lyonnee/hvalid"
err := hvalid.Validate("name", "hi", hvalid.MinLen[string](3))
// name: value length too short
err = hvalid.Validate("count", 10, hvalid.Min(5), hvalid.Max(15))Validate runs every rule. Reasons are joined with "; ". A direct call such as hvalid.Min(5)(4) returns only must be greater than or equal to 5, because no field name was given.
Defined types use the same rules:
type Age int
err := hvalid.Validate("age", Age(17), hvalid.Min[Age](18))Write a rule for the struct and call Validate once per field. Return that error as-is so the field name stays intact.
type User struct {
Name string
Age int
}
func UserRule() hvalid.ValidatorFunc[User] {
return func(user User) error {
if err := hvalid.Validate("name", user.Name, hvalid.MinLen[string](1)); err != nil {
return err
}
return hvalid.Validate("age", user.Age, hvalid.Min(18))
}
}
err := UserRule()(User{Name: "Zhang San", Age: 20})A custom rule is the same type as a built-in one. Its error text becomes one reason.
import "errors"
func IsPositive() hvalid.ValidatorFunc[int] {
return func(n int) error {
if n <= 0 {
return errors.New("must be positive")
}
return nil
}
}
err := hvalid.Validate("n", 0, IsPositive())
// n: must be positive| Rule | Value |
|---|---|
Min, Max, Range, Positive, Negative |
numbers, including defined numeric types |
MinLen, MaxLen |
string, []byte, and defined text types |
MinItems, MaxItems, NotEmpty, Empty, Contains |
slices |
MinSize, MaxSize, MapNotEmpty, MapEmpty, HasKey, NoKey |
maps |
IsTrue, IsFalse |
bool |
Before, After, Equal, Between |
time.Time |
ContainsStr, Regexp |
string |
ContainsBytes |
[]byte |
Eq |
any value |
MinLen is for text. Slice length is MinItems.
Email, IPv4, IPv6, and URL checks live in validators/primitive and already include a field name, so call them directly:
import "github.com/lyonnee/hvalid/validators/primitive"
err := primitive.NewStringValidator("email").IsEmail()("user@example.com")go test ./...MIT. See LICENSE.