Documentation
¶
Overview ¶
Package validate contains functions for validating values.
The common argument name can be the name of the JSON or YAML property, the name of a function argument, or anything similar.
NOTE: More specific validations, like those of network addresses or URLs, should be put into related utility packages.
TODO(a.garipov): Add a function that validates for both nilness and emptiness.
TODO(a.garipov): Consider adding validate.KeyValues.
Example (WithNaN) ¶
package main
import (
"fmt"
"math"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
nan := math.NaN()
fmt.Println(validate.InRange("foo", nan, 0, 1))
fmt.Println(validate.NotNegative("foo", nan))
fmt.Println(validate.Positive("foo", nan))
}
Output: foo: out of range: must be no less than 0, got NaN foo: negative value: NaN foo: not positive: NaN
Index ¶
- func Append(errs []error, name string, v Interface) (res []error)
- func AppendSlice[T Interface](errs []error, name string, values []T) (res []error)
- func Empty[T comparable](name string, v T) (err error)
- func EmptySlice[T any](name string, v []T) (err error)
- func Equal[T comparable](name string, got, want T) (err error)
- func GreaterThan[T cmp.Ordered](name string, a, b T) (err error)
- func InRange[T cmp.Ordered](name string, v, min, max T) (err error)
- func LessThan[T cmp.Ordered](name string, a, b T) (err error)
- func Nil[T any](name string, v *T) (err error)
- func NoGreaterThan[T cmp.Ordered](name string, v, max T) (err error)
- func NoLessThan[T cmp.Ordered](name string, v, min T) (err error)
- func NotEmpty[T comparable](name string, v T) (err error)
- func NotEmptySlice[T any](name string, v []T) (err error)
- func NotNegative[T cmp.Ordered](name string, v T) (err error)
- func NotNil[T any](name string, v *T) (err error)
- func NotNilInterface(name string, v any) (err error)
- func Positive[T cmp.Ordered](name string, v T) (err error)
- func Slice[T Interface](name string, values []T) (err error)
- type Interface
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Append ¶
Append validates v and, if it returns an error, appends it to errs and returns the result.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/validate"
)
// value is a simple value that returns err in [value.Validate].
type value struct {
err error
}
// Validate implements the [validate.Interface] interface for *Value.
func (v *value) Validate() (err error) {
return v.err
}
func main() {
var errs []error
var (
badValue = &value{
err: errors.Error("test error"),
}
goodValue = &value{}
)
errs = validate.Append(errs, "first_value", goodValue)
errs = validate.Append(errs, "second_value", badValue)
fmt.Println(errors.Join(errs...))
}
Output: second_value: test error
func AppendSlice ¶
AppendSlice validates values, wraps errors with the name and the index, appends them to errs, and returns the result.
func Empty ¶ added in v0.31.1
func Empty[T comparable](name string, v T) (err error)
Empty returns an error if v is not equal to its zero value. The underlying error of err is errors.ErrNotEmpty.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.Empty("foo", "value"))
fmt.Println(validate.Empty("foo", ""))
}
Output: foo: not empty <nil>
func EmptySlice ¶ added in v0.31.1
EmptySlice returns an error if v is neither nil nor empty. The underlying error of err is either errors.ErrNotEmpty.
TODO(a.garipov): Find ways of extending to other nilable types with length.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.EmptySlice("foo", []int{1}))
fmt.Println(validate.EmptySlice("foo", []int(nil)))
fmt.Println(validate.EmptySlice("foo", []int{}))
}
Output: foo: not empty <nil> <nil>
func Equal ¶ added in v0.32.11
func Equal[T comparable](name string, got, want T) (err error)
Equal returns an error if got is not equal to want. The underlying error of err is errors.ErrNotEqual.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.Equal("foo", "bar", "baz"))
fmt.Println(validate.Equal("foo", "bar", "bar"))
}
Output: foo: not equal to expected value: got bar, want baz <nil>
func GreaterThan ¶ added in v0.31.1
GreaterThan returns an error if a is less than or equal to b. The underlying error of err is errors.ErrOutOfRange.
NOTE: NaN is also considered less than anything, since cmp.Compare sorts it below -Infinity.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.GreaterThan("foo", 0, 0))
fmt.Println(validate.GreaterThan("foo", 0, 1))
fmt.Println(validate.GreaterThan("foo", 1, 0))
}
Output: foo: out of range: must be greater than 0, got 0 foo: out of range: must be greater than 1, got 0 <nil>
func InRange ¶
InRange returns an error of v is less than min or greater than max. The underlying error of err is errors.ErrOutOfRange.
NOTE: NaN is also considered less than anything, since cmp.Compare sorts it below -Infinity.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.InRange("foo", 0, 0, 100))
fmt.Println(validate.InRange("foo", 100, 0, 100))
fmt.Println(validate.InRange("foo", 101, 0, 100))
fmt.Println(validate.InRange("foo", -1, 0, 100))
}
Output: <nil> <nil> foo: out of range: must be no greater than 100, got 101 foo: out of range: must be no less than 0, got -1
func LessThan ¶ added in v0.31.1
LessThan returns an error if a is greater than or equal to b. The underlying error of err is errors.ErrOutOfRange.
NOTE: NaN is also considered less than anything, since cmp.Compare sorts it below -Infinity.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.LessThan("foo", 0, 0))
fmt.Println(validate.LessThan("foo", 0, 1))
fmt.Println(validate.LessThan("foo", 1, 0))
}
Output: foo: out of range: must be less than 0, got 0 <nil> foo: out of range: must be less than 0, got 1
func Nil ¶ added in v0.32.8
Nil returns an error if v is not nil. The underlying error of err is errors.ErrUnexpectedValue.
For checking against emptiness (comparing with the zero value), prefer Empty.
TODO(a.garipov): Find ways of extending to other nilable types.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
var p *int
fmt.Println(validate.Nil("p", p))
p = new(int)
fmt.Println(validate.Nil("p", p))
}
Output: <nil> p: unexpected value
func NoGreaterThan ¶
NoGreaterThan returns an error if v is greater than max. The underlying error of err is errors.ErrOutOfRange.
NOTE: NaN is also considered less than anything, since cmp.Compare sorts it below -Infinity.
func NoLessThan ¶
NoLessThan returns an error if v is less than min. The underlying error of err is errors.ErrOutOfRange.
NOTE: NaN is also considered less than anything, since cmp.Compare sorts it below -Infinity.
func NotEmpty ¶
func NotEmpty[T comparable](name string, v T) (err error)
NotEmpty returns an error if v is its zero value. The underlying error of err is errors.ErrEmpty.
For pointers, prefer NotNil.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.NotEmpty("foo", "value"))
fmt.Println(validate.NotEmpty("foo", ""))
type Bar struct {
Field int
}
fmt.Println(validate.NotEmpty("bar", Bar{Field: 1}))
fmt.Println(validate.NotEmpty("bar", Bar{}))
}
Output: <nil> foo: empty value <nil> bar: empty value
func NotEmptySlice ¶
NotEmptySlice returns an error if v is nil or empty. The underlying error of err is either errors.ErrNoValue or errors.ErrEmpty correspondingly.
TODO(a.garipov): Find ways of extending to other nilable types with length.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.NotEmptySlice("foo", []int{1}))
fmt.Println(validate.NotEmptySlice("foo", []int(nil)))
fmt.Println(validate.NotEmptySlice("foo", []int{}))
}
Output: <nil> foo: no value foo: empty value
func NotNegative ¶
NotNegative returns an error if v is less than the zero value of type T. The underlying error of err is errors.ErrNegative.
NOTE: NaN is also considered negative, since cmp.Compare sorts it below -Infinity.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.NotNegative("foo", 1))
fmt.Println(validate.NotNegative("foo", 0))
fmt.Println(validate.NotNegative("foo", -1))
}
Output: <nil> <nil> foo: negative value: -1
func NotNil ¶
NotNil returns an error if v is nil. The underlying error of err is errors.ErrNoValue.
For checking against emptiness (comparing with the zero value), prefer NotEmpty.
TODO(a.garipov): Find ways of extending to other nilable types.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
v := 1
fmt.Println(validate.NotNil("foo", &v))
fmt.Println(validate.NotNil("foo", (*int)(nil)))
}
Output: <nil> foo: no value
func NotNilInterface ¶ added in v0.31.2
NotNilInterface returns an error if v is nil. The underlying error of err is errors.ErrNoValue.
For checking against emptiness (comparing with the zero value), prefer NotEmpty.
NOTE: This function returns an error only if v is a nil interface value. This means that if v is an interface value with a type and a nil pointer, err is nil.
TODO(a.garipov): Find ways of merging with NotNil.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
var v any
fmt.Println(validate.NotNilInterface("foo", v))
type T struct{}
v = T{}
fmt.Println(validate.NotNilInterface("foo", v))
// NOTE: A typed but nil interface value, be careful!
v = (*T)(nil)
fmt.Println(validate.NotNilInterface("foo", v))
}
Output: foo: no value <nil> <nil>
func Positive ¶
Positive returns an error if v is less than or equal to the zero value of type T. The underlying error of err is errors.ErrNotPositive.
NOTE: NaN is also considered negative, since cmp.Compare sorts it below -Infinity.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/validate"
)
func main() {
fmt.Println(validate.Positive("foo", 1))
fmt.Println(validate.Positive("foo", 0))
fmt.Println(validate.Positive("foo", -1))
}
Output: <nil> foo: not positive: 0 foo: not positive: -1
func Slice ¶
Slice validates values, wraps errors with the name and the index, and returns the result as a single joined error.
Example ¶
package main
import (
"fmt"
"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/validate"
)
// value is a simple value that returns err in [value.Validate].
type value struct {
err error
}
// Validate implements the [validate.Interface] interface for *Value.
func (v *value) Validate() (err error) {
return v.err
}
func main() {
values := []*value{
0: {
err: nil,
},
1: {
err: errors.Error("test error 1"),
},
2: {
err: errors.Error("test error 2"),
},
}
fmt.Println(validate.Slice("values", values))
}
Output: values: at index 1: test error 1 values: at index 2: test error 2
Types ¶
type Interface ¶
type Interface interface {
// Validate returns an error if the entity isn't valid. Entities should not
// add a prefix; instead, the callers should add prefixes depending on the
// use.
Validate() (err error)
}
Interface is the interface for configuration entities that can validate themselves.