validate

package
v0.31.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2025 License: Unlicense Imports: 3 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Append

func Append(errs []error, name string, v Interface) (res []error)

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

func AppendSlice[T Interface](errs []error, name string, values []T) (res []error)

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

func EmptySlice[T any](name string, v []T) (err error)

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

func GreaterThan[T cmp.Ordered](name string, a, b T) (err error)

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

func InRange[T cmp.Ordered](name string, v, min, max T) (err error)

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

func LessThan[T cmp.Ordered](name string, a, b T) (err error)

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

func NoGreaterThan[T cmp.Ordered](name string, v, max T) (err error)

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

func NoLessThan[T cmp.Ordered](name string, v, min T) (err error)

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

func NotEmptySlice[T any](name string, v []T) (err error)

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

func NotNegative[T cmp.Ordered](name string, v T) (err error)

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

func NotNil[T any](name string, v *T) (err error)

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

func Positive[T cmp.Ordered](name string, v T) (err error)

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

func Slice[T Interface](name string, values []T) (err error)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL