Documentation
¶
Overview ¶
Package validation provides typed rules and owned validation diagnostics. Generated declarations compose these same rules; transport adapters own decoding, presence discovery and HTTP error mapping.
Index ¶
- Constants
- func Check[T any](r Rule[T], ctx context.Context, input T, limits Limits) error
- func CheckProhibitions[T any](r Rule[T], ctx context.Context, input T, limits Limits) error
- func FieldName[T, V any](f Field[T, V]) string
- func MessageDefinitions() []i18n.MessageDefinition
- func Select[T, V any](f Field[T, V], input T) (V, error)
- func ValidateField[T, V any](f Field[T, V]) error
- func ValidateMessages(description Description, catalog *i18n.Catalog) error
- func ValidateRule[T any](r Rule[T]) error
- type AnyLookup
- type BatchLookup
- type Description
- type DimensionConstraints
- type Errors
- func (*Errors) Error() string
- func (*Errors) Is(target error) bool
- func (e *Errors) Issues() []contract.Issue
- func (e *Errors) Localize(ctx context.Context, catalog *i18n.Catalog, locale i18n.LocaleID) (*Errors, error)
- func (e *Errors) LocalizeLabels(ctx context.Context, catalog *i18n.Catalog, locale i18n.LocaleID) (*Errors, error)
- func (e *Errors) Truncated() bool
- type Field
- type FileValue
- type ImageMeasurer
- type ImageSize
- type Integer
- type Kind
- type LimitError
- type Limits
- type Lookup
- type MapKey
- type NowTemporal
- type Number
- type Pair
- type Parameter
- type PasswordOptions
- type Rejection
- type Report
- type Rule
- func ASCII[S ~string]() Rule[S]
- func Absent[T any]() Rule[value.Optional[T]]
- func Accepted[B ~bool]() Rule[B]
- func After[T Temporal](bound T) Rule[T]
- func AfterField[T any, V Temporal](field, other Field[T, V]) Rule[T]
- func AfterNow[T NowTemporal](service temporal.Service) Rule[T]
- func AfterOrEqual[T Temporal](bound T) Rule[T]
- func AfterOrEqualField[T any, V Temporal](field, other Field[T, V]) Rule[T]
- func AfterOrEqualNow[T NowTemporal](service temporal.Service) Rule[T]
- func AfterOrEqualToday[T TodayTemporal](service temporal.Service) Rule[T]
- func AfterToday[T TodayTemporal](service temporal.Service) Rule[T]
- func All[T any](rules ...Rule[T]) Rule[T]
- func Alpha[S ~string]() Rule[S]
- func AlphaDash[S ~string]() Rule[S]
- func AlphaNumeric[S ~string]() Rule[S]
- func Bail[T any](rules ...Rule[T]) Rule[T]
- func Before[T Temporal](bound T) Rule[T]
- func BeforeField[T any, V Temporal](field, other Field[T, V]) Rule[T]
- func BeforeNow[T NowTemporal](service temporal.Service) Rule[T]
- func BeforeOrEqual[T Temporal](bound T) Rule[T]
- func BeforeOrEqualField[T any, V Temporal](field, other Field[T, V]) Rule[T]
- func BeforeOrEqualNow[T NowTemporal](service temporal.Service) Rule[T]
- func BeforeOrEqualToday[T TodayTemporal](service temporal.Service) Rule[T]
- func BeforeToday[T TodayTemporal](service temporal.Service) Rule[T]
- func Between[N Number](minimum, maximum N) Rule[N]
- func Compare[T, V any](field, other Field[T, V], comparator Rule[Pair[V]]) Rule[T]
- func Confirmed[T any, V Scalar](field, confirmation Field[T, V]) Rule[T]
- func Contains[S ~string](part S) Rule[S]
- func ContainsItems[S ~[]T, T Scalar](members ...T) Rule[S]
- func Custom[T any](spec Spec, check func(context.Context, T) (bool, error)) Rule[T]
- func Date[S ~string]() Rule[S]
- func DateFormat[S ~string](layout string) Rule[S]
- func DateTime[S ~string]() Rule[S]
- func DecimalBetween(minimum, maximum decimal.Decimal) Rule[decimal.Decimal]
- func DecimalGreaterOrEqual() Rule[Pair[decimal.Decimal]]
- func DecimalGreaterThan() Rule[Pair[decimal.Decimal]]
- func DecimalLessOrEqual() Rule[Pair[decimal.Decimal]]
- func DecimalLessThan() Rule[Pair[decimal.Decimal]]
- func DecimalMax(maximum decimal.Decimal) Rule[decimal.Decimal]
- func DecimalMaxPlaces(maximum int) Rule[decimal.Decimal]
- func DecimalMin(minimum decimal.Decimal) Rule[decimal.Decimal]
- func DecimalMultipleOf(divisor decimal.Decimal) Rule[decimal.Decimal]
- func DecimalPositive() Rule[decimal.Decimal]
- func Declined[B ~bool]() Rule[B]
- func Different[V Scalar]() Rule[Pair[V]]
- func Digits[S ~string]() Rule[S]
- func DigitsBetween[S ~string](minimum, maximum int) Rule[S]
- func Dimensions[F any](measurer ImageMeasurer[F], constraints DimensionConstraints) Rule[F]
- func Distinct[S ~[]T, T Scalar]() Rule[S]
- func DistinctBy[S ~[]T, T any, K Scalar](field Field[T, K]) Rule[S]
- func DistinctIgnoringCase[S ~[]T, T ~string]() Rule[S]
- func DoesntContain[S ~string](part S) Rule[S]
- func DoesntEndWith[S ~string](suffix S) Rule[S]
- func DoesntStartWith[S ~string](prefix S) Rule[S]
- func Dynamic[T any](spec Spec, check func(context.Context, T) (Rejection, error)) Rule[T]
- func Each[S ~[]T, T any](rules ...Rule[T]) Rule[S]
- func EachKey[M ~map[K]V, K MapKey, V any](rules ...Rule[K]) Rule[M]
- func EachValue[M ~map[K]V, K MapKey, V any](rules ...Rule[V]) Rule[M]
- func Email[S ~string]() Rule[S]
- func Embed[Outer, Inner any](rule Rule[Inner], selector func(Outer) Inner) Rule[Outer]
- func Empty[T any]() Rule[T]
- func EndsWith[S ~string](suffix S) Rule[S]
- func Enum[E enum.Scalar](descriptor enum.Descriptor[E]) Rule[E]
- func ExcludesItems[S ~[]T, T Scalar](members ...T) Rule[S]
- func Exists[T any](lookup Lookup[T]) Rule[T]
- func ExistsAll[S ~[]T, T any](lookup BatchLookup[T]) Rule[S]
- func ExistsEach[S ~[]E, E, V any](field Field[E, V], lookup BatchLookup[V]) Rule[S]
- func FileContentTypes[F FileValue](allowed ...string) Rule[F]
- func FileExtensions[F FileValue](allowed ...string) Rule[F]
- func FileMaxSize[F FileValue](maximum int64) Rule[F]
- func FileMinSize[F FileValue](minimum int64) Rule[F]
- func FilePresent[F FileValue]() Rule[F]
- func GreaterOrEqual[N Number]() Rule[Pair[N]]
- func GreaterThan[N Number]() Rule[Pair[N]]
- func HexColor[S ~string]() Rule[S]
- func Hook[T any](spec Spec, hook func(context.Context, T, *Report) error) Rule[T]
- func IP[S ~string]() Rule[S]
- func IPv4[S ~string]() Rule[S]
- func IPv6[S ~string]() Rule[S]
- func Items[S ~[]T, T any](count int) Rule[S]
- func ItemsBetween[S ~[]T, T any](minimum, maximum int) Rule[S]
- func JSON[S ~string]() Rule[S]
- func Length[S ~string](count int) Rule[S]
- func LengthBetween[S ~string](minimum, maximum int) Rule[S]
- func LessOrEqual[N Number]() Rule[Pair[N]]
- func LessThan[N Number]() Rule[Pair[N]]
- func LocalDateTime[S ~string]() Rule[S]
- func Locales[M ~map[i18n.LocaleID]V, V ~string](catalog i18n.LocaleCatalog, require i18n.LocaleRequirement) Rule[M]
- func Lowercase[S ~string]() Rule[S]
- func MACAddress[S ~string]() Rule[S]
- func Matches[S ~string](pattern string) Rule[S]
- func Max[N Number](maximum N) Rule[N]
- func MaxBytes[S ~string](maximum int) Rule[S]
- func MaxDigits[S ~string](maximum int) Rule[S]
- func MaxItems[S ~[]T, T any](maximum int) Rule[S]
- func MaxLength[S ~string](maximum int) Rule[S]
- func Min[N Number](minimum N) Rule[N]
- func MinDigits[S ~string](minimum int) Rule[S]
- func MinItems[S ~[]T, T any](minimum int) Rule[S]
- func MinLength[S ~string](minimum int) Rule[S]
- func MultipleOf[N Integer](divisor N) Rule[N]
- func NonBlank[S ~string]() Rule[S]
- func NonEmpty[T any]() Rule[T]
- func NotMatches[S ~string](pattern string) Rule[S]
- func NotNil[T any]() Rule[*T]
- func NotNull[T any]() Rule[value.Nullable[T]]
- func NotOneOf[K Scalar](values ...K) Rule[K]
- func Nullable[T any](rules ...Rule[T]) Rule[value.Nullable[T]]
- func OneOf[K Scalar](values ...K) Rule[K]
- func Optional[T any](rules ...Rule[T]) Rule[value.Optional[T]]
- func Parallel[T any](rules ...Rule[T]) Rule[T]
- func ParallelLimit[T any](concurrency int, rules ...Rule[T]) Rule[T]
- func Password[S ~string](options PasswordOptions) Rule[S]
- func PasswordValue[P interface{ ... }](options PasswordOptions) Rule[P]
- func Pointer[T any](rules ...Rule[T]) Rule[*T]
- func Positive[N Number]() Rule[N]
- func Present[T any]() Rule[value.Optional[T]]
- func Prohibited[T any]() Rule[value.Optional[T]]
- func ProhibitedNullable[T any]() Rule[value.Optional[value.Nullable[T]]]
- func Provide[T, P any](slot Slot[P], derive func(context.Context, T) (P, error), rules ...Rule[T]) Rule[T]
- func Required[T any](rules ...Rule[T]) Rule[value.Optional[T]]
- func RequiredNullable[T any](rules ...Rule[T]) Rule[value.Optional[value.Nullable[T]]]
- func Requires[T, P any](slot Slot[P], rule Rule[T]) Rule[T]
- func Rules[T, V any](f Field[T, V], rules ...Rule[V]) Rule[T]
- func Same[V Scalar]() Rule[Pair[V]]
- func StartsWith[S ~string](prefix S) Rule[S]
- func Time[S ~string]() Rule[S]
- func Timezone[S ~string]() Rule[S]
- func ULID[S ~string]() Rule[S]
- func URL[S ~string]() Rule[S]
- func UUID[S ~string]() Rule[S]
- func Unique[T any](lookup Lookup[T]) Rule[T]
- func UniqueAll[S ~[]T, T any](lookup AnyLookup[T]) Rule[S]
- func UniqueEach[S ~[]E, E, V any](field Field[E, V], lookup AnyLookup[V]) Rule[S]
- func Unless[T any](condition Rule[T], rules ...Rule[T]) Rule[T]
- func Uppercase[S ~string]() Rule[S]
- func When[T any](condition Rule[T], rules ...Rule[T]) Rule[T]
- func WithMessage[T any](r Rule[T], message string) Rule[T]
- func WithTranslation[T, A any](rule Rule[T], translated message.Message[A], args A) Rule[T]
- type RuleID
- type Scalar
- type Slot
- type Spec
- type Temporal
- type TodayTemporal
Constants ¶
const DefaultConcurrency = 4
Variables ¶
This section is empty.
Functions ¶
func Check ¶ added in v0.2.0
Check executes owned callbacks and returns nil only after all applicable checks pass. Input and referenced data must remain unchanged until return. Panics and infrastructure errors remain internal faults. A tree containing application callbacks (Custom, Dynamic, Hook, lookups, Provide, image measurement) runs in one owned goroutine so runtime.Goexit is also contained; other trees run inline without a goroutine, where Goexit in a selector or value method ends the caller like any Go function. Cancellation never abandons a selector or custom rule that still owns work. Valid input allocates no issue storage or JSON Pointer paths.
func CheckProhibitions ¶ added in v0.2.0
CheckProhibitions checks only built-in Prohibited/Absent rules on original decoded input before preparation. Conditions retain their original-input semantics. It does not substitute for Check on the prepared value.
func FieldName ¶ added in v0.2.0
FieldName returns the generated transport property name, shared by validation and other typed field consumers. ValidateField rejects an undefined descriptor.
func MessageDefinitions ¶
func MessageDefinitions() []i18n.MessageDefinition
MessageDefinitions registers every built-in rule's translation signature. The returned values are owned snapshots. English fallback text is retained by the rule even when English is not an enabled catalog/request locale.
func Select ¶ added in v0.2.0
Select reads this exact field without reflection or a second getter map. Like a direct application getter, it executes synchronously; services using custom selectors own callback isolation, cancellation and input lifetime.
func ValidateField ¶ added in v0.2.0
ValidateField checks the name and selector without executing it.
func ValidateMessages ¶
func ValidateMessages(description Description, catalog *i18n.Catalog) error
ValidateMessages checks a rule description against a catalog at startup. Missing definitions are optional (English fallback); registered signatures and parameter-free label declarations must match. No selectors or checks execute.
func ValidateRule ¶ added in v0.2.0
ValidateRule checks the declaration without executing selectors or callbacks. A rule reading a Slot is complete only inside a Provide for that slot.
Types ¶
type AnyLookup ¶
type AnyLookup[T any] interface { // Validate checks the lookup's configuration. Validate() error // AnyExist reports whether any supplied value exists. AnyExist(context.Context, []T) (bool, error) }
AnyLookup reports whether any value of a collection exists, in bounded batches. It backs UniqueAll and UniqueEach with the Lookup ownership contract.
type BatchLookup ¶
type BatchLookup[T any] interface { // Validate checks the lookup's configuration. Validate() error // AllExist reports whether all supplied values exist. AllExist(context.Context, []T) (bool, error) }
BatchLookup checks a collection in bounded batches rather than one remote call per value. Implementations retain the same error/ownership contract as Lookup. Empty input succeeds without I/O; use MinItems to require selection.
type Description ¶
type Description struct {
Kind Kind `json:"kind"`
Field string `json:"field,omitempty"`
OtherField string `json:"other_field,omitempty"`
Label string `json:"label,omitempty"`
OtherLabel string `json:"other_label,omitempty"`
LabelKey i18n.MessageKey `json:"label_key,omitempty"`
OtherLabelKey i18n.MessageKey `json:"other_label_key,omitempty"`
Spec *Spec `json:"spec,omitempty"`
ServerOnly bool `json:"server_only,omitempty"`
Children []Description `json:"children,omitempty"`
}
Description is an owned rule tree. Kind defines composition; Spec describes a leaf. Field carries a declared wire name; Label is its optional static display name. OtherField/OtherLabel describe a comparison target. ServerOnly marks rules whose behavior cannot be promised by a browser validator.
func DescribeRule ¶ added in v0.2.0
func DescribeRule[T any](r Rule[T]) (Description, error)
DescribeRule returns an independent snapshot of the same rule tree Check uses. A subtree awaiting its enclosing Provide can still be described.
func (Description) Normalize ¶
func (d Description) Normalize() (Description, error)
Normalize validates and owns serialized inspection metadata. It reuses rule parameter validation and composition budgets; it creates no executable rule and does not claim that a custom/server-only rule runs in a browser.
type DimensionConstraints ¶
type DimensionConstraints struct {
MinWidth, MaxWidth, MinHeight, MaxHeight int
Width, Height int
RatioWidth, RatioHeight int
}
DimensionConstraints bound an image's pixel size. Zero fields are unbounded; at least one constraint is required. RatioWidth and RatioHeight together require an exact aspect ratio, such as 16 by 9.
func (DimensionConstraints) Validate ¶
func (c DimensionConstraints) Validate() error
Validate checks dimension bounds, paired ratio values, and the presence of at least one constraint.
type Errors ¶
type Errors struct {
// contains filtered or unexported fields
}
Errors reports rejected input. Truncated reports that the issue cap stopped further validation; it does not claim the omitted checks would have failed.
func (*Errors) Localize ¶
func (e *Errors) Localize(ctx context.Context, catalog *i18n.Catalog, locale i18n.LocaleID) (*Errors, error)
Localize returns owned labels/messages using a request-independent explicit catalog and locale. Codes, paths, order and truncation are unchanged. Missing translations retain English; conflicting declarations return an error.
func (*Errors) LocalizeLabels ¶
func (e *Errors) LocalizeLabels(ctx context.Context, catalog *i18n.Catalog, locale i18n.LocaleID) (*Errors, error)
LocalizeLabels returns independent diagnostics. Missing registered labels retain their existing static text; declaration/configuration failures return an error. Rule messages remain the rule's approved public text.
type Field ¶
type Field[T, V any] struct { // contains filtered or unexported fields }
Field retains both the containing request and concrete field value types. Generated declarations own names/selectors; this is their explicit constructor.
func DefineField ¶
DefineField declares a field selector, retaining an error for an invalid name or nil selector.
func WithLabel ¶ added in v0.2.0
WithLabel returns a field with a static public display name. It preserves the wire name, selector and concrete types. Diagnostics keep their JSON Pointer path and carry the label separately; built-in messages use this name. Nested fields select their own labels, while scalar collection items use their containing field's label. Localization produces an owned copy.
func WithLabelKey ¶ added in v0.2.0
func WithLabelKey[T, V any](f Field[T, V], key i18n.MessageKey) Field[T, V]
WithLabelKey attaches a parameter-free UI message while preserving the static label as the missing-translation fallback. It never changes the wire path.
type FileValue ¶
type FileValue interface {
// IsZero reports whether the file value is absent.
IsZero() bool
// Size returns the file size in bytes.
Size() int64
// ContentType returns the file's content type.
ContentType() string
// Extension returns the file's extension.
Extension() string
}
FileValue supplies captured file metadata. HTTP UploadedFile implements it; domain adapters must supply the same truthful metadata contract. These rules perform no I/O and never consult a client-declared content type. Metadata methods execute within the ordinary owned validation callback boundary.
type ImageMeasurer ¶
type ImageMeasurer[F any] interface { // Validate checks the image measurer's configuration. Validate() error // Measure measures image dimensions, reporting whether the input is a supported image. Measure(context.Context, F) (size ImageSize, ok bool, err error) }
ImageMeasurer reads an image file's dimensions without decoding pixels. ok=false reports a file that is absent, oversized or not a supported image, which rejects the input; an error is an execution failure. The imaging validation adapter supplies this from imaging.Inspect.
type ImageSize ¶
type ImageSize struct{ Width, Height int }
ImageSize is inspected image metadata in displayed orientation.
type Integer ¶
type Integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
Integer restricts exact modulo checks to ordinary or named integer values.
type Kind ¶
type Kind string
Kind identifies validation metadata kinds.
const ( LeafKind Kind = "rule" AllKind Kind = "all" BailKind Kind = "bail" FieldKind Kind = "field" CompareKind Kind = "compare" OptionalKind Kind = "optional" NullableKind Kind = "nullable" EachKind Kind = "each" WhenKind Kind = "when" UnlessKind Kind = "unless" PointerKind Kind = "pointer" // EachKeyKind and EachValueKind visit map entries in ascending key order. EachKeyKind Kind = "each_key" EachValueKind Kind = "each_value" )
type LimitError ¶
type LimitError struct{}
LimitError means validation could not complete within its work/value bound. It is distinct from rejected rule input and never establishes a valid result.
func (*LimitError) Error ¶
func (*LimitError) Error() string
Error returns the fixed validation budget exhaustion message.
func (*LimitError) Is ¶
func (*LimitError) Is(target error) bool
Is reports whether the target is fault.Invalid.
type Limits ¶
Limits bounds one Check. Checks counts rule and field visits; Issues caps retained diagnostics. Depth bounds composition and ValueBytes bounds native text before scanning it. Callbacks own their internal work and allocations.
func DefaultLimits ¶
func DefaultLimits() Limits
DefaultLimits returns default check, issue, depth, and value byte budgets.
type Lookup ¶
type Lookup[T any] interface { // Validate checks the lookup's configuration. Validate() error // Exists reports whether the supplied value exists. Exists(context.Context, T) (bool, error) }
Lookup checks whether a concrete value exists in an explicitly scoped source. Validate checks its declaration without I/O. Exists must honor the context and retain ownership of its work until return. The database adapter supplies this contract from ORM declarations; applications can provide other typed sources.
type MapKey ¶
MapKey is a native JSON object key: ordinary or named text or integers. Keys with custom JSON/text codecs are rejected because their wire names are not their native values.
type NowTemporal ¶
type NowTemporal interface {
time.Time | temporal.DateTime | temporal.LocalDateTime
// String returns the temporal value's text representation.
String() string
}
NowTemporal values compare with the current time: instants directly and local date-times with the current wall time in the service's timezone.
type Number ¶
type Number interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64
}
Number is the set of integer and floating-point types supported by numeric rules.
type Pair ¶
type Pair[V any] struct{ Left, Right V }
Pair retains both values' concrete type for reusable comparison rules.
type Parameter ¶
type Parameter struct {
Name string `json:"name"`
Value json.RawMessage `json:"value"`
}
Parameter is declaration metadata, never a received field value. Values are bounded, valid JSON and copied at construction and inspection boundaries.
type PasswordOptions ¶
type PasswordOptions struct {
MinLength int
MaxLength int
Letters bool
MixedCase bool
Numbers bool
Symbols bool
}
PasswordOptions counts Unicode code points. Composition requirements are opt-in; no normalization, trimming, hashing or external breach request occurs.
func DefaultPasswordOptions ¶
func DefaultPasswordOptions() PasswordOptions
DefaultPasswordOptions returns password length bounds of 12 through 128.
func (PasswordOptions) Validate ¶
func (o PasswordOptions) Validate() error
Validate checks that password length bounds are positive and ordered.
type Rejection ¶
type Rejection struct {
// contains filtered or unexported fields
}
Rejection is a message chosen at check time. The zero value accepts input. Messages are public text written by the application; never include secrets or unapproved submitted values.
func Reject ¶
Reject rejects input with literal public text. Empty text uses the rule's declared message (including its translation).
func RejectWith ¶
RejectWith rejects input with a generated typed message whose arguments are computed at check time, such as a remaining quota. It renders in the request locale like built-in messages; the rule's declared message is the English fallback. Arguments are bound only when the rejection is recorded.
type Report ¶
type Report struct {
// contains filtered or unexported fields
}
Report records Hook issues relative to the hook's input path. It is valid only during the hook call and is not safe for concurrent use.
func (*Report) Add ¶
Add rejects a location with the hook's declared message. Each path segment is one unescaped JSON object name or array index, relative to the hook's input. No segments address the input itself. Adds past the issue cap are dropped and mark the result truncated.
func (*Report) AddRejection ¶
AddRejection records a location with a check-time message.
type Rule ¶
type Rule[T any] struct { // contains filtered or unexported fields }
Rule retains its concrete input type. It is immutable after construction; Check may run concurrently on independent inputs. The zero value is invalid.
func Absent ¶
Absent requires omission. A supplied zero, empty or null value is still present; use explicit value rules when those representations should be allowed.
func AfterField ¶
AfterField requires the first field to be strictly after the second field.
func AfterNow ¶
func AfterNow[T NowTemporal](service temporal.Service) Rule[T]
AfterNow requires a value strictly after the current time. The clock is read at every check, never at construction. Pass the application's temporal service (application Services.Time) so frozen test clocks and the configured timezone apply; a zero Service makes the declaration invalid. Metadata is server-only.
func AfterOrEqual ¶
AfterOrEqual accepts values at or after their same-type temporal bound.
func AfterOrEqualField ¶
AfterOrEqualField requires the first field to be at or after the second field.
func AfterOrEqualNow ¶
func AfterOrEqualNow[T NowTemporal](service temporal.Service) Rule[T]
AfterOrEqualNow accepts the current time or later.
func AfterOrEqualToday ¶
func AfterOrEqualToday[T TodayTemporal](service temporal.Service) Rule[T]
AfterOrEqualToday accepts today or a later date.
func AfterToday ¶
func AfterToday[T TodayTemporal](service temporal.Service) Rule[T]
AfterToday requires a calendar date after today in the service's timezone, read at check time. Absent dates and out-of-range instants reject.
func Alpha ¶
Alpha accepts Unicode Alphabetic characters, including alphabetic marks. Empty text passes; use NonBlank for presence. Unicode-table behavior is server-only metadata because browser Unicode versions can differ.
func AlphaDash ¶
AlphaDash creates a rule accepting alphabetic runes, Unicode numbers, hyphens, and underscores.
func AlphaNumeric ¶
AlphaNumeric accepts Unicode Alphabetic and Number characters. It does not accept punctuation or normalize combining marks, case or scripts.
func Bail ¶
Bail stops this sequence after its first failed rule. Other object fields may still be checked by an enclosing All sequence.
func Before ¶
Before requires a temporal value strictly before its declared bound. Dates and local values compare in calendar order; instants compare in UTC without monotonic readings. No host timezone or current clock is consulted; use the relative BeforeNow/BeforeToday family for bounds read at check time.
func BeforeField ¶
BeforeField compares two generated fields while preserving their request and temporal value types. Failures use the first field's path; metadata retains both field names. Absent Date/LocalDateTime values reject rather than compare as calendar dates. Optional and nullable states require explicit wrappers.
func BeforeNow ¶
func BeforeNow[T NowTemporal](service temporal.Service) Rule[T]
BeforeNow requires a value strictly before the current time.
func BeforeOrEqual ¶
BeforeOrEqual also accepts a value equal to the bound, retaining nanoseconds.
func BeforeOrEqualField ¶
BeforeOrEqualField allows equality when comparing two same-type fields.
func BeforeOrEqualNow ¶
func BeforeOrEqualNow[T NowTemporal](service temporal.Service) Rule[T]
BeforeOrEqualNow accepts the current time or earlier.
func BeforeOrEqualToday ¶
func BeforeOrEqualToday[T TodayTemporal](service temporal.Service) Rule[T]
BeforeOrEqualToday accepts today or an earlier date.
func BeforeToday ¶
func BeforeToday[T TodayTemporal](service temporal.Service) Rule[T]
BeforeToday requires a date before today.
func Compare ¶
Compare binds a reusable comparator to fields with the same request and value types. Failures use the first field's wire path; metadata retains both names. Custom comparators use Custom[Pair[V]] and remain server-only.
func ContainsItems ¶
ContainsItems requires every declared scalar member at least once. It owns the declaration and scans input once; ExcludesItems prohibits any member.
func Custom ¶
Custom defines a typed server rule. Returning false rejects the input with Spec.Message; returning an error means execution failed, not invalid input. Reuse the returned rule value when sharing one definition across fields.
func Date ¶
Temporal text rules reuse the framework temporal parsers. Prefer concrete temporal DTO fields when the transport should decode a temporal value directly.
func DateFormat ¶
DateFormat accepts text written exactly in a Go reference-time layout, such as "2006-01-02" or "02/01/2006 15:04". The value must parse and format back to the same text, so optional padding and alternative zone spellings reject. The layout must round-trip the reference time. No timezone or clock is consulted; prefer concrete temporal DTO fields when the wire format is RFC 3339.
func DecimalBetween ¶
DecimalBetween combines inclusive decimal bounds, rejecting reversed bounds.
func DecimalGreaterOrEqual ¶
DecimalGreaterOrEqual creates a rule requiring the first decimal in a pair to be greater than or equal to the second.
func DecimalGreaterThan ¶
DecimalGreaterThan and its siblings compare two exact decimal fields through Compare, for example a maximum price against a minimum price. They never convert through floating point; failures use the first field's path.
func DecimalLessOrEqual ¶
DecimalLessOrEqual creates a rule requiring the first decimal in a pair to be less than or equal to the second.
func DecimalLessThan ¶
DecimalLessThan creates a rule requiring the first decimal in a pair to be less than the second.
func DecimalMax ¶
DecimalMax creates a rule requiring a decimal no greater than the maximum.
func DecimalMaxPlaces ¶
DecimalMaxPlaces limits significant fractional digits. Decimals are canonical, so 1.50 has one place; validate raw text when trailing zeros are significant.
func DecimalMin ¶
DecimalMin and DecimalMax preserve the framework's exact decimal comparison. Their metadata uses the same string representation as decimal DTO fields.
func DecimalMultipleOf ¶
DecimalMultipleOf requires an exact integer quotient, for example a quantity in 0.25 steps. The divisor must be positive; comparison is exact at any scale.
func DecimalPositive ¶
DecimalPositive accepts strictly positive decimals at every supported scale. Validation runs on the server, preserving exact decimal comparisons.
func Digits ¶
Digits accepts only ASCII digits, preserving leading zeros. Empty text passes; use NonBlank and length rules when the field must contain a fixed-size code.
func DigitsBetween ¶
DigitsBetween validates ASCII numeric text without discarding leading zeros.
func Dimensions ¶
func Dimensions[F any](measurer ImageMeasurer[F], constraints DimensionConstraints) Rule[F]
Dimensions checks an image's pixel size through an explicitly injected measurer. Files that are not supported images reject. Combine it with FileMaxSize so oversized uploads reject before any bytes are read.
func Distinct ¶
Distinct checks scalar slice values with native equality and bounded work. It reports at the collection's path and does not normalize or mutate values.
func DistinctBy ¶
DistinctBy checks a concrete field of each object without serializing objects. Failures belong to the collection; use Each for per-object value constraints.
func DistinctIgnoringCase ¶
DistinctIgnoringCase checks text elements for duplicates after Unicode case folding, so "Tag" and "tag" collide. Values are not modified. Folding follows the server's Unicode tables, so metadata is server-only.
func DoesntContain ¶
DoesntContain creates a rule excluding the supplied substring.
func DoesntEndWith ¶
DoesntEndWith creates a rule excluding the supplied suffix.
func DoesntStartWith ¶
DoesntStartWith creates a rule excluding the supplied prefix.
func Dynamic ¶
Dynamic defines a server rule whose rejection message is decided at check time. Return the zero Rejection to accept and an error when execution fails. Spec supplies the stable code and declared message; built-in IDs are reserved.
func Each ¶
Each checks an ordinary or named slice in input order and uses index paths. Empty slices have no elements; collection-size rules are separate.
func EachKey ¶
EachKey checks every key of a map. Entries are visited in ascending key order, so diagnostics are deterministic; each issue uses the entry's path, such as /labels/en. A nil or empty map has no keys. Metadata is server-only.
func EachValue ¶
EachValue checks every value of a map in ascending key order and reports at the entry's path. Use EachKey for key constraints.
func Email ¶
Email accepts a single bare mailbox using Go's net/mail parser. Display names, comments, angle wrappers and surrounding whitespace are rejected. It performs no DNS/delivery checks or normalization. Parser semantics remain server-only in metadata rather than claiming browser equivalence.
func Embed ¶
Embed applies an existing rule tree to a concrete value selected from an outer input, retaining the child's wire paths and metadata without a prefix. Use it when the outer transport flattens that value, such as EmbedQuery. Selectors must not mutate or retain input. Their work runs inside the same owned callback boundary and limits as the original rule tree.
func Empty ¶
Empty accepts blank text and empty collections. It does not treat numeric zero, false or a zero struct as null or omission. Text remains unchanged.
func Enum ¶
func Enum[E enum.Scalar](descriptor enum.Descriptor[E]) Rule[E]
Enum validates a concrete enum from its existing descriptor. Runtime values and actual wire cases share that descriptor; custom enum codecs are owned at construction and do not execute on each input check.
func ExcludesItems ¶
ExcludesItems creates a rule excluding the supplied member values from a slice.
func Exists ¶
Exists requires a matching value in the declared lookup. It is server-only and advisory: later changes can invalidate the observation. Input omission and nullability are handled by the normal Optional/Nullable adapters.
func ExistsAll ¶
func ExistsAll[S ~[]T, T any](lookup BatchLookup[T]) Rule[S]
ExistsAll validates all values against one scoped source. Valid input costs one batched observation (split into the lookup's own statement batches). A rejection is located with bounded additional batch observations and reported at each missing element's index path, such as /tags/3, using the collection's label. The issue does not distinguish a nonexistent value from an inaccessible one. Every item is charged against the shared work budget before any I/O, and each observation costs one further check.
func ExistsEach ¶
func ExistsEach[S ~[]E, E, V any](field Field[E, V], lookup BatchLookup[V]) Rule[S]
ExistsEach selects one field from every object of a collection and checks the selected values with batched observations instead of one call per element. Missing values are reported at the element's field path, for example /items/3/product_id, using that field's label.
func FileContentTypes ¶
FileContentTypes compares detected MIME media types. Declarations may use an exact type, a major-type wildcard such as image/*, or */*. Parameters such as charset do not participate in matching. The HTTP detector is a bounded sniff, not full image/document validation; imaging validation belongs to that adapter. Rules remain server-only because browser file.type is client metadata.
func FileExtensions ¶
FileExtensions compares the normalized final filename extension without a leading dot. An allowed extension never proves the file's actual content; combine it with a detected content-type rule when that behavior is required.
func FileMaxSize ¶
FileMaxSize compares bytes without converting through floating point.
func FileMinSize ¶
FileMinSize compares exact byte counts, including an inclusive zero bound.
func FilePresent ¶
FilePresent rejects an absent handle. A captured zero-byte file is present; use FileMinSize(1) when nonempty content is required. Optional and Required adapters retain the separate question of whether the form part was supplied.
func GreaterOrEqual ¶
GreaterOrEqual creates a rule requiring the first number in a pair to be greater than or equal to the second.
func GreaterThan ¶
GreaterThan creates a rule requiring the first number in a pair to be greater than the second.
func Hook ¶
Hook runs an application callback that may add issues at arbitrary paths below its input, for checks spanning several fields or collection elements. Place it after field rules in Bail when it needs them to pass first. Returning an error means execution failed, not invalid input. Spec supplies the issue code and declared message; built-in IDs are reserved.
func ItemsBetween ¶
ItemsBetween combines inclusive minimum and maximum item rules, rejecting reversed bounds.
func JSON ¶
JSON validates bounded JSON text through the same strict parser as DTOs. Duplicate keys are rejected; the original string remains unchanged.
func LengthBetween ¶
LengthBetween combines inclusive text length bounds, rejecting reversed bounds.
func LessOrEqual ¶
LessOrEqual creates a rule requiring the first number in a pair to be less than or equal to the second.
func LessThan ¶
LessThan creates a rule requiring the first number in a pair to be less than the second.
func LocalDateTime ¶
LocalDateTime creates a text rule using temporal.ParseLocalDateTime.
func Locales ¶
func Locales[M ~map[i18n.LocaleID]V, V ~string](catalog i18n.LocaleCatalog, require i18n.LocaleRequirement) Rule[M]
Locales checks a locale-keyed map, such as translated text, against one locale catalog snapshot per check. Every key must be a supported locale (foundry.supported_locale at the entry path, such as /title/fr), and every locale require selects must be present with nonempty content (foundry.required at its entry path, such as /title/ms). The catalog is runtime configuration, so the rule is server-only metadata.
func Lowercase ¶
Lowercase and Uppercase check case without changing the received text. Uncased characters pass; nonempty/letter requirements are separate rules.
func MACAddress ¶
MACAddress accepts a six-byte address in formats supported by net.ParseMAC.
func Matches ¶
Matches uses Go's regexp semantics. It is server-only metadata because a JavaScript regular expression does not promise identical syntax or behavior.
func MaxBytes ¶
MaxBytes limits the UTF-8 encoded size of text, for storage bounds measured in bytes. MaxLength counts characters instead. It is server-only metadata.
func MaxLength ¶
MaxLength creates a rule limiting Unicode rune count, rejecting a negative maximum.
func Min ¶
Min and Max compare in N itself; integers never pass through a floating-point comparison. Floating-point bounds and input values must be finite.
func MinItems ¶
MinItems and MaxItems validate ordinary or named slices. Nil and empty slices both have zero items; omitted/null transport states use their own wrappers.
func MultipleOf ¶
MultipleOf uses exact integer remainder. The divisor must be positive.
func NonBlank ¶
NonBlank rejects empty or whitespace-only text. It leaves the value intact; normalization belongs to explicit domain behavior or model mutators.
func NonEmpty ¶
NonEmpty rejects blank text and empty collections without inferring wire presence. Zero numbers, false and ordinary structs pass. Domain validity is separate. Use Optional/Nullable/Pointer to unwrap those representations.
func NotMatches ¶
NotMatches rejects text matching a Go regular expression.
func NotOneOf ¶
NotOneOf rejects any declared scalar value. Non-finite numbers and invalid UTF-8 are rejected even when they are absent from the exclusion list.
func Nullable ¶
Nullable skips explicit null and validates a present value. Combine it with Optional for a patch that distinguishes omitted, null and replacement values.
func OneOf ¶
OneOf accepts one of the declared scalar values without coercion. Input and declaration values retain their concrete type; empty/duplicate lists fail.
func Optional ¶
Optional skips an omitted value and validates present values, including zero. It does not infer wire presence from an ordinary Go field's zero value.
func Parallel ¶
Parallel checks independent branches with DefaultConcurrency workers. Each branch retains normal All/Bail order. Use a concurrency-safe pool or client; a transaction or other serial dependency belongs in a sequential branch.
func ParallelLimit ¶
ParallelLimit runs bounded waves, merges issues in declaration order, and shares one work budget. Nested parallel groups execute sequentially inside their branch, so nesting cannot multiply concurrency or deadlock workers. All admitted callbacks finish before return, including after cancellation, panic or Goexit. Inputs/selectors/dependencies must support concurrent reads. Metadata is logical All, server-only; scheduling is not a wire contract.
func Password ¶
func Password[S ~string](options PasswordOptions) Rule[S]
Password creates a password rule using the supplied options.
func PasswordValue ¶
func PasswordValue[P interface{ Secret() secret.String }](options PasswordOptions) Rule[P]
PasswordValue accepts redacted password input such as auth/password.Plaintext. The secret is inspected only during Check and never enters public metadata.
func Pointer ¶
Pointer skips nil and validates a non-nil pointed-to value. It does not infer wire presence: an ordinary pointer can represent both omission and null.
func Positive ¶
Positive accepts only strictly positive, finite numbers. Zero, including negative floating-point zero, is rejected. This rule is server-only until the TypeScript runtime supports foundry.positive.
func Present ¶
Present requires an Optional to have been supplied; its inner zero or null remains distinct and can be checked by additional value rules.
func Prohibited ¶
Prohibited accepts omission or empty content. Unlike Absent, supplied blank text and empty collections pass. Supplied numeric zero and false reject. Use ProhibitedNullable when explicit null is a representable input state.
func ProhibitedNullable ¶
ProhibitedNullable also accepts explicit null, while preserving the distinction from omission and a nonempty T. It does not mutate or unset supplied values.
func Provide ¶
func Provide[T, P any](slot Slot[P], derive func(context.Context, T) (P, error), rules ...Rule[T]) Rule[T]
Provide derives the slot's value from the check context and the input at this level, then runs rules with that value available to their contexts. For HTTP, attach it with WithValidation so derive can read path parameters while the rules select body fields. derive is an application callback: its error is an execution failure, never a rejection or an absent value. The value is visible only to this subtree and only for the current check.
func Required ¶
Required requires a supplied, nonempty Optional value. Supplied numeric zero and false pass. Additional same-type rules run only after that requirement succeeds and bail on the first rejection. For nullable input use RequiredNullable; ordinary fields use NonEmpty without inferring presence.
func RequiredNullable ¶
RequiredNullable distinguishes omission, explicit null and supplied T. Null and empty content reject; zero numbers and false remain valid supplied values. Additional T rules run only on the nonempty, non-null value and bail on failure.
func Requires ¶
Requires records that rule reads slot. Validate then rejects any tree in which no enclosing Provide supplies it, so a missing provider fails registration instead of every check. Adapters that accept a Slot apply this themselves.
func Rules ¶ added in v0.2.0
Rules binds value rules to this field without dynamic field lookups. The selector runs once for this binding and must not mutate the input.
func StartsWith ¶
StartsWith checks an exact, case-sensitive prefix without normalization. An empty prefix matches every string; use NonBlank to require nonempty text.
func Timezone ¶
Timezone accepts UTC, an installed IANA zone or a fixed +/-HH:MM offset. It rejects implicit machine-local zones and retains server-only metadata.
func ULID ¶
ULID checks the 26-character Crockford encoding, including its 128-bit bound. Lowercase input is accepted. It does not require a particular timestamp.
func URL ¶
URL accepts an absolute HTTP or HTTPS URL with a hostname. It checks syntax, not reachability or whether a destination is authorized for outbound fetching.
func UUID ¶
UUID reuses the framework's canonical hyphenated UUID parser. It checks representation, including the nil UUID; model identity constraints are separate.
func Unique ¶
Unique requires no matching value in the declared lookup. It does not reserve the value or replace a database unique constraint. A lookup failure is an internal execution failure, never evidence that the value is available.
func UniqueAll ¶
UniqueAll requires that no value of a collection exists in the scoped source, reporting each conflicting element at its index path. It does not detect duplicates inside the request itself; combine it with Distinct.
func UniqueEach ¶
UniqueEach selects one field from every object and requires that none of the selected values exists in the scoped source, reporting conflicts at the element's field path. It is advisory and does not reserve values; combine it with DistinctBy for duplicates inside the request.
func Unless ¶
Unless runs rules only when the condition rejects its input. A failed or incomplete condition never counts as an ordinary false condition.
func When ¶
When runs rules only when the condition passes. Conditions are ordinary typed rules and may reference generated fields. Their rejection diagnostics remain private; infrastructure failures and cancellation still fail the whole check.
func WithMessage ¶ added in v0.2.0
WithMessage replaces only the public message of one leaf. Composite trees retain their individual messages; overriding a composite is rejected.
func WithTranslation ¶
WithTranslation attaches a generated, typed message to a leaf rule. Arguments are public declaration data, evaluated and snapshotted once; never pass received secrets. Optional text arguments attribute/other receive the bound field labels. The rule's current message is the English fallback. WithMessage restores a literal override; it is not parsed as a template.
type RuleID ¶
type RuleID string
RuleID identifies a rule independently of its public message. Built-in IDs use the reserved foundry namespace; application rules use semantic IDs.
type Slot ¶
type Slot[P any] struct { // contains filtered or unexported fields }
Slot declares a typed value that an enclosing Provide derives once per check from the request context and the input it validates, such as the key of the row being updated or the tenant of the authenticated actor. Rules and lookups below that Provide read it with Value, so a rule tree is declared once and parameterized at check time instead of being rebuilt for every request. Declare slots once, beside the rules that use them. The zero Slot is invalid.
type Spec ¶
type Spec struct {
ID RuleID `json:"id"`
Message string `json:"message"`
Parameters []Parameter `json:"parameters,omitempty"`
Translation *i18n.MessageRecipe `json:"translation,omitempty"`
}
Spec is a custom rule's public declaration. Message contains approved static public text; an execution error's text is never used as a validation message.
type Temporal ¶
type Temporal interface {
time.Time | temporal.Date | temporal.Time | temporal.DateTime | temporal.LocalDateTime
// String returns the temporal value's text representation.
String() string
}
Temporal retains the distinction between instants, dates and wall times. A bound or related field must have the same concrete type as the input.
type TodayTemporal ¶
type TodayTemporal interface {
time.Time | temporal.DateTime | temporal.Date | temporal.LocalDateTime
// String returns the temporal value's text representation.
String() string
}
TodayTemporal values compare by calendar date with today in the service's timezone. Instants are first converted to their date in that timezone.
Source Files
¶
- collection.go
- collection_extra.go
- compare.go
- composition.go
- conditional.go
- decimal.go
- description.go
- dynamic.go
- embed.go
- empty.go
- file.go
- format.go
- image.go
- label.go
- limits.go
- locales.go
- lookup.go
- maps.go
- membership.go
- message_catalog.go
- messages.go
- messages_builtin.go
- metadata.go
- number.go
- number_extra.go
- parallel.go
- password.go
- presence.go
- required.go
- rule.go
- scalar.go
- slot.go
- temporal.go
- text.go
- text_extra.go
- text_format.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package database supplies advisory typed model validation.
|
Package database supplies advisory typed model validation. |
|
Package imaging validates uploaded image files with the framework's bounded container inspection.
|
Package imaging validates uploaded image files with the framework's bounded container inspection. |