Help us shape the future of Go! Take the 2026 Go Developer Survey

valid

package
v1.27.1 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package valid provides declarative, type-safe struct validation. A field is a name, a value, and a list of rules; a rule is just `func(T) error`, so any custom validator is a first-class rule with no wrapper:

func (in CreateInput) Validate() valid.Problems {
	return valid.Validate(
		valid.String("name", in.Name, valid.Required, valid.MinLength(3)),
		valid.String("host", in.Host, valid.Required, isSubdomain), // isSubdomain: func(string) error
		valid.Number("ttl", in.TTL, valid.Required, valid.Max(100)),
		valid.Slice("values", in.Values, valid.NotEmpty, valid.Each(isIPv4)),
	)
}

Type safety comes from the per-type constructors: String only accepts Rule[~string], Number only Rule[number], Slice only Rule[[]T] — so a string rule cannot be attached to a number field, and Each([]T)'s element rules are keyed to the element type.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Domain added in v1.26.0

func Domain(s string) error

Domain asserts the string is a valid domain name (e.g. example.com).

func IP added in v1.26.0

func IP(s string) error

IP asserts the string is a valid IPv4 or IPv6 address.

func NotBlank

func NotBlank[T ~string](v T) error

NotBlank asserts the string is not empty after trimming whitespace.

func NotEmpty

func NotEmpty[T any](v []T) error

NotEmpty asserts the slice has at least one element.

func Required

func Required[T comparable](v T) error

Required asserts a comparable value is not its zero value (empty string, zero number, zero-value enum). For slices use NotEmpty.

func URL added in v1.26.0

func URL(s string) error

URL asserts the string is a valid absolute URL with a scheme and host.

Types

type Problems

type Problems map[string]string

Problems maps a json-style field name to its validation problem. nil means no problems. It is a defined type so it reads as a domain type at call sites and leaves room to grow, while still marshaling like its underlying map and being assignable to a plain map[string]string.

func Validate

func Validate(fields ...Validatable) Problems

Validate runs the given fields and merges their problems into a single flat map of field name -> problem. Within a field the first failing rule wins; if two fields produce the same key the first is kept. It returns nil when everything is valid.

func (Problems) Error added in v1.26.0

func (p Problems) Error() string

Error renders problems as "key: msg; key2: msg2" with keys sorted, letting a non-empty Problems be returned where an error is expected. Guard with Ok() to return a nil error when there are no problems.

func (Problems) Ok

func (p Problems) Ok() bool

Ok reports whether there are no problems.

type Rule

type Rule[T any] func(T) error

Rule validates a value of type T, returning an error whose message becomes the field's problem, or nil when the value is ok.

func Each

func Each[T any](rules ...Rule[T]) Rule[[]T]

Each wraps per-element rules into a single slice rule, reporting "element #i: <problem>" on the first failing element.

func In

func In[T ~string](allowed ...T) Rule[T]

In asserts the value equals one of the allowed values. It accepts ~string values (e.g. enum value slices via In(TypeValues()...)) and is usable inside Each.

func Match

func Match(re *regexp.Regexp, msg string) Rule[string]

Match asserts the string matches re, reporting msg on failure.

func Max

func Max[T number](n T) Rule[T]

Max asserts the number is at most n.

func MaxLength

func MaxLength(n int) Rule[string]

MaxLength asserts the string has at most n characters.

func Min

func Min[T number](n T) Rule[T]

Min asserts the number is at least n.

func MinLength

func MinLength(n int) Rule[string]

MinLength asserts the string has at least n characters.

type Validatable added in v1.26.0

type Validatable interface {
	// Validate returns problems keyed relative to this value: a leaf returns
	// {name: msg}, a nested struct returns {name.child: msg, ...}; nil when ok.
	Validate() Problems
}

Validatable is anything that validates itself, returning a flat map of keyed problems (nil when ok). Both the leaf fields built by String/Number/Slice and domain types (e.g. service Input types exposing Validate() Problems) satisfy it, so a Validatable can be a single field in a Validate(...) call or a nested struct folded in via Struct, which namespaces its keys.

func Number

func Number[T number](name string, value T, rules ...Rule[T]) Validatable

Number validates a numeric field.

func OptionalString

func OptionalString[T ~string](name string, value *T, rules ...Rule[T]) Validatable

OptionalString validates an optional string field addressed by a pointer. When the pointer is nil the field is treated as absent (no rules run).

func Slice

func Slice[T any](name string, value []T, rules ...Rule[[]T]) Validatable

Slice validates a slice field. Rules operate on the whole slice (e.g. NotEmpty, MinItems); use Each to apply per-element rules.

func String

func String[T ~string](name string, value T, rules ...Rule[T]) Validatable

String validates a string (or ~string, e.g. an enum) field.

func Struct added in v1.26.0

func Struct(name string, value Validatable) Validatable

Struct validates a nested Validatable, namespacing its problems under name (name.<child key>), so nesting composes to arbitrary depth (a.b.c). Pass a value whose Validate() satisfies Validatable — e.g. &in.Inner when Validate has a pointer receiver. A nil value is skipped, so an optional nested struct can be passed directly. Note: a typed nil pointer is not a nil interface — a caller with an optional *Inner field should pass a genuine nil.

Jump to

Keyboard shortcuts

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