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 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 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 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 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 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 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.