Documentation
¶
Overview ¶
Package validation checks a submitted request against a set of rules.
A rule is written as a string, and a field's rules are one string:
var Register = validation.MustCompile(validation.Rules{
"name": "required|max:255",
"email": "required|email",
"password": "required|min:12|confirmed",
})
in, err := ctx.Validate(requests.Register)
if err != nil {
return err
}
A rule set is compiled ONCE, in a package-level variable, and every rule string is parsed and checked there: an unknown rule, a missing or unparseable argument, a pattern that does not compile, a cross-field reference naming a field that does not exist -- each of those fails at boot, naming the field, the rule and the file, and all of them are reported together. A rule set that boots is a rule set whose names are all real.
Where the files are ¶
attributes.go one ValidateX method per rule rulebuilders.go the typed builders, for a rule nobody wants to spell validator.go the Validator, which runs a compiled set over one request messages.go Errors, the messages a failed run collected compile.go the boot-time compile; parser.go is the per-request half rules.go the catalogue: arity, check and message of every rule
Four things worth knowing before writing a rule string ¶
- date_format takes a GO layout -- date_format:2006-01-02, never date_format:Y-m-d. It is a layout in the host language, and it is checked at boot.
- regex takes a GO pattern: RE2, without delimiters, without backreferences and without lookaround. It is compiled at boot.
- `unique` and `exists` take an auth Grant and a PresenceVerifier, given with WithPresence, and fail closed without one. A read is authorized like any other: "the validator only counts rows" is how a count of rows becomes a way to ask whether another tenant has a user with a given address.
- `current_password` takes a CurrentPasswordChecker. Nothing here resolves a guard or a hasher, so without a checker the rule fails closed.
Reading what passed ¶
There is no reflection and there are no struct tags. The rule set is data, the request struct is written by hand or generated, and the values that passed are read out of Input one at a time -- so a field nobody declared a rule for cannot reach a repository through here.
Index ¶
- func Confirmed(e Errors, field, value, confirmation string)
- func Email(e Errors, field, value string)
- func Extend(rule string, extension ExtensionFunc, message string)
- func ExtendDependent(rule string, extension ExtensionFunc, message string)
- func ExtendImplicit(rule string, extension ExtensionFunc, message string)
- func GetLeadingExplicitAttributePath(attribute string) string
- func InitializeAndGatherData(attribute string, masterData Data) map[string]any
- func MaxLen(e Errors, field, value string, n int)
- func MinLen(e Errors, field, value string, n int)
- func NotZero[T comparable](e Errors, field string, value T)
- func Parse(rule string) (string, []string)
- func PasswordDefaults(callback func() *Password)
- func Required(e Errors, field, value string)
- func ToKilobytes(size string) (int, bool)
- type AnyOf
- type ArrayRule
- type Can
- type ClosureValidationRule
- type CompilableRules
- type CompileError
- type CompileErrors
- type ConditionalRules
- type CurrentPasswordChecker
- type Data
- type DataAwareRule
- type DatabasePresenceVerifier
- func (d *DatabasePresenceVerifier) Connection() string
- func (d *DatabasePresenceVerifier) GetCount(ctx context.Context, g auth.Grant, collection, column string, value any, ...) (int, error)
- func (d *DatabasePresenceVerifier) GetMultiCount(ctx context.Context, g auth.Grant, collection, column string, values []any, ...) (int, error)
- func (d *DatabasePresenceVerifier) SetConnection(connection string)
- type DatabaseRule
- func (r *DatabaseRule) FormatWheres() string
- func (r *DatabaseRule) OnlyTrashed(deletedAtColumn ...string) *DatabaseRule
- func (r *DatabaseRule) QueryCallbacks() []func(query any)
- func (r *DatabaseRule) ResolveTableName(table string) string
- func (r *DatabaseRule) Using(callback func(query any)) *DatabaseRule
- func (r *DatabaseRule) Where(column, value string) *DatabaseRule
- func (r *DatabaseRule) WhereIn(column string, values ...string) *DatabaseRule
- func (r *DatabaseRule) WhereNot(column, value string) *DatabaseRule
- func (r *DatabaseRule) WhereNotIn(column string, values ...string) *DatabaseRule
- func (r *DatabaseRule) WhereNotNull(column string) *DatabaseRule
- func (r *DatabaseRule) WhereNull(column string) *DatabaseRule
- func (r *DatabaseRule) WithoutTrashed(deletedAtColumn ...string) *DatabaseRule
- type Date
- func (r *Date) After(date string) *Date
- func (r *Date) AfterOrEqual(date string) *Date
- func (r *Date) AfterToday() *Date
- func (r *Date) Before(date string) *Date
- func (r *Date) BeforeOrEqual(date string) *Date
- func (r *Date) BeforeToday() *Date
- func (r *Date) Between(from, to string) *Date
- func (r *Date) BetweenOrEqual(from, to string) *Date
- func (r *Date) Format(format string) *Date
- func (r *Date) String() string
- func (r *Date) TodayOrAfter() *Date
- func (r *Date) TodayOrBefore() *Date
- type Dimensioner
- type Dimensions
- func (r *Dimensions) Height(value int) *Dimensions
- func (r *Dimensions) MaxHeight(value int) *Dimensions
- func (r *Dimensions) MaxRatio(value float64) *Dimensions
- func (r *Dimensions) MaxWidth(value int) *Dimensions
- func (r *Dimensions) MinHeight(value int) *Dimensions
- func (r *Dimensions) MinRatio(value float64) *Dimensions
- func (r *Dimensions) MinWidth(value int) *Dimensions
- func (r *Dimensions) Ratio(value float64) *Dimensions
- func (r *Dimensions) RatioBetween(min, max float64) *Dimensions
- func (r *Dimensions) String() string
- func (r *Dimensions) Width(value int) *Dimensions
- type EmailRule
- func (r *EmailRule) PreventSpoofing() *EmailRule
- func (r *EmailRule) RfcCompliant(strict ...bool) *EmailRule
- func (r *EmailRule) Rules(rules ...string) *EmailRule
- func (r *EmailRule) Strict() *EmailRule
- func (r *EmailRule) String() string
- func (r *EmailRule) ValidateMxRecord() *EmailRule
- func (r *EmailRule) WithNativeValidation(allowUnicode ...bool) *EmailRule
- type Enum
- type Errors
- func (e Errors) Add(field, msg string)
- func (e Errors) AddIf(condition bool, field, msg string) Errors
- func (e Errors) All() []string
- func (e Errors) Any() bool
- func (e Errors) Count() int
- func (e Errors) Error() string
- func (e Errors) First(key ...string) string
- func (e Errors) Forget(key string) Errors
- func (e Errors) Get(key string) []string
- func (e Errors) GetMessages() map[string][]string
- func (e Errors) Has(keys ...string) bool
- func (e Errors) HasAny(keys ...string) bool
- func (e Errors) IsEmpty() bool
- func (e Errors) IsNotEmpty() bool
- func (e Errors) Keys() []string
- func (e Errors) Merge(other Errors) Errors
- func (e Errors) Messages() map[string][]string
- func (e Errors) Missing(keys ...string) bool
- func (e Errors) Unique() []string
- type ExcludeIf
- type Exists
- type ExplodedRules
- type ExtensionFunc
- type Factory
- func (f *Factory) ExcludeUnvalidatedArrayKeys()
- func (f *Factory) Extend(rule string, extension ExtensionFunc, message ...string)
- func (f *Factory) ExtendDependent(rule string, extension ExtensionFunc, message ...string)
- func (f *Factory) ExtendImplicit(rule string, extension ExtensionFunc, message ...string)
- func (f *Factory) GetPresenceVerifier() PresenceVerifier
- func (f *Factory) GetTranslator() Translator
- func (f *Factory) IncludeUnvalidatedArrayKeys()
- func (f *Factory) Make(data Data, rules *Set, opts ...ValidatorOption) *Validator
- func (f *Factory) Replacer(rule string, replacer ReplacerFunc)
- func (f *Factory) Resolver(resolver func(data Data, rules *Set, opts []ValidatorOption) *Validator)
- func (f *Factory) SetAttributeNames(attributes map[string]string) *Factory
- func (f *Factory) SetCustomMessages(messages map[string]any) *Factory
- func (f *Factory) SetPresenceVerifier(g auth.Grant, presenceVerifier PresenceVerifier)
- func (f *Factory) Validate(data Data, rules *Set, opts ...ValidatorOption) (Input, error)
- type File
- type FileRule
- func (r *FileRule) Between(minSize, maxSize int) *FileRule
- func (r *FileRule) Dimensions(dimensions *Dimensions) *FileRule
- func (r *FileRule) Extensions(extensions ...string) *FileRule
- func (r *FileRule) Max(size int) *FileRule
- func (r *FileRule) Min(size int) *FileRule
- func (r *FileRule) Rules(rules ...string) *FileRule
- func (r *FileRule) Size(size int) *FileRule
- func (r *FileRule) String() string
- type ImplicitRule
- type In
- type Input
- func (in Input) Bool(field string) bool
- func (in Input) Data() Data
- func (in Input) File(field string) (File, bool)
- func (in Input) Float(field string) float64
- func (in Input) Has(field string) bool
- func (in Input) Int(field string) int64
- func (in Input) String(field string) string
- func (in Input) Strings(field string) []string
- func (in Input) Time(field, layout string) time.Time
- func (in Input) Values() url.Values
- type InvokableValidationRule
- func (r *InvokableValidationRule) Implicit() bool
- func (r *InvokableValidationRule) Invokable() ValidationRule
- func (r *InvokableValidationRule) Message() []string
- func (r *InvokableValidationRule) Passes(attribute string, value any) bool
- func (r *InvokableValidationRule) SetData(data Data)
- func (r *InvokableValidationRule) SetValidator(validator *Validator)
- type Messages
- type NestedRules
- type NotIn
- type Numeric
- func (r *Numeric) Between(min, max float64) *Numeric
- func (r *Numeric) Decimal(min int, max ...int) *Numeric
- func (r *Numeric) Different(field string) *Numeric
- func (r *Numeric) Digits(length int) *Numeric
- func (r *Numeric) DigitsBetween(min, max int) *Numeric
- func (r *Numeric) Exactly(value int) *Numeric
- func (r *Numeric) GreaterThan(field string) *Numeric
- func (r *Numeric) GreaterThanOrEqualTo(field string) *Numeric
- func (r *Numeric) Integer() *Numeric
- func (r *Numeric) LessThan(field string) *Numeric
- func (r *Numeric) LessThanOrEqualTo(field string) *Numeric
- func (r *Numeric) Max(value float64) *Numeric
- func (r *Numeric) MaxDigits(value int) *Numeric
- func (r *Numeric) Min(value float64) *Numeric
- func (r *Numeric) MinDigits(value int) *Numeric
- func (r *Numeric) MultipleOf(value float64) *Numeric
- func (r *Numeric) Same(field string) *Numeric
- func (r *Numeric) String() string
- type Option
- type Password
- func (p *Password) AppliedRules() map[string]any
- func (p *Password) Letters() *Password
- func (p *Password) Max(size int) *Password
- func (p *Password) Message() []string
- func (p *Password) MixedCase() *Password
- func (p *Password) Numbers() *Password
- func (p *Password) Passes(attribute string, value any) bool
- func (p *Password) Rules(rules ...string) *Password
- func (p *Password) SetData(data Data)
- func (p *Password) SetValidator(validator *Validator)
- func (p *Password) Symbols() *Password
- func (p *Password) Uncompromised(verifier UncompromisedVerifier, threshold ...int) *Password
- type PresenceQuery
- type PresenceVerifier
- type ProhibitedIf
- type ReplacerFunc
- type RequiredIf
- type Resolver
- type Rule
- type RuleFactory
- func (RuleFactory) AnyOf(sets ...*Set) *AnyOf
- func (RuleFactory) Array(keys ...string) *ArrayRule
- func (RuleFactory) Can(allows func(g auth.Grant, ability string, arguments []string, value any) bool, ...) *Can
- func (RuleFactory) Date() *Date
- func (RuleFactory) Default() *FileRule
- func (RuleFactory) Defaults(rules ...string) *FileRule
- func (RuleFactory) Dimensions() *Dimensions
- func (RuleFactory) Email() *EmailRule
- func (RuleFactory) Enum(cases ...string) *Enum
- func (RuleFactory) ExcludeIf(condition bool) *ExcludeIf
- func (RuleFactory) Exists(table string, column ...string) *Exists
- func (RuleFactory) File() *FileRule
- func (RuleFactory) Image(allowSvg ...bool) *FileRule
- func (RuleFactory) ImageFile(allowSvg ...bool) *FileRule
- func (RuleFactory) In(values ...string) *In
- func (RuleFactory) NotIn(values ...string) *NotIn
- func (RuleFactory) Numeric() *Numeric
- func (RuleFactory) Password(min int) *Password
- func (RuleFactory) ProhibitedIf(condition bool) *ProhibitedIf
- func (RuleFactory) RequiredIf(condition bool) *RequiredIf
- func (RuleFactory) Unique(table string, column ...string) *Unique
- type Rules
- type Set
- type Translator
- type UncompromisedVerifier
- type Unique
- type UploadedFile
- type Validatable
- type ValidationException
- func (e *ValidationException) Error() string
- func (e *ValidationException) ErrorBag(errorBag string) *ValidationException
- func (e *ValidationException) Errors() map[string][]string
- func (e *ValidationException) GetErrorBag() string
- func (e *ValidationException) GetRedirectTo() string
- func (e *ValidationException) GetResponse() any
- func (e *ValidationException) GetStatus() int
- func (e *ValidationException) RedirectTo(url string) *ValidationException
- func (e *ValidationException) Status(status int) *ValidationException
- func (e *ValidationException) Validator() *Validator
- type ValidationRule
- type ValidationRuleParser
- type Validator
- func (v *Validator) AddCustomAttributes(attributes map[string]string) *Validator
- func (v *Validator) AddCustomValues(values map[string]map[string]string) *Validator
- func (v *Validator) AddDependentExtension(rule string, extension ExtensionFunc)
- func (v *Validator) AddDependentExtensions(extensions map[string]ExtensionFunc)
- func (v *Validator) AddExtension(rule string, extension ExtensionFunc)
- func (v *Validator) AddExtensions(extensions map[string]ExtensionFunc)
- func (v *Validator) AddFailure(attribute, rule string, parameters []string)
- func (v *Validator) AddImplicitExtension(rule string, extension ExtensionFunc)
- func (v *Validator) AddImplicitExtensions(extensions map[string]ExtensionFunc)
- func (v *Validator) AddReplacer(rule string, replacer ReplacerFunc)
- func (v *Validator) AddReplacers(replacers map[string]ReplacerFunc)
- func (v *Validator) AddRules(rules *Set) *Validator
- func (v *Validator) After(callback func(*Validator)) *Validator
- func (v *Validator) AllFailingRequired(attributes []string) bool
- func (v *Validator) AnyFailingRequired(attributes []string) bool
- func (v *Validator) Attributes() Data
- func (v *Validator) Compare(result, against int, operator string) bool
- func (v *Validator) CompareDates(attribute string, value any, parameters []string, operator string) bool
- func (v *Validator) Context() context.Context
- func (v *Validator) CustomAttributes() map[string]string
- func (v *Validator) CustomMessages() map[string]any
- func (v *Validator) EnsureExponentWithinAllowedRange(scale int, attribute string, value any) bool
- func (v *Validator) EnsureExponentWithinAllowedRangeUsing(callback func(scale int, attribute string, value any) bool) *Validator
- func (v *Validator) Errors() Errors
- func (v *Validator) ExcludeAttribute(attribute string)
- func (v *Validator) ExtractDistinctValues(attribute string) []any
- func (v *Validator) Failed() map[string][]string
- func (v *Validator) Fails() bool
- func (v *Validator) FailsBasicDimensionChecks(parameters map[string]string, width, height int) bool
- func (v *Validator) FailsMaxRatioCheck(parameters map[string]string, width, height int) bool
- func (v *Validator) FailsMinRatioCheck(parameters map[string]string, width, height int) bool
- func (v *Validator) FailsRatioCheck(parameters map[string]string, width, height int) bool
- func (v *Validator) GetDNSRecords(hostname string) ([]string, error)
- func (v *Validator) GetData() Data
- func (v *Validator) GetDateFormat(attribute string) string
- func (v *Validator) GetDisplayableAttribute(attribute string) string
- func (v *Validator) GetDisplayableValue(attribute string, value any) string
- func (v *Validator) GetDistinctValues(attribute string) []any
- func (v *Validator) GetException() func(*Validator) error
- func (v *Validator) GetExtraConditions(segments []string) map[string]string
- func (v *Validator) GetMessageBag() Errors
- func (v *Validator) GetPresenceVerifier() (PresenceVerifier, error)
- func (v *Validator) GetQueryColumn(parameters []string, attribute string) string
- func (v *Validator) GetRule(attribute string, rules []string) (string, []string, bool)
- func (v *Validator) GetRules() map[string][]string
- func (v *Validator) GetRulesWithoutPlaceholders() map[string][]string
- func (v *Validator) GetSize(attribute string, value any) (*big.Rat, bool)
- func (v *Validator) GetTranslator() Translator
- func (v *Validator) GetUniqueExtra(parameters []string) map[string]string
- func (v *Validator) GetUniqueIds(idColumn string, parameters []string) (string, any)
- func (v *Validator) GetValue(attribute string) any
- func (v *Validator) GuessColumnForQuery(attribute string) string
- func (v *Validator) HasRule(attribute string, rules []string) bool
- func (v *Validator) Invalid() Data
- func (v *Validator) IsValidFileInstance(value any) bool
- func (v *Validator) MakeReplacements(message, attribute, rule string, parameters []string) string
- func (v *Validator) Messages() Errors
- func (v *Validator) Now() time.Time
- func (v *Validator) ParseData(data Data) Data
- func (v *Validator) ParseDependentRuleParameters(parameters []string) ([]string, any)
- func (v *Validator) ParseNamedParameters(parameters []string) map[string]string
- func (v *Validator) ParseTable(table string) (connection, name, idColumn string)
- func (v *Validator) Passes() bool
- func (v *Validator) PrepareUniqueId(id string) any
- func (v *Validator) ReplaceProhibitedIfDeclined(message, attribute, rule string, parameters []string) string
- func (v *Validator) ReplaceRequiredIfDeclined(message, attribute, rule string, parameters []string) string
- func (v *Validator) RequireParameterCount(count int, parameters []string, rule string) bool
- func (v *Validator) Safe(keys ...string) (*support.ValidatedInput, error)
- func (v *Validator) SetAttributeNames(attributes map[string]string) *Validator
- func (v *Validator) SetCustomMessages(messages map[string]any) *Validator
- func (v *Validator) SetData(data Data) *Validator
- func (v *Validator) SetException(exception func(*Validator) error) *Validator
- func (v *Validator) SetFallbackMessages(messages map[string]any)
- func (v *Validator) SetImplicitAttributesFormatter(formatter func(string) string) *Validator
- func (v *Validator) SetPresenceVerifier(g auth.Grant, presenceVerifier PresenceVerifier)
- func (v *Validator) SetRules(rules *Set) *Validator
- func (v *Validator) SetTranslator(translator Translator)
- func (v *Validator) SetValue(attribute string, value any)
- func (v *Validator) SetValueNames(values map[string]map[string]string) *Validator
- func (v *Validator) ShouldBeExcluded(attribute string) bool
- func (v *Validator) ShouldBlockPhpUpload(value any, parameters []string) bool
- func (v *Validator) ShouldStopValidating(attribute string) bool
- func (v *Validator) Sometimes(attributes []string, rules *Set, ...) *Validator
- func (v *Validator) StopOnFirstFailure() *Validator
- func (v *Validator) Valid() Data
- func (v *Validator) Validate() (Input, error)
- func (v *Validator) ValidateAccepted(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateAcceptedIf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateActiveUrl(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateAfter(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateAfterOrEqual(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateAlpha(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateAlphaDash(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateAlphaNum(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateArray(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateAscii(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateBail(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateBefore(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateBeforeOrEqual(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateBetween(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateBoolean(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateConfirmed(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateContains(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateCurrentPassword(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDate(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDateEquals(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDateFormat(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDecimal(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDeclined(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDeclinedIf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDifferent(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDigits(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDigitsBetween(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDimensions(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDistinct(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDoesntEndWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateDoesntStartWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateEmail(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateEndsWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateEnum(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateExclude(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateExcludeIf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateExcludeUnless(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateExcludeWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateExcludeWithout(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateExists(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateExtensions(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateFile(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateFilled(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateGt(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateGte(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateHexColor(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateImage(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateIn(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateInArray(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateInteger(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateIp(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateIpv4(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateIpv6(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateJson(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateList(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateLowercase(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateLt(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateLte(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMacAddress(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMax(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMaxDigits(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMimes(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMimetypes(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMin(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMinDigits(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMissing(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMissingIf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMissingUnless(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMissingWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMissingWithAll(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateMultipleOf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateNotIn(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateNotRegex(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateNullable(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateNumeric(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidatePresent(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidatePresentIf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidatePresentUnless(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidatePresentWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidatePresentWithAll(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateProhibited(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateProhibitedIf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateProhibitedIfAccepted(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateProhibitedIfDeclined(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateProhibitedUnless(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateProhibits(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRegex(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequired(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredArrayKeys(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredIf(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredIfAccepted(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredIfDeclined(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredUnless(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredWithAll(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredWithout(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateRequiredWithoutAll(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateSame(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateSize(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateSometimes(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateStartsWith(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateString(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateTimezone(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateUlid(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateUnique(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateUppercase(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateUrl(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateUsingCustomRule(attribute string, value any, rule Rule)
- func (v *Validator) ValidateUuid(attribute string, value any, parameters []string) bool
- func (v *Validator) ValidateWithBag(errorBag string) (Input, error)
- func (v *Validator) Validated() Input
- type ValidatorAwareRule
- type ValidatorOption
- func WithClock(now func() time.Time) ValidatorOption
- func WithContext(ctx context.Context) ValidatorOption
- func WithCurrentPassword(c CurrentPasswordChecker) ValidatorOption
- func WithCustomAttributes(attributes map[string]string) ValidatorOption
- func WithCustomMessages(messages map[string]any) ValidatorOption
- func WithCustomValues(values map[string]map[string]string) ValidatorOption
- func WithPresence(g auth.Grant, p PresenceVerifier) ValidatorOption
- func WithResolver(r Resolver) ValidatorOption
- func WithTranslator(t Translator) ValidatorOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Confirmed ¶
Confirmed rejects a value its confirmation field does not repeat.
It is what a "confirm your password" box is for, and the message goes on the confirmation rather than on the field itself: a form that reports "password does not match" next to the first box tells the person to change the one they meant, and they change it, and the form fails again.
An empty confirmation is reported here rather than by Required, so the field gets one message instead of two saying the same thing.
func Email ¶
Email checks the shape only. Deliverability is proven by sending mail, never by a regular expression.
Whitespace is rejected rather than trimmed: an address with a space in it is almost always a paste accident, and silently trimming input hides the mistake from the person who made it.
The shape itself is emailShape, which the `email` rule also calls: two implementations of "is this an address" would drift, and the one that drifted would be whichever a screen did not exercise.
func Extend ¶
func Extend(rule string, extension ExtensionFunc, message string)
Extend registers a rule of the application's own: a rule name, the check behind it, and the sentence it says.
It is called from an init or from main, before any rule set is compiled. An empty message leaves the rule saying "is not valid".
func ExtendDependent ¶
func ExtendDependent(rule string, extension ExtensionFunc, message string)
ExtendDependent is Extend for a rule whose first parameter names another field.
func ExtendImplicit ¶
func ExtendImplicit(rule string, extension ExtensionFunc, message string)
ExtendImplicit is Extend for a rule that runs even when the value is blank.
func GetLeadingExplicitAttributePath ¶
GetLeadingExplicitAttributePath returns the part of a path before its first wildcard: "foo.bar.*.baz" gives "foo.bar", which is all of it that can be walked without guessing.
func InitializeAndGatherData ¶
InitializeAndGatherData returns the slice of the request one attribute names, flattened, plus the exact keys a wildcard matched.
func MinLen ¶
MinLen counts runes, not bytes: a limit measured in bytes rejects valid input in any language that needs more than one byte per character.
func NotZero ¶
func NotZero[T comparable](e Errors, field string, value T)
NotZero reports a value that was never filled in.
It is Required for everything that is not text. Required takes a string and the generator used to hand it a literal "" for an int, a date or an amount -- so every required field of those types failed validation with "is required" no matter what was sent, and the generated create endpoint could not be used at all. Found by audit.
A time.Time is asked rather than compared: a parsed "0001-01-01T00:00:00Z" carries a location the zero value does not, so == says they differ when they do not.
Bool has no meaningful zero to reject -- false is an answer, not an absence -- and the specification refuses `required` on a bool for that reason.
func Parse ¶
Parse splits a rule string into its name and the parameters written after the colon.
The name stays as it was typed, which is how every table in this package keys it. Its two aliases are normalized: "int" is "integer" and "bool" is "boolean".
A malformed parameter list answers with no parameters rather than an error; Compile is where a malformed list is reported, with the field and the file.
func PasswordDefaults ¶
func PasswordDefaults(callback func() *Password)
PasswordDefaults registers the policy every later PasswordDefault answers with.
func Required ¶
Required rejects an empty or blank value. It is the `required` rule for one value, without a rule set.
func ToKilobytes ¶
ToKilobytes reads a size written with a suffix: "2mb" is 2000 kilobytes -- a thousand, not 1024.
The bool is false for a suffix it does not know, and for a number written with no suffix at all.
Types ¶
type AnyOf ¶
type AnyOf struct {
// contains filtered or unexported fields
}
AnyOf is the rule that the value passes when it passes any one of the given rule sets. Build one with NewAnyOf.
func (*AnyOf) Passes ¶
Passes reports whether the value passes any one of the sets, each run over the validator's data with this attribute replaced.
func (*AnyOf) SetValidator ¶
SetValidator hands the rule the validator running it, which is where the data and the translator come from.
type ArrayRule ¶
type ArrayRule struct {
// contains filtered or unexported fields
}
ArrayRule builds the "array" rule: the value must be an array, and when keys are given it may hold no key outside that list, which is how a nested object arriving from a form is kept to the shape it was meant to have. With no keys it renders the bare "array". The name carries a suffix because array is a type.
func NewArrayRule ¶
NewArrayRule returns an `array` rule, restricted to the given keys when any are named.
type Can ¶
type Can struct {
// contains filtered or unexported fields
}
Can is the rule that the value is one the current subject is allowed to choose.
The question is asked through the callback the caller gives, against the Grant the validator carries. Build one with NewCan.
func NewCan ¶
func NewCan(allows func(g auth.Grant, ability string, arguments []string, value any) bool, ability string, arguments ...string) *Can
NewCan returns a Can that asks allows about the ability.
func (*Can) Passes ¶
Passes reports what the callback says about the Grant, the ability and the value.
A missing callback FAILS rather than passes: "nobody wired the authorizer" is not "everybody is allowed".
func (*Can) SetValidator ¶
SetValidator hands the rule the validator running it, which is where the Grant and the translator come from.
type ClosureValidationRule ¶
type ClosureValidationRule struct {
// Callback is the check itself.
Callback func(attribute string, value any, fail func(message string), validator *Validator)
// Failed reports whether the last Passes called fail at all.
Failed bool
// contains filtered or unexported fields
}
ClosureValidationRule is a rule written as a function rather than as a type, for a check that does not deserve a type of its own. The callback is handed the attribute, its value, a fail function and the validator, and reports a problem by calling fail with the sentence to show. Each call to fail adds one message, and a callback that never calls it passes.
func NewClosureValidationRule ¶
func NewClosureValidationRule(callback func(attribute string, value any, fail func(message string), validator *Validator)) *ClosureValidationRule
NewClosureValidationRule returns a rule that runs the callback.
func (*ClosureValidationRule) Message ¶
func (r *ClosureValidationRule) Message() []string
Message returns what the last Passes collected.
func (*ClosureValidationRule) Passes ¶
func (r *ClosureValidationRule) Passes(attribute string, value any) bool
Passes runs the callback, and reports whether it called fail. A nil callback passes.
func (*ClosureValidationRule) SetValidator ¶
func (r *ClosureValidationRule) SetValidator(validator *Validator)
SetValidator hands the rule the validator running it, which the callback is given as its fourth argument.
type CompilableRules ¶
type CompilableRules interface {
// Compile returns the rules this attribute gets, given what it holds.
Compile(attribute string, value any, data Data) *ExplodedRules
}
CompilableRules is rules decided by looking at the value, which is what NestedRules is.
type CompileError ¶
type CompileError struct {
// Field is the input the rule was written against.
Field string
// Rule is the rule name, or empty when the failure is about the field as a
// whole.
Rule string
// File and Line are where the rule set was compiled, from runtime.Caller --
// so the message names the application's source, not this package's.
File string
Line int
// Msg says what is wrong and, where there is one, where the answer lives.
Msg string
}
CompileError is one thing wrong with a rule set, named precisely enough to fix without opening the framework.
func (CompileError) Error ¶
func (e CompileError) Error() string
Error renders one failure on its own, with the file and line, because a single failure has to stand alone when it is the only one.
type CompileErrors ¶
type CompileErrors []CompileError
CompileErrors is everything wrong with a rule set, not the first thing.
A set with three typos reports three. Reporting one at a time turns a boot check into three restarts, which is how a boot check gets a reputation for being slower than finding out on the request.
func (CompileErrors) Error ¶
func (e CompileErrors) Error() string
Error renders the header once and one failure per line, the way kyse.Errors does, so a panic reads as a list rather than as a paragraph.
type ConditionalRules ¶
type ConditionalRules struct {
// contains filtered or unexported fields
}
ConditionalRules is the rules an attribute gets when a condition holds, and the ones it gets when it does not.
func NewConditionalRules ¶
func NewConditionalRules(condition func(Data) bool, rules string, defaultRules ...string) *ConditionalRules
NewConditionalRules returns rules chosen by the condition: rules when it holds, and defaultRules when it does not.
func Unless ¶
func Unless(condition func(Data) bool, rules string, defaultRules ...string) *ConditionalRules
Unless is When with the condition turned around.
func When ¶
func When(condition func(Data) bool, rules string, defaultRules ...string) *ConditionalRules
When returns the rules an attribute gets when a condition holds, and the ones it gets when it does not.
func (*ConditionalRules) DefaultRules ¶
func (c *ConditionalRules) DefaultRules(data Data) []string
DefaultRules returns the rules used when the condition does not hold.
func (*ConditionalRules) Passes ¶
func (c *ConditionalRules) Passes(data Data) bool
Passes reports whether the condition holds for this request. A nil condition does not hold.
func (*ConditionalRules) Rules ¶
func (c *ConditionalRules) Rules(data Data) []string
Rules returns the rules used when the condition holds.
type CurrentPasswordChecker ¶
type CurrentPasswordChecker interface {
// CheckCurrentPassword reports whether the plain password is the one the
// subject the Grant was issued to already has. It answers false for a
// subject that is not authenticated.
CheckCurrentPassword(ctx context.Context, g auth.Grant, guard, password string) bool
}
CurrentPasswordChecker is what `current_password` asks. Nothing here resolves a guard or a hasher: the question arrives already answerable.
type Data ¶
Data is a submitted request, one entry per input name, and it is what a Validator is built over.
A value is one of: nil -- the null a browser cannot send but a JSON body can --, a string, a []any (what a multi-select or a repeated input sends), a Data (a nested object), or a File. A number or a bool put in by hand is read as its printed form by every rule that asks.
This is the shape `array`, `list`, `distinct`, `contains`, `nullable` and the file rules need, and the reason the package does not stop at url.Values: url.Values cannot hold a null, a nested value or an upload, and six of the rules are about exactly those.
func DataFrom ¶
DataFrom builds the Data of a submitted HTML form.
A name sent once is a string and a name sent more than once is a list: reading `tags[]` as a string would make `array` unable to pass on input that really is one. A name present with no value at all is the empty list, which `required` refuses for having no members.
func ExtractDataFromPath ¶
ExtractDataFromPath returns the sub-section of the request one dotted path names, so that the rest of it is not walked.
func (Data) Clone ¶
Clone is a shallow copy, so that a Validator cannot write through to the request's own map.
func (Data) Forget ¶
Forget drops the key. Only a top-level key is dropped, which is every key an exclude rule names.
func (Data) HasAll ¶
HasAll reports whether every one of the keys exists. It is what missing_with_all and present_with_all ask.
type DataAwareRule ¶
type DataAwareRule interface {
// SetData hands the rule every value being validated.
SetData(data Data)
}
DataAwareRule is implemented by a rule object that has to see the whole request and not only the one value it was written against -- a check that compares two fields, for instance. Before asking such a rule whether the value passes, the validator hands it every value it is validating. A rule that looks only at its own value does not implement it and is not given the data.
type DatabasePresenceVerifier ¶
type DatabasePresenceVerifier struct {
// contains filtered or unexported fields
}
DatabasePresenceVerifier is the PresenceVerifier over a relational store.
The query is given rather than built -- see PresenceQuery -- so what is left here is the two counts and the connection name.
func NewDatabasePresenceVerifier ¶
func NewDatabasePresenceVerifier(query PresenceQuery) *DatabasePresenceVerifier
NewDatabasePresenceVerifier returns a verifier that counts through the given query.
func (*DatabasePresenceVerifier) Connection ¶
func (d *DatabasePresenceVerifier) Connection() string
Connection reports the connection SetConnection named, which is what the query is expected to run on.
func (*DatabasePresenceVerifier) GetCount ¶
func (d *DatabasePresenceVerifier) GetCount(ctx context.Context, g auth.Grant, collection, column string, value any, excludeID any, idColumn string, extra map[string]string) (int, error)
GetCount counts the rows holding the value, through the query this was built with.
func (*DatabasePresenceVerifier) GetMultiCount ¶
func (d *DatabasePresenceVerifier) GetMultiCount(ctx context.Context, g auth.Grant, collection, column string, values []any, extra map[string]string) (int, error)
GetMultiCount counts the rows holding any of the values, through the same query.
func (*DatabasePresenceVerifier) SetConnection ¶
func (d *DatabasePresenceVerifier) SetConnection(connection string)
SetConnection names the connection the query is expected to run on.
type DatabaseRule ¶
type DatabaseRule struct {
// contains filtered or unexported fields
}
DatabaseRule holds what the two database rules have in common: the table and the column to look in, the extra conditions that narrow the search, and the query callbacks registered through Using. Unique and Exists embed it rather than repeat it, so the Where methods below are written once and read as methods on either; FormatWheres renders the conditions into the parameter list each of them builds. It is not useful on its own.
func (*DatabaseRule) FormatWheres ¶
func (r *DatabaseRule) FormatWheres() string
FormatWheres renders the conditions into the trailing parameters of the rule, column then value, every value quoted.
func (*DatabaseRule) OnlyTrashed ¶
func (r *DatabaseRule) OnlyTrashed(deletedAtColumn ...string) *DatabaseRule
OnlyTrashed narrows the search to rows that are soft deleted. The column defaults to deleted_at.
func (*DatabaseRule) QueryCallbacks ¶
func (r *DatabaseRule) QueryCallbacks() []func(query any)
QueryCallbacks returns the callbacks Using registered.
func (*DatabaseRule) ResolveTableName ¶
func (r *DatabaseRule) ResolveTableName(table string) string
ResolveTableName returns the table a rule queries. There are no models here, so a table name is already the table name.
func (*DatabaseRule) Using ¶
func (r *DatabaseRule) Using(callback func(query any)) *DatabaseRule
Using registers a query callback the rule runs instead of the conditions it would otherwise build.
The query is any because the builder belongs to hesape/database and this package does not import it -- a rule carries the callback and the repository that runs it knows what it holds.
func (*DatabaseRule) Where ¶
func (r *DatabaseRule) Where(column, value string) *DatabaseRule
Where narrows the search to rows holding value in column.
func (*DatabaseRule) WhereIn ¶
func (r *DatabaseRule) WhereIn(column string, values ...string) *DatabaseRule
WhereIn narrows the search to rows holding one of the values in column.
func (*DatabaseRule) WhereNot ¶
func (r *DatabaseRule) WhereNot(column, value string) *DatabaseRule
WhereNot narrows the search to rows NOT holding value in column.
func (*DatabaseRule) WhereNotIn ¶
func (r *DatabaseRule) WhereNotIn(column string, values ...string) *DatabaseRule
WhereNotIn narrows the search to rows holding none of the values in column.
func (*DatabaseRule) WhereNotNull ¶
func (r *DatabaseRule) WhereNotNull(column string) *DatabaseRule
WhereNotNull narrows the search to rows holding anything but null in column.
func (*DatabaseRule) WhereNull ¶
func (r *DatabaseRule) WhereNull(column string) *DatabaseRule
WhereNull narrows the search to rows holding null in column.
func (*DatabaseRule) WithoutTrashed ¶
func (r *DatabaseRule) WithoutTrashed(deletedAtColumn ...string) *DatabaseRule
WithoutTrashed narrows the search to rows that are not soft deleted. The column defaults to deleted_at.
type Date ¶
type Date struct {
// contains filtered or unexported fields
}
Date builds the date rules of one field, without the caller remembering their names. Build one with NewDate.
func (*Date) AfterOrEqual ¶
AfterOrEqual adds after_or_equal, against the given moment.
func (*Date) BeforeOrEqual ¶
BeforeOrEqual adds before_or_equal, against the given moment.
func (*Date) BetweenOrEqual ¶
BetweenOrEqual adds after_or_equal and before_or_equal, so both ends are inclusive.
func (*Date) Format ¶
Format sets the layout the value has to be written in, which makes the rule date_format rather than date. It is a GO layout -- Format("2006-01-02"), never "Y-m-d".
func (*Date) TodayOrAfter ¶
TodayOrAfter adds after_or_equal:today.
func (*Date) TodayOrBefore ¶
TodayOrBefore adds before_or_equal:today.
type Dimensioner ¶
type Dimensioner interface {
// Dimensions returns the pixel size of an image, and false when the bytes
// are not one.
Dimensions() (width, height int, ok bool)
}
Dimensioner is a File that knows its own pixel size. One that implements it is measured through it; one that does not has its bytes decoded instead.
type Dimensions ¶
type Dimensions struct {
// contains filtered or unexported fields
}
Dimensions builds the "dimensions" rule: the pixel width and height an uploaded image must have or stay within, and the aspect ratio it must match. Each method sets one constraint, and String renders them all as a single rule in a fixed order rather than the order they were set, since a Go map remembers none. Build one with NewDimensions.
func NewDimensions ¶
func NewDimensions() *Dimensions
NewDimensions returns a Dimensions carrying no constraint yet.
func (*Dimensions) Height ¶
func (r *Dimensions) Height(value int) *Dimensions
Height sets the exact height, in pixels.
func (*Dimensions) MaxHeight ¶
func (r *Dimensions) MaxHeight(value int) *Dimensions
MaxHeight sets the highest height, in pixels.
func (*Dimensions) MaxRatio ¶
func (r *Dimensions) MaxRatio(value float64) *Dimensions
MaxRatio sets the highest aspect ratio.
func (*Dimensions) MaxWidth ¶
func (r *Dimensions) MaxWidth(value int) *Dimensions
MaxWidth sets the highest width, in pixels.
func (*Dimensions) MinHeight ¶
func (r *Dimensions) MinHeight(value int) *Dimensions
MinHeight sets the lowest height, in pixels.
func (*Dimensions) MinRatio ¶
func (r *Dimensions) MinRatio(value float64) *Dimensions
MinRatio sets the lowest aspect ratio.
func (*Dimensions) MinWidth ¶
func (r *Dimensions) MinWidth(value int) *Dimensions
MinWidth sets the lowest width, in pixels.
func (*Dimensions) Ratio ¶
func (r *Dimensions) Ratio(value float64) *Dimensions
Ratio sets the exact aspect ratio, width over height.
func (*Dimensions) RatioBetween ¶
func (r *Dimensions) RatioBetween(min, max float64) *Dimensions
RatioBetween sets both ends of the aspect ratio.
func (*Dimensions) String ¶
func (r *Dimensions) String() string
String renders the constraints as one rule, in dimensionOrder.
func (*Dimensions) Width ¶
func (r *Dimensions) Width(value int) *Dimensions
Width sets the exact width, in pixels.
type EmailRule ¶
type EmailRule struct {
// contains filtered or unexported fields
}
EmailRule builds the "email" rule together with the list of checks it should run: the RFC reading, a stricter one, an MX record lookup on the domain, the spoofing check, and the native one. With nothing asked for it renders the bare "email", which is the shape check alone. Build one with NewEmailRule. It carries the suffix because Email is already the one-value helper here.
func NewEmailRule ¶
func NewEmailRule() *EmailRule
NewEmailRule returns an EmailRule asking for the shape check alone.
func (*EmailRule) PreventSpoofing ¶
PreventSpoofing asks for the spoofing check.
func (*EmailRule) RfcCompliant ¶
RfcCompliant asks for the RFC reading, or for the stricter one when strict is true.
func (*EmailRule) String ¶
String renders the chain. With nothing asked for it is the bare `email`, which is the shape check.
func (*EmailRule) ValidateMxRecord ¶
ValidateMxRecord asks for the lookup on the domain.
func (*EmailRule) WithNativeValidation ¶
WithNativeValidation asks for the native check, allowing unicode when told to.
type Enum ¶
type Enum struct {
// contains filtered or unexported fields
}
Enum is the rule that the value must be one of the cases of a type.
Only and Except then narrow them. Build it with EnumOf, which reads the cases off the type, or with NewEnum when there is no type to read -- a set that lives in a column and nowhere else.
func EnumOf ¶ added in v0.25.0
EnumOf returns an Enum over the cases of a generated enum type.
validation.EnumOf(enums.InvoiceStatusValues()...)
The cases are derived rather than written, so the rule cannot disagree with the type -- which is the failure a hand-written list produces and nothing reports. It takes the values because the generated list of them is a package function, the one place that knows the declaration order.
func NewEnum ¶
NewEnum returns an Enum over the given cases.
The cases are text, so the rule can only compare text. Prefer EnumOf wherever a generated type exists: a list written beside a type is a second copy of the set, and the two disagree the first time a case is added to one of them.
func (*Enum) Passes ¶
Passes reports whether the value is one of the cases, after Only and Except have narrowed them.
A value of the enum type is asked rather than compared: stringOf renders a named type as nothing, so comparing text used to refuse every typed value the rule was built for. Only and Except still narrow, and they narrow on the shown spelling, which is what the caller wrote them in.
func (*Enum) SetValidator ¶
SetValidator hands the rule the validator running it, so that its message comes from the same translator.
type Errors ¶
Errors maps a field to its messages. It is what a view draws its inline errors from, and it serializes straight into the HTMX partial that re-renders the form.
func (Errors) Add ¶
Add appends a message to a field. It is a no-op on a nil map, so a caller that forgot to initialize the map does not panic in the middle of a request.
func (Errors) All ¶
All returns every message in the bag, with the fields in a stable order so that two renders of the same failure agree.
A Go map remembers no order, so the fields are sorted.
func (Errors) Error ¶
Error renders the errors with fields in a stable order, so that logs and golden files do not change between runs.
func (Errors) First ¶
First returns the first message for a key, or the first message of any key when none is given.
Only the first key of the variadic is read. A key with no messages is the empty string.
With no key the field order is not stable -- a map has none -- so that form answers "what is wrong" and not "which field". When which field failed matters, pass the key.
func (Errors) Get ¶
Get returns every message for a key.
An absent key is an empty slice. There is no wildcard form: this bag keys by the field name the validator wrote, and no rule writes a star into one.
func (Errors) GetMessages ¶
GetMessages is an alias of Messages.
func (Errors) Has ¶
Has reports whether every key given has at least one message. No key at all is Any.
func (Errors) IsNotEmpty ¶
IsNotEmpty reports whether anything failed.
type ExcludeIf ¶
type ExcludeIf struct{ Condition bool }
ExcludeIf renders the "exclude" rule when its condition holds and an empty string when it does not, so a field can be dropped from a rule set without branching around the set itself. An excluded attribute is removed from the validated data rather than reported: it is not part of this request, which is a different thing from being wrong, and no message is put on it. Build one with NewExcludeIf.
func NewExcludeIf ¶
NewExcludeIf returns an ExcludeIf over a condition already settled. A caller holding a closure calls it: the condition is a bool, so nothing else can be passed by mistake.
type Exists ¶
type Exists struct{ DatabaseRule }
Exists builds the "exists" rule: some row in the table must already hold this value in the column, which is how an identifier arriving from a form is checked before anything is written against it. The check is a read of the table, so it runs only with a Grant carrying a tenant and counts only that tenant's rows -- an identifier belonging to somebody else does not exist as far as this rule is concerned. Build one with NewExists.
type ExplodedRules ¶
type ExplodedRules struct {
// Rules is one entry per attribute, holding the rules written against it in
// the order they were written.
Rules map[string][]string
// Order is the order the attributes were written in, because a Go map
// remembers none.
Order []string
// ImplicitAttributes is the wildcard key each expanded attribute came from,
// which is what names a field in a message the way the caller wrote it.
ImplicitAttributes map[string][]string
}
ExplodedRules is a rule set with every wildcard expanded, together with the wildcard keys that produced it.
type ExtensionFunc ¶
ExtensionFunc is a rule written by the application, called with the arguments every rule in the catalogue is.
type Factory ¶
type Factory struct {
// contains filtered or unexported fields
}
Factory makes Validators already wired to the translator, the presence verifier and the message overrides an application registered once.
It is a value an application builds at boot and hands where it is needed. There is no global one, and nothing here resolves an extension by name: an extension is a function, and Extend takes it directly.
func NewFactory ¶
func NewFactory(translator Translator) *Factory
NewFactory returns a Factory over a translator. The translator may be nil, and then every Validator it makes falls back to the compiled rule set's own sentences -- see getMessage.
func (*Factory) ExcludeUnvalidatedArrayKeys ¶
func (f *Factory) ExcludeUnvalidatedArrayKeys()
ExcludeUnvalidatedArrayKeys drops the keys of an array that no rule declared.
func (*Factory) Extend ¶
func (f *Factory) Extend(rule string, extension ExtensionFunc, message ...string)
Extend registers a rule this application adds, and the sentence it says when it fails.
It registers into the one catalogue MustCompile checks against, so the name is real for every rule set compiled after this call -- which is why it belongs at start-up, before any set is compiled.
func (*Factory) ExtendDependent ¶
func (f *Factory) ExtendDependent(rule string, extension ExtensionFunc, message ...string)
ExtendDependent registers a rule whose first parameter names another field.
func (*Factory) ExtendImplicit ¶
func (f *Factory) ExtendImplicit(rule string, extension ExtensionFunc, message ...string)
ExtendImplicit registers a rule that runs even when the attribute is blank, the way `required` does.
func (*Factory) GetPresenceVerifier ¶
func (f *Factory) GetPresenceVerifier() PresenceVerifier
GetPresenceVerifier returns the verifier this Factory hands its Validators.
func (*Factory) GetTranslator ¶
func (f *Factory) GetTranslator() Translator
GetTranslator returns the catalogue this Factory hands its Validators.
func (*Factory) IncludeUnvalidatedArrayKeys ¶
func (f *Factory) IncludeUnvalidatedArrayKeys()
IncludeUnvalidatedArrayKeys keeps the keys of an array that no rule declared.
func (*Factory) Make ¶
func (f *Factory) Make(data Data, rules *Set, opts ...ValidatorOption) *Validator
Make returns a Validator over the data and the rules, with everything this Factory carries already on it.
The rules are a compiled Set rather than an array of strings, because the strings are parsed and checked at boot -- see MustCompile. Per-call overrides are the WithCustomMessages and WithCustomAttributes options.
func (*Factory) Replacer ¶
func (f *Factory) Replacer(rule string, replacer ReplacerFunc)
Replacer registers how one rule fills the placeholders of its own message.
func (*Factory) Resolver ¶
func (f *Factory) Resolver(resolver func(data Data, rules *Set, opts []ValidatorOption) *Validator)
Resolver registers another way of building the Validator itself, which is how an application ships one of its own.
func (*Factory) SetAttributeNames ¶
SetAttributeNames sets the field names every Validator this Factory makes starts with.
func (*Factory) SetCustomMessages ¶
SetCustomMessages sets the inline messages every Validator this Factory makes starts with.
func (*Factory) SetPresenceVerifier ¶
func (f *Factory) SetPresenceVerifier(g auth.Grant, presenceVerifier PresenceVerifier)
SetPresenceVerifier sets the Grant and the verifier this Factory hands its Validators.
type File ¶
type File interface {
// GetPath returns the non-empty location or upload name that identifies the
// file. An empty path is a file that was never written, which `mimes` and
// `mimetypes` refuse.
GetPath() string
// GetRealPath returns where the bytes are.
GetRealPath() string
// GetSize returns the size in bytes. The size rules divide it by 1024,
// because `max:100` on a file means kilobytes.
GetSize() int64
// GetMimeType returns the media type, guessed from the content.
GetMimeType() string
// GetExtension returns the extension of the file's own name.
GetExtension() string
// GuessExtension returns the extension implied by the content, which is what
// `mimes` compares and why a .png renamed to .jpg does not pass.
GuessExtension() string
}
File is the shape `file`, `mimes`, `mimetypes`, `extensions`, `dimensions` and the size rules ask about an upload.
It is an interface rather than a struct because the upload itself belongs to the HTTP layer. A type there satisfies this by having the methods, with no import either way.
type FileRule ¶
type FileRule struct {
// contains filtered or unexported fields
}
FileRule builds the rules an upload has to pass: what it may be, and how big it may be. It carries the suffix because File is already the upload interface. Build one with NewFileRule, or with NewImageFile.
func NewFileRule ¶
func NewFileRule() *FileRule
NewFileRule returns a FileRule that asks only for an upload that finished.
func NewImageFile ¶
NewImageFile returns a FileRule that asks for an image, and for an SVG too when allowSvg is true.
func (*FileRule) Dimensions ¶
func (r *FileRule) Dimensions(dimensions *Dimensions) *FileRule
Dimensions adds the dimension rule the builder rendered.
func (*FileRule) Extensions ¶
Extensions sets the extensions the upload may carry. It is the extension the BROWSER sent, which is not the same question the content asks.
type ImplicitRule ¶
type ImplicitRule interface {
// Implicit reports whether this rule runs on a blank value.
Implicit() bool
}
ImplicitRule is a rule that runs even when the value is blank. The marker is the question itself, because an interface here needs a method.
type In ¶
type In struct {
// contains filtered or unexported fields
}
In builds the "in" rule -- the value must be one of a fixed list -- without the caller spelling the rule string by hand. String renders every value quoted, so one containing a comma survives the parameter list instead of splitting into two allowed values. Build one with NewIn.
type Input ¶
type Input struct {
// contains filtered or unexported fields
}
Input is what passed the rules. It is the only way to read a submitted value out of a validated request: a field the set does not declare is not in here, so a value nobody wrote a rule for cannot reach a repository by accident.
func (Input) Bool ¶
Bool reads a checkbox.
It accepts every value `accepted` does -- "1", "on", "yes", "true" -- and not only the "0" and "1" that the `boolean` rule allows, because an unticked checkbox sends nothing and a ticked one sends "on". Anything else is false: a checkbox has no third answer.
func (Input) Data ¶
Data returns a copy of everything that passed, in the shape the rules read it. It is a copy so that a caller cannot reach back into the request's own values through it.
func (Input) Float ¶
Float returns the value as a number, zero when there is none. `numeric` or `decimal` is what proves there is.
func (Input) Int ¶
Int returns the value as a whole number. It is zero when the field was not sent or does not hold one -- which is a rule's job to have proven, with `integer`.
func (Input) String ¶
String returns the value, or empty when the field was not sent. A field sent more than once is a list, and this is its first value -- what url.Values.Get answers.
func (Input) Strings ¶
Strings returns every value of a field, which is what a multi-select sends. A field sent once is a list of one.
type InvokableValidationRule ¶
type InvokableValidationRule struct {
// contains filtered or unexported fields
}
InvokableValidationRule is a ValidationRule wrapped so that it reads as a Rule. Build one with NewInvokableValidationRule.
func NewInvokableValidationRule ¶
func NewInvokableValidationRule(invokable ValidationRule) *InvokableValidationRule
NewInvokableValidationRule wraps a ValidationRule as a Rule, carrying over whether the wrapped one is implicit.
The name is New rather than Make because Make is already the Validator's constructor.
func (*InvokableValidationRule) Implicit ¶
func (r *InvokableValidationRule) Implicit() bool
Implicit reports whether the wrapped rule runs on a blank value.
func (*InvokableValidationRule) Invokable ¶
func (r *InvokableValidationRule) Invokable() ValidationRule
Invokable returns the rule this wraps.
func (*InvokableValidationRule) Message ¶
func (r *InvokableValidationRule) Message() []string
Message returns what the last Passes collected.
func (*InvokableValidationRule) Passes ¶
func (r *InvokableValidationRule) Passes(attribute string, value any) bool
Passes runs the wrapped rule, handing it the data and the validator first when it asks for them, and reports whether it called fail. A nil rule passes.
func (*InvokableValidationRule) SetData ¶
func (r *InvokableValidationRule) SetData(data Data)
SetData hands the wrapper every value being validated.
func (*InvokableValidationRule) SetValidator ¶
func (r *InvokableValidationRule) SetValidator(validator *Validator)
SetValidator hands the wrapper the validator running it.
type Messages ¶
Messages overrides the sentence one rule puts on one field, keyed "field.rule":
validation.MustCompile(rules, validation.WithMessageOverrides(validation.Messages{
"email.required": "we need an address to send the receipt to",
}))
A key naming a field or a rule the set does not declare is a boot failure: a typo in an override is otherwise invisible, because the default sentence is still there and still reads correctly.
type NestedRules ¶
type NestedRules struct {
// contains filtered or unexported fields
}
NestedRules is the rules for one member of an array, decided by looking at that member. Build one with NewNestedRules.
func ForEach ¶
func ForEach(callback func(value any, attribute string, data Data) Rules) *NestedRules
ForEach returns rules for one member of an array, decided by looking at that member.
func NewNestedRules ¶
func NewNestedRules(callback func(value any, attribute string, data Data) Rules) *NestedRules
NewNestedRules returns rules the callback decides, member by member.
func (*NestedRules) Compile ¶
func (n *NestedRules) Compile(attribute string, value any, data Data) *ExplodedRules
Compile asks the callback what this member's rules are, and expands them. A nil callback compiles to nothing.
type NotIn ¶
type NotIn struct {
// contains filtered or unexported fields
}
NotIn builds the "not_in" rule -- the value must be none of a fixed list -- with the same quoting In uses, so a listed value containing a comma is still one value. Build one with NewNotIn.
type Numeric ¶
type Numeric struct {
// contains filtered or unexported fields
}
Numeric builds a whole chain of numeric rules for one field -- bounds, digit counts, decimal places, comparisons against another field -- without the caller remembering any of their names. It always begins with "numeric", and String renders the chain with repeats dropped, because several of the methods add "integer" of their own. Build one with NewNumeric.
func NewNumeric ¶
func NewNumeric() *Numeric
NewNumeric returns a Numeric carrying `numeric` and nothing else yet.
func (*Numeric) DigitsBetween ¶
DigitsBetween adds integer and digits_between.
func (*Numeric) GreaterThan ¶
GreaterThan adds gt, against the named field.
func (*Numeric) GreaterThanOrEqualTo ¶
GreaterThanOrEqualTo adds gte, against the named field.
func (*Numeric) LessThanOrEqualTo ¶
LessThanOrEqualTo adds lte, against the named field.
func (*Numeric) MultipleOf ¶
MultipleOf adds multiple_of.
type Option ¶
type Option func(*settings)
Option adjusts a compilation.
func WithMessageOverrides ¶
WithMessageOverrides replaces the default sentence for the named field and rule.
It is not spelled WithMessages: that name belongs to WithMessages on a ValidationException, and this is a compile-time override of a sentence rather than an exception built out of one.
type Password ¶
type Password struct {
// contains filtered or unexported fields
}
Password is the password policy of one field: a length, the kinds of character it must carry, and whether it has appeared in a leak.
It cannot be a rule string: it holds a verifier, and it says four different things depending on which part failed. It runs through Validator.After:
v.After(func(v *validation.Validator) {
v.ValidateUsingCustomRule("password", v.GetValue("password"), rule)
})
func NewPassword ¶
NewPassword returns a policy asking for a minimum length. A minimum below one is raised to one.
func PasswordDefault ¶
func PasswordDefault() *Password
PasswordDefault returns the registered policy, or a minimum of eight when none was registered.
func PasswordMin ¶
PasswordMin returns a policy asking for a minimum length.
func PasswordRequired ¶
PasswordRequired returns the `required` rule string and the default policy, which are the two things a required password field takes.
func PasswordSometimes ¶
PasswordSometimes returns the `sometimes` rule string and the default policy.
func (*Password) AppliedRules ¶
AppliedRules returns what this policy is currently asking for, which is what a "your password must" list on the form is drawn from.
func (*Password) Message ¶
Message returns what the last Passes refused, one sentence per failed check.
func (*Password) Passes ¶
Passes reports whether the value satisfies the policy, and Message says what failed when it does not.
The length and the merged rules are checked by a sibling validator compiled from the same chain; the four character checks run after it.
func (*Password) SetValidator ¶
SetValidator hands the rule the validator running it, so that its messages come from the same translator.
func (*Password) Uncompromised ¶
func (p *Password) Uncompromised(verifier UncompromisedVerifier, threshold ...int) *Password
Uncompromised refuses a password that has appeared in a data leak more times than the threshold allows.
The verifier is a parameter because nothing here resolves one. A nil verifier FAILS the check rather than passing it: "we could not ask" is not "it is safe".
type PresenceQuery ¶
type PresenceQuery func(ctx context.Context, g auth.Grant, collection, column string, values []any, excludeID any, idColumn string, extra map[string]string) (int, error)
PresenceQuery is the one question `unique` and `exists` ask of a store: how many rows of the collection hold any of the values in the column, once the Grant's tenant and the extra conditions are applied.
It is a function rather than a repository because building the query needs hesape/database, and this package does not import it: the application passes the query in, already written against whatever it stores rows in.
type PresenceVerifier ¶
type PresenceVerifier interface {
// GetCount returns how many rows of the collection hold the value in the
// column, excluding the row whose idColumn is excludeID when one is given,
// and matching every extra condition.
GetCount(ctx context.Context, g auth.Grant, collection, column string, value any, excludeID any, idColumn string, extra map[string]string) (int, error)
// GetMultiCount returns how many rows hold any of the values.
GetMultiCount(ctx context.Context, g auth.Grant, collection, column string, values []any, extra map[string]string) (int, error)
}
PresenceVerifier is what `exists` and `unique` count rows through. Both methods take the context the query runs under and the Grant that authorizes it.
type ProhibitedIf ¶
type ProhibitedIf struct{ Condition bool }
ProhibitedIf renders the "prohibited" rule when its condition holds and an empty string when it does not. A prohibited attribute fails whenever it arrived with a value at all, which refuses a field that must not accompany this request instead of quietly ignoring it. Build one with NewProhibitedIf.
func NewProhibitedIf ¶
func NewProhibitedIf(condition bool) *ProhibitedIf
NewProhibitedIf returns a ProhibitedIf over a condition already settled.
func (*ProhibitedIf) String ¶
func (r *ProhibitedIf) String() string
String renders `prohibited` when the condition holds, and nothing at all when it does not.
type ReplacerFunc ¶
type ReplacerFunc func(message, attribute, rule string, parameters []string, validator *Validator) string
ReplacerFunc is a replacer an application registers with AddReplacer: message, attribute, rule, parameters, validator.
type RequiredIf ¶
type RequiredIf struct{ Condition bool }
RequiredIf renders the "required" rule when its condition holds and an empty string when it does not, so a field is demanded only in the case the caller decides. The condition is a bool settled before the rule set is built; a condition that has to look at the request is required_if, which is a rule name and takes the other field as its parameter. Build one with NewRequiredIf.
func NewRequiredIf ¶
func NewRequiredIf(condition bool) *RequiredIf
NewRequiredIf returns a RequiredIf over a condition already settled.
func (*RequiredIf) String ¶
func (r *RequiredIf) String() string
String renders `required` when the condition holds, and nothing at all when it does not.
type Resolver ¶
type Resolver interface {
// LookupIPAddr returns the A and AAAA records of the host.
LookupIPAddr(ctx context.Context, host string) ([]net.IPAddr, error)
}
Resolver is what `active_url` asks whether a host has an address record. *net.Resolver implements it, and net.DefaultResolver is the default.
type Rule ¶
type Rule interface {
// Passes reports whether the value satisfies the rule.
Passes(attribute string, value any) bool
// Message returns what the last Passes refused, one sentence per failure.
Message() []string
}
Rule is a check written as a type: it reports whether a value passes, and says what was wrong when it does not.
Message returns a slice because both wrappers below return several: one per call to their fail function.
type RuleFactory ¶
type RuleFactory struct{}
RuleFactory gathers the rule builders under one name, so that a rule set reads as a list of rules rather than as a list of constructors:
validation.Rules{
"role": validation.RuleFactory{}.In("admin", "member").String(),
"email": "required|email|" + validation.RuleFactory{}.Unique("users").String(),
}
It is not spelled Rule because that name is the interface a rule of one's own implements. It is an empty struct, and every method returns exactly what the matching NewX returns: a second way of NAMING a constructor, not a second constructor.
func (RuleFactory) AnyOf ¶
func (RuleFactory) AnyOf(sets ...*Set) *AnyOf
AnyOf builds an AnyOf: the value has to satisfy one of the rule sets.
func (RuleFactory) Array ¶
func (RuleFactory) Array(keys ...string) *ArrayRule
Array builds an `array` rule.
func (RuleFactory) Can ¶
func (RuleFactory) Can(allows func(g auth.Grant, ability string, arguments []string, value any) bool, ability string, arguments ...string) *Can
Can builds a Can: the rule passes when the subject the Grant was issued to is allowed the ability against the value.
func (RuleFactory) Default ¶
func (RuleFactory) Default() *FileRule
Default builds the file rule an application uses everywhere unless it says otherwise. Nothing stores it: what comes back is a plain builder, and the application keeps the one it made.
func (RuleFactory) Defaults ¶
func (RuleFactory) Defaults(rules ...string) *FileRule
Defaults builds a file rule with those rules already merged in. Nothing stores it either, for the reason Default gives.
func (RuleFactory) Dimensions ¶
func (RuleFactory) Dimensions() *Dimensions
Dimensions builds a `dimensions` rule.
func (RuleFactory) Enum ¶
func (RuleFactory) Enum(cases ...string) *Enum
Enum builds an `enum` rule.
Go has no enum type to read the cases off, so they are given: a Go program spells an enum as a named string type with a list of values, and that list is what this takes.
func (RuleFactory) ExcludeIf ¶
func (RuleFactory) ExcludeIf(condition bool) *ExcludeIf
ExcludeIf builds an ExcludeIf over a condition already settled.
func (RuleFactory) Exists ¶
func (RuleFactory) Exists(table string, column ...string) *Exists
Exists builds an `exists` rule.
func (RuleFactory) File ¶
func (RuleFactory) File() *FileRule
File builds the upload rules of one field.
func (RuleFactory) Image ¶
func (RuleFactory) Image(allowSvg ...bool) *FileRule
Image builds the upload rules of an image field, as ImageFile does.
func (RuleFactory) ImageFile ¶
func (RuleFactory) ImageFile(allowSvg ...bool) *FileRule
ImageFile builds the upload rules of an image field.
func (RuleFactory) NotIn ¶
func (RuleFactory) NotIn(values ...string) *NotIn
NotIn builds a `not_in` rule.
func (RuleFactory) Numeric ¶
func (RuleFactory) Numeric() *Numeric
Numeric builds the numeric rules of one field.
func (RuleFactory) Password ¶
func (RuleFactory) Password(min int) *Password
Password builds a password policy with a minimum length.
func (RuleFactory) ProhibitedIf ¶
func (RuleFactory) ProhibitedIf(condition bool) *ProhibitedIf
ProhibitedIf builds a ProhibitedIf over a condition already settled.
func (RuleFactory) RequiredIf ¶
func (RuleFactory) RequiredIf(condition bool) *RequiredIf
RequiredIf builds a RequiredIf over a condition already settled.
type Rules ¶
Rules is the rule set of one request, keyed by the name of the form input -- the same name components.FieldProps.Name carries.
A field's rules are one string, and the whole set is written in one place:
var Register = validation.MustCompile(validation.Rules{
"name": "required|max:255",
"email": "required|email",
"password": "required|min:12|confirmed",
})
What a string costs is that a typo in "requried" is not a compiler error. What Compile buys back is that it is a BOOT error, naming the field, the rule and the file -- so a rule set that boots is a rule set whose names are all real, whose regular expressions compile, whose numeric arguments are numbers and whose cross-field references name fields that exist.
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set is a compiled, checked rule set.
Build one in a package-level variable with MustCompile: the rules are then parsed once, at boot, and a set that boots is a set whose names are all real. A Set is read-only once compiled, so one is shared by every request; the per-request state lives in the Validator that Make builds over it.
func Compile ¶
Compile parses and checks a rule set, and reports everything wrong with it.
Use it where a rule set is built from something that is not a literal. Everywhere else the rule set belongs in a package-level variable, which is what MustCompile is for.
func MustCompile ¶
MustCompile is Compile for a package-level variable, which is where a rule set belongs: the check then runs before main does.
var StorePost = validation.MustCompile(validation.Rules{
"title": "required|max:255",
})
It panics, for the reason view.Register panics: finding out at boot beats finding out from the one request that first exercises the rule. A set compiled inside a handler is checked once per request and reports its typo to whoever triggered it -- `aru doctor` refuses that with rules-not-at-boot, because this package cannot see where it was called from.
func (*Set) RulesFor ¶
RulesFor returns the rule names written against one field, in the order they were written. It is nil for a field the set does not declare.
func (*Set) Validate ¶
Validate runs the set over a submitted form and returns what passed and what failed.
It is Make plus Passes for the common case: an HTML form, no upload, no rule that leaves the process. A set with `unique`, `exists`, `current_password` or `active_url` in it goes through Make instead, which is where the Grant, the verifier and the context are given -- those four fail closed here, on purpose: a read is authorized like any other, and a rule set carries no Grant.
The input is url.Values rather than Data because that is what a form arrives as; DataFrom is the conversion, and a name sent twice becomes a list.
The returned Errors is nil when nothing failed. Assigning it to an error interface makes that interface non-nil even so, because the type is not nil -- callers ask Any(), and http.Context.Validate returns a plain nil for exactly this reason.
type Translator ¶
type Translator interface {
// Get returns the line under the key, or the key itself when there is none.
Get(key string, replace map[string]any, locale string) any
// Choice returns the line under the key, in the form that number calls for.
Choice(key string, number int, replace map[string]any, locale string) string
}
Translator is the catalogue messages are read out of, narrowed to the two methods this package reaches for.
Get returns any because a language line is a string and a key naming a group -- "validation.custom", "validation.attributes", "validation.min" -- is a map. A key with no line answers with the key itself, which is what every "is there a custom message" check here compares against.
The locale is a parameter rather than state, as it is on hesape/translation.Translator: the locale belongs to the request. The empty string means the translator's own default.
type UncompromisedVerifier ¶
type UncompromisedVerifier interface {
// Verify reports false when the value has appeared more times than the
// threshold allows.
Verify(value string, threshold int) bool
}
UncompromisedVerifier answers whether a password has appeared in a data leak.
Asking a breach service is a network call and belongs with whoever owns the HTTP client, so what is here is only the question.
type Unique ¶
type Unique struct {
DatabaseRule
// contains filtered or unexported fields
}
Unique builds the "unique" rule: no row in the table may already hold this value in the column. Ignore names the one row allowed to hold it, which is how a form that edits an existing record does not collide with itself. The check is a read of the table, so it runs only with a Grant carrying a tenant and counts only that tenant's rows. Build one with NewUnique.
func NewUnique ¶
NewUnique returns a `unique` rule over the table. The column defaults to "NULL", which the rule reads as the attribute's own name.
func (*Unique) Ignore ¶
Ignore names the row this check is allowed to find, which is the row being edited.
func (*Unique) IgnoreModel ¶
IgnoreModel names the row being edited by its key rather than by the record itself. There are no records to pass here, so it is Ignore under a second name.
type UploadedFile ¶
type UploadedFile interface {
File
// GetClientOriginalExtension returns the extension of the name the browser
// sent, which is what `extensions` compares -- the name, not the content.
GetClientOriginalExtension() string
// IsValid reports whether the upload finished.
IsValid() bool
}
UploadedFile is a File that also knows what the client called it and whether the upload finished.
type Validatable ¶
type Validatable interface {
Validate() Errors
}
Validatable is implemented by every request type that checks itself.
type ValidationException ¶
type ValidationException struct {
// contains filtered or unexported fields
}
ValidationException is the error a failed Validate carries, and what a controller reads to answer 422.
Errors is the bag, GetStatus the code, GetErrorBag the named bag a redirect flashes it into, and GetRedirectTo where that redirect goes.
func NewValidationException ¶
func NewValidationException(validator *Validator, response ...any) *ValidationException
NewValidationException returns the error a failed run is turned into.
The variadic response is the answer the HTTP layer already prepared, when it prepared one. The bag starts at "default" and is changed with ErrorBag.
func WithMessages ¶
func WithMessages(messages map[string][]string) *ValidationException
WithMessages returns an exception built from a plain map of messages, for a failure that no rule produced.
func (*ValidationException) Error ¶
func (e *ValidationException) Error() string
Error is the summary: the first message, and how many more there were.
func (*ValidationException) ErrorBag ¶
func (e *ValidationException) ErrorBag(errorBag string) *ValidationException
ErrorBag names the bag a redirect flashes the messages into, so that two forms on one page do not draw each other's errors.
func (*ValidationException) Errors ¶
func (e *ValidationException) Errors() map[string][]string
Errors returns every validation message, keyed by the field it belongs to. It is what a controller turns into a 422 body.
func (*ValidationException) GetErrorBag ¶
func (e *ValidationException) GetErrorBag() string
GetErrorBag reads the bag ErrorBag named, for the reason GetStatus exists.
func (*ValidationException) GetRedirectTo ¶
func (e *ValidationException) GetRedirectTo() string
GetRedirectTo reads the URL RedirectTo named, for the reason GetStatus exists.
func (*ValidationException) GetResponse ¶
func (e *ValidationException) GetResponse() any
GetResponse returns the answer the HTTP layer prepared, when it prepared one.
func (*ValidationException) GetStatus ¶
func (e *ValidationException) GetStatus() int
GetStatus reads the code Status set. A field cannot carry the same name as the method that sets it, so the pair is spelled the way GetResponse already is.
func (*ValidationException) RedirectTo ¶
func (e *ValidationException) RedirectTo(url string) *ValidationException
RedirectTo names where the client is sent back to, which is the form it came from.
func (*ValidationException) Status ¶
func (e *ValidationException) Status(status int) *ValidationException
Status sets the HTTP status code to answer with. It returns the exception, so calls chain.
func (*ValidationException) Validator ¶
func (e *ValidationException) Validator() *Validator
Validator returns the run that failed.
type ValidationRule ¶
type ValidationRule interface {
// Validate checks the value, calling fail once per problem it finds.
Validate(attribute string, value any, fail func(message string))
}
ValidationRule is a check that reports a problem by calling fail with the sentence to show, rather than by returning false. NewInvokableValidationRule wraps one so that it reads as a Rule.
type ValidationRuleParser ¶
type ValidationRuleParser struct {
// Data is the request the wildcards are expanded against, because "items.*"
// means the items that were actually sent.
Data Data
// ImplicitAttributes is the wildcard key each expanded attribute came from,
// filled in as the expansion runs.
ImplicitAttributes map[string][]string
}
ValidationRuleParser turns a rule set as it was written into the rule set the validator runs: one list of rules per attribute, with every wildcard attribute -- "items.*.price" -- replaced by the concrete keys the request actually carries. It holds the request data because that expansion cannot be decided without it, and it remembers which wildcard each expanded key came from, so a message can name the field the way the caller wrote it.
func NewValidationRuleParser ¶
func NewValidationRuleParser(data Data) *ValidationRuleParser
NewValidationRuleParser returns a parser that expands wildcards against data.
func (*ValidationRuleParser) Explode ¶
func (p *ValidationRuleParser) Explode(rules Rules) *ExplodedRules
Explode turns the rules as they were written into the full rule set the validator runs.
The primary purpose of this parser is to expand any "*" rules to all of the explicit rules needed for the given data. For example the rule names.* would get expanded to names.0, names.1, and so on.
func (*ValidationRuleParser) MergeRules ¶
func (p *ValidationRuleParser) MergeRules(results Rules, attribute, rules string) Rules
MergeRules adds more rules to an attribute that may already have some.
type Validator ¶
type Validator struct {
// contains filtered or unexported fields
}
Validator is one submitted request, the rules written against it, and the answer.
It is built by Make and it is not safe for concurrent use: one belongs to one request. The compiled Set behind it is read-only and is shared by all of them.
The four rules that leave the process -- `unique`, `exists`, `current_password` and `active_url` -- take what they need through an option, and each of them fails closed when the thing it needs was not given.
func Make ¶
func Make(data Data, rules *Set, opts ...ValidatorOption) *Validator
Make returns a Validator over the data and the rules.
The rules are a compiled Set rather than an array of strings, because the strings are parsed and checked at boot -- see MustCompile. The data is copied, so that excluding a field does not reach back into the request's own map.
func (*Validator) AddCustomAttributes ¶
AddCustomAttributes merges more field names into the ones in force.
func (*Validator) AddCustomValues ¶
AddCustomValues merges more value names into the ones in force.
func (*Validator) AddDependentExtension ¶
func (v *Validator) AddDependentExtension(rule string, extension ExtensionFunc)
AddDependentExtension registers a rule of the application's own whose first parameter names another field, which is then checked at boot like every other cross-field reference.
func (*Validator) AddDependentExtensions ¶
func (v *Validator) AddDependentExtensions(extensions map[string]ExtensionFunc)
AddDependentExtensions registers several dependent rules at once.
func (*Validator) AddExtension ¶
func (v *Validator) AddExtension(rule string, extension ExtensionFunc)
AddExtension registers a rule of the application's own.
A rule name has to exist before MustCompile reads it, so an extension joins the one catalogue every rule set is checked against. Registering the same name twice panics, for the reason two answers to one rule name always do.
The catalogue is package level rather than per-validator: an extension is registered once, at start-up, before any validator is made.
func (*Validator) AddExtensions ¶
func (v *Validator) AddExtensions(extensions map[string]ExtensionFunc)
AddExtensions registers several rules of the application's own at once.
func (*Validator) AddFailure ¶
AddFailure records that one rule refused one attribute.
An exclude rule never puts a message on the field: its failure removes the field from the validated data instead, which is the whole of what the five exclude rules do.
func (*Validator) AddImplicitExtension ¶
func (v *Validator) AddImplicitExtension(rule string, extension ExtensionFunc)
AddImplicitExtension registers a rule of the application's own that runs even when the value is blank.
func (*Validator) AddImplicitExtensions ¶
func (v *Validator) AddImplicitExtensions(extensions map[string]ExtensionFunc)
AddImplicitExtensions registers several implicit rules at once.
func (*Validator) AddReplacer ¶
func (v *Validator) AddReplacer(rule string, replacer ReplacerFunc)
AddReplacer registers how one rule fills the placeholders of its own message.
func (*Validator) AddReplacers ¶
func (v *Validator) AddReplacers(replacers map[string]ReplacerFunc)
AddReplacers registers several replacers at once.
func (*Validator) AddRules ¶
AddRules merges another compiled set into this validator's, so that a rule decided at request time joins the ones decided at boot.
What is merged is a Set, already parsed and checked by MustCompile. A field both sets declare keeps the rules of both, in the order this one wrote them first.
func (*Validator) After ¶
After registers a callback that runs once every rule has.
It is where a check that needs the whole form goes, and it is the seam a rule object is run through: the callback holds the Validator, so it calls AddFailure with the attribute and rule name of its choosing.
func (*Validator) AllFailingRequired ¶
AllFailingRequired reports whether ALL of the attributes hold no answer.
func (*Validator) AnyFailingRequired ¶
AnyFailingRequired reports whether ANY of the attributes holds no answer.
func (*Validator) Attributes ¶
Attributes returns the data the rules run against.
func (*Validator) Compare ¶
Compare applies the operator to the result of a comparison. It takes what comparing the two values said rather than the values themselves, because there is no operator to apply to an any.
func (*Validator) CompareDates ¶
func (v *Validator) CompareDates(attribute string, value any, parameters []string, operator string) bool
CompareDates reads both moments and answers what the operator says. A moment that cannot be read fails on either side -- a date rule that cannot read the date has not been passed.
The other moment is a field this rule set declares, one of the three keywords today, tomorrow and yesterday, or a literal date. The keywords are those three and nothing else: a rule whose accepted set nobody can enumerate cannot be reasoned about.
func (*Validator) Context ¶
Context is the context every rule that leaves the process runs under: the request's, so a DNS lookup or a count query carries the request's deadline.
func (*Validator) CustomAttributes ¶
CustomAttributes returns the field names in force, read for the reason CustomMessages is.
func (*Validator) CustomMessages ¶
CustomMessages returns the inline messages in force, which a rule object reads to build a sibling validator that says the same things.
func (*Validator) EnsureExponentWithinAllowedRange ¶
EnsureExponentWithinAllowedRange asks that check.
With nothing registered the answer is the default range -- an exponent between -1000 and 1000 -- and never a plain yes: a range check that accepts every scale is no range check.
func (*Validator) EnsureExponentWithinAllowedRangeUsing ¶
func (v *Validator) EnsureExponentWithinAllowedRangeUsing(callback func(scale int, attribute string, value any) bool) *Validator
EnsureExponentWithinAllowedRangeUsing sets the check `numeric` and `decimal` make before they read a number written in exponent notation, so that "1e100000" is refused rather than turned into a float nobody meant.
func (*Validator) Errors ¶
Errors returns the messages a run collected, running first if it has not been.
func (*Validator) ExcludeAttribute ¶
ExcludeAttribute drops the attribute from the validated data.
func (*Validator) ExtractDistinctValues ¶
ExtractDistinctValues reads the attribute and returns it as a list, or nothing when it holds no list.
func (*Validator) FailsBasicDimensionChecks ¶
FailsBasicDimensionChecks reports whether the image misses any of width, min_width, max_width, height, min_height and max_height.
func (*Validator) FailsMaxRatioCheck ¶
FailsMaxRatioCheck reports whether the image is taller than max_ratio allows.
func (*Validator) FailsMinRatioCheck ¶
FailsMinRatioCheck reports whether the image is wider than min_ratio allows.
func (*Validator) FailsRatioCheck ¶
FailsRatioCheck reports whether the image misses the ratio. The tolerance widens with the image, so that a 3/2 photograph of 1201 by 800 is still 3/2.
func (*Validator) GetDNSRecords ¶
GetDNSRecords returns the addresses the hostname resolves to.
func (*Validator) GetDateFormat ¶
GetDateFormat returns the layout the field's date_format declares, and empty when it declares none.
func (*Validator) GetDisplayableAttribute ¶
GetDisplayableAttribute returns the name of a field as a sentence names it.
The default is the snake-cased name with its underscores turned into spaces: "password_confirmation" reads "password confirmation", LOWERCASE. The name sits inside the sentence ("The password confirmation field must match") and never at the head of one, so it is never capitalised here.
func (*Validator) GetDisplayableValue ¶
GetDisplayableValue returns how a value is spelled inside a message, after the custom values an application declared and the validation.values lines.
func (*Validator) GetDistinctValues ¶
GetDistinctValues returns the values `distinct` compares: the list held at the attribute, for the reason ValidateDistinct gives.
func (*Validator) GetException ¶
GetException returns what a failure is turned into: the function that builds the error.
func (*Validator) GetExtraConditions ¶
GetExtraConditions reads the trailing parameters in pairs, column then value.
func (*Validator) GetMessageBag ¶
GetMessageBag returns the messages a run collected, which is what Errors returns.
func (*Validator) GetPresenceVerifier ¶
func (v *Validator) GetPresenceVerifier() (PresenceVerifier, error)
GetPresenceVerifier returns the verifier `unique` and `exists` count through, and an error when none was set.
func (*Validator) GetQueryColumn ¶
GetQueryColumn returns the column the rule queries: the second parameter when it names one, and the guess otherwise.
func (*Validator) GetRule ¶
GetRule returns the first of the given rules written against the attribute, and the parameters it carries. The third value reports whether one was found.
func (*Validator) GetRulesWithoutPlaceholders ¶
GetRulesWithoutPlaceholders returns the same map GetRules does, for the reason ParseData is only a copy: no key was ever escaped, so there is nothing to take back out.
func (*Validator) GetSize ¶
GetSize is what min, max, size, between and the four comparisons measure.
A number is its own size when the field declares numeric, integer or decimal; an array is how many members it has; a file is its KILOBYTES; anything else is how many characters it has. Characters, never bytes: a limit in bytes rejects valid input in every language that needs more than one byte for a letter.
The size is a *big.Rat and not a float64, because 9007199254740993 and 9007199254740992 are the SAME float64: "numeric|max:9007199254740992" would pass on the value 9007199254740993, and a monetary limit or a quota would be over-runnable by one unit of rounding. math/big is stdlib and the comparison is exact.
The bool is false for an exponent outside the allowed range, which gives a value no size at all. Every caller fails the rule on it, which is the closed answer.
func (*Validator) GetTranslator ¶
func (v *Validator) GetTranslator() Translator
GetTranslator returns the catalogue messages are read out of, which is never nil: without one it is a translator that finds no line.
func (*Validator) GetUniqueExtra ¶
GetUniqueExtra returns the extra conditions of a `unique` rule, which are its parameters past the fourth.
func (*Validator) GetUniqueIds ¶
GetUniqueIds returns the column and the value of the row the rule must ignore, which is the row being edited.
func (*Validator) GuessColumnForQuery ¶
GuessColumnForQuery returns the last segment of a dotted attribute, and the attribute itself otherwise.
func (*Validator) IsValidFileInstance ¶
IsValidFileInstance reports whether the value is a File, and an upload that finished.
func (*Validator) MakeReplacements ¶
MakeReplacements fills every placeholder of a message with what actually happened.
It is exported because a rule object reaches for it.
func (*Validator) Now ¶
Now is the clock the relative date keywords read. It is settable so that a test of `after:today` does not have to be run before midnight.
func (*Validator) ParseData ¶
ParseData returns the request as the Validator will read it, which is a copy.
Nothing has to be escaped first: lookup tries the literal key before it walks a dotted path, so an input genuinely named "a.b" is found as itself. What is left is the copy, which keeps a Validator from writing through to the request's own map.
func (*Validator) ParseDependentRuleParameters ¶
ParseDependentRuleParameters returns the values a dependent rule compares against, and the other attribute's value.
Nothing is converted here. Reading "true", "false" and "null" as what they name is the comparison's job, so that one place decides what "the other field says yes" means.
func (*Validator) ParseNamedParameters ¶
ParseNamedParameters reads parameters of the form "min_width=100" into a map.
func (*Validator) ParseTable ¶
ParseTable splits "connection.table", and reads a bare name as the table. A rule names a table, never a model: there are no models.
func (*Validator) PrepareUniqueId ¶
PrepareUniqueId reads the ignored row's id: "[field]" takes it out of the submitted data, "null" is null, and a whole number is a number.
func (*Validator) ReplaceProhibitedIfDeclined ¶
func (v *Validator) ReplaceProhibitedIfDeclined(message, attribute, rule string, parameters []string) string
ReplaceProhibitedIfDeclined fills :other for `prohibited_if_declined`, exported for the reason ReplaceRequiredIfDeclined is.
func (*Validator) ReplaceRequiredIfDeclined ¶
func (v *Validator) ReplaceRequiredIfDeclined(message, attribute, rule string, parameters []string) string
ReplaceRequiredIfDeclined fills :other for `required_if_declined`. It is exported because it is called from outside this package.
func (*Validator) RequireParameterCount ¶
RequireParameterCount reports whether the rule was given the parameters it needs, and the rule that asked returns false when it was not.
The count is already proven at boot by compile.go, so this is the second lock on a door the first one closed -- and a rule invoked directly, outside a compiled set, still cannot read past the end of its parameters.
func (*Validator) Safe ¶
func (v *Validator) Safe(keys ...string) (*support.ValidatedInput, error)
Safe returns the validated attributes in a container that reads them one at a time, narrowed to the named keys when any are given.
It is a ValidatedInput either way, so a caller has one type to write against, and ValidatedInput.All answers with the map.
func (*Validator) SetAttributeNames ¶
SetAttributeNames replaces the field names in force.
func (*Validator) SetCustomMessages ¶
SetCustomMessages merges more inline messages into the ones in force.
func (*Validator) SetData ¶
SetData replaces the request the rules run against. The data is copied, for the reason Make copies it.
func (*Validator) SetException ¶
SetException sets what a failure is turned into. The signature settles the shape, so only a nil factory is left to reject.
func (*Validator) SetFallbackMessages ¶
SetFallbackMessages sets the sentence a rule registered with Factory.Extend says when nothing else names one.
func (*Validator) SetImplicitAttributesFormatter ¶
SetImplicitAttributesFormatter sets how a wildcard attribute that nothing named is spelled.
func (*Validator) SetPresenceVerifier ¶
func (v *Validator) SetPresenceVerifier(g auth.Grant, presenceVerifier PresenceVerifier)
SetPresenceVerifier gives `unique` and `exists` the Grant and the verifier they need.
There is no way to give a verifier without a Grant: a read is authorized like any other. WithPresence is the same pair as an option.
func (*Validator) SetTranslator ¶
func (v *Validator) SetTranslator(translator Translator)
SetTranslator sets the catalogue messages are read out of.
func (*Validator) SetValueNames ¶
SetValueNames replaces the value names in force.
func (*Validator) ShouldBeExcluded ¶
ShouldBeExcluded reports whether the attribute, or a parent of it, was excluded.
func (*Validator) ShouldBlockPhpUpload ¶
ShouldBlockPhpUpload reports whether the explicit `extensions` rule refuses the client-announced name: one of phpExtensions is, unless the rule asked for php by name. Content-based rules deliberately do not consult this metadata.
func (*Validator) ShouldStopValidating ¶
ShouldStopValidating reports whether the field is finished, whatever rules it has left.
`bail` stops the field at its first failure. A failed implicit rule stops it too, without being asked: `required` failing must not also produce "must be at least 12 characters" about the same empty box.
func (*Validator) Sometimes ¶
func (v *Validator) Sometimes(attributes []string, rules *Set, callback func(payload *support.Fluent, value any) bool) *Validator
Sometimes adds rules to an attribute only when the callback says so.
The callback is handed the whole request, as a Fluent, and the value of the attribute being decided.
func (*Validator) StopOnFirstFailure ¶
StopOnFirstFailure leaves after the first field that fails, rather than reporting every field. It returns the Validator, so calls chain.
func (*Validator) Validate ¶
Validate returns the attributes that were validated, or the error the failures make.
The error is always a *ValidationException, so errors.As reaches the bag, the status and the redirect.
func (*Validator) ValidateAccepted ¶
ValidateAccepted is `accepted`: the value is one of yes, on, 1 or true. It implies the attribute is required.
func (*Validator) ValidateAcceptedIf ¶
ValidateAcceptedIf is `accepted_if`: accepted when the other attribute holds one of the given values.
func (*Validator) ValidateActiveUrl ¶
ValidateActiveUrl is `active_url`: the host of the value has an A or an AAAA record.
The name spells Url rather than URL because `url` is the rule somebody types, and ValidateUrl would then read differently from its neighbour here.
This puts a DNS lookup on the request path. The deadline comes from the Validator's context, which is the request's.
func (*Validator) ValidateAfter ¶
ValidateAfter is `after`: the date is later than the other moment.
func (*Validator) ValidateAfterOrEqual ¶
ValidateAfterOrEqual is `after_or_equal`: the date is not earlier than the other moment.
func (*Validator) ValidateAlpha ¶
ValidateAlpha is `alpha`: letters only. With the parameter "ascii" it is the ASCII letters only.
func (*Validator) ValidateAlphaDash ¶
ValidateAlphaDash is `alpha_dash`: letters, digits, dashes and underscores. With the parameter "ascii" it is the ASCII ones only.
func (*Validator) ValidateAlphaNum ¶
ValidateAlphaNum is `alpha_num`: letters and digits. With the parameter "ascii" it is the ASCII ones only.
func (*Validator) ValidateArray ¶
ValidateArray is `array`: the value is an array, and with parameters, an array with no key outside them.
func (*Validator) ValidateAscii ¶
ValidateAscii is `ascii`: every character is a 7-bit ASCII one.
func (*Validator) ValidateBail ¶
ValidateBail is `bail`. It is a marker: Set.Validate reads it and stops the field at its first failure.
func (*Validator) ValidateBefore ¶
ValidateBefore is `before`: the date is earlier than the other moment.
func (*Validator) ValidateBeforeOrEqual ¶
ValidateBeforeOrEqual is `before_or_equal`: the date is not later than the other moment.
func (*Validator) ValidateBetween ¶
ValidateBetween is `between`: the size is within the two bounds, both of them inclusive.
func (*Validator) ValidateBoolean ¶
ValidateBoolean is `boolean`. The comparison is by type as well as by value, so exactly six pass: true, false, 0, 1, "0" and "1". A ticked checkbox sends "on", which is what `accepted` is for.
func (*Validator) ValidateConfirmed ¶
ValidateConfirmed is `confirmed`: the value is repeated by <attribute>_confirmation, or by the attribute the parameter names.
func (*Validator) ValidateContains ¶
ValidateContains is `contains`: the array holds every one of the given values.
func (*Validator) ValidateCurrentPassword ¶
ValidateCurrentPassword is `current_password`: the value is the password of whoever is signed in.
The question is asked of the CurrentPasswordChecker given to the Validator with WithCurrentPassword. Without one the rule fails closed, because a password check that passes for want of a checker is the worst outcome available. The parameter, when given, names the guard.
func (*Validator) ValidateDate ¶
ValidateDate is `date`: the value reads as a date.
func (*Validator) ValidateDateEquals ¶
ValidateDateEquals is `date_equals`: the date is the other moment.
func (*Validator) ValidateDateFormat ¶
ValidateDateFormat is `date_format`: the value is a date written in one of the given layouts.
The layout is a GO layout -- date_format:2006-01-02, never date_format:Y-m-d. compile.go refuses a layout it cannot read at boot, rather than accepting one that then rejects every date.
More than one layout may be given, and the value passes when ANY of them matches. A numeric value is read as the text it prints as, so a JSON body that sent 20240301 unquoted is not refused for having no quotes.
func (*Validator) ValidateDecimal ¶
ValidateDecimal is `decimal`: the count of digits after the point is the given number, or between the two given numbers.
func (*Validator) ValidateDeclined ¶
ValidateDeclined is `declined`: the value is one of no, off, 0 or false. It implies the attribute is required.
func (*Validator) ValidateDeclinedIf ¶
ValidateDeclinedIf is `declined_if`: declined when the other attribute holds one of the given values.
func (*Validator) ValidateDifferent ¶
ValidateDifferent is `different`: this attribute holds none of the values the named ones hold. An attribute the form did not send is not compared: a field that is not in the form is not the same as this one.
func (*Validator) ValidateDigits ¶
ValidateDigits is `digits`: the value is digits only, and exactly the given number of them.
func (*Validator) ValidateDigitsBetween ¶
ValidateDigitsBetween is `digits_between`: the value is digits only, and how many of them is within the two bounds.
func (*Validator) ValidateDimensions ¶
ValidateDimensions is `dimensions`: the image measures what the named parameters ask for.
An SVG passes without being measured once its document is validated: it has no pixels to count. Validating it means reading its bytes, so a file that announces an SVG it will not let anyone read fails instead of passing. Supported raster bytes are decoded under fixed input and pixel bounds before their dimensions are compared.
func (*Validator) ValidateDistinct ¶
ValidateDistinct is `distinct`: no value repeats.
There are no wildcards in a rule string, so the rule is asked of the whole list at once rather than once per member. The parameters are `ignore_case`, which compares case-insensitively, and `strict`, which compares types as well as values.
func (*Validator) ValidateDoesntEndWith ¶
ValidateDoesntEndWith is `doesnt_end_with`: the value ends with none of the given suffixes.
func (*Validator) ValidateDoesntStartWith ¶
ValidateDoesntStartWith is `doesnt_start_with`: the value begins with none of the given prefixes.
func (*Validator) ValidateEmail ¶
ValidateEmail is `email`: the value has the shape of an address.
Shape is all it checks by default. Deliverability is proven by sending mail; the parameter `dns` asks whether the domain resolves at all, which is as far as a lookup can go.
func (*Validator) ValidateEndsWith ¶
ValidateEndsWith is `ends_with`: the value ends with one of the given suffixes.
func (*Validator) ValidateEnum ¶
ValidateEnum is `enum`: the value is one of the cases.
A value that carries its own type -- a generated enum -- is asked, and the parameters are not consulted for membership. The list in a rule string is a second copy of a set the type already holds, and a second copy can disagree with it: a case added to the type and not to the rule used to reject a value the column accepts, and the two were never compared by anything.
The parameters are still read, for exactly that disagreement. A case named in the rule that the type does not declare fails the rule outright, whatever the value was, because a rule listing a case nothing can produce was written against a different type -- and passing the field would hide it until the case that is missing arrives.
Written against an untyped value -- a string straight off a form, which is what a field that has not been typed yet carries -- the parameters are the only set there is, and the rule reads them. Without either, there is nothing to decide against and the value is refused rather than waved through.
func (*Validator) ValidateExclude ¶
ValidateExclude is `exclude`: always excluded.
func (*Validator) ValidateExcludeIf ¶
ValidateExcludeIf is `exclude_if`: excluded when the other attribute holds one of the given values.
func (*Validator) ValidateExcludeUnless ¶
ValidateExcludeUnless is `exclude_unless`: excluded unless the other attribute holds one of the given values.
func (*Validator) ValidateExcludeWith ¶
ValidateExcludeWith is `exclude_with`: excluded when the named attribute was sent.
func (*Validator) ValidateExcludeWithout ¶
ValidateExcludeWithout is `exclude_without`: excluded when the named attributes hold no answer.
func (*Validator) ValidateExists ¶
ValidateExists is `exists`: the table holds a row with this value.
The verifier arrives with the request, through WithPresence, together with the Grant -- because a rule that reads a table to answer "does this exist" is a read, and a read is authorized like any other. Without a verifier the rule fails closed.
func (*Validator) ValidateExtensions ¶
ValidateExtensions is `extensions`: the extension THE CLIENT SENT is one of the given ones. It is the counterpart of mimes, which asks the content instead.
func (*Validator) ValidateFile ¶
ValidateFile is `file`: the value is an upload that finished.
func (*Validator) ValidateFilled ¶
ValidateFilled is `filled`: a key that was sent holds an answer. A key that was not sent passes, which is the whole difference from required.
func (*Validator) ValidateGt ¶
ValidateGt is `gt`: greater than a literal bound, or than another attribute.
func (*Validator) ValidateGte ¶
ValidateGte is `gte`: greater than or equal to a literal bound, or to another attribute.
func (*Validator) ValidateHexColor ¶
ValidateHexColor is `hex_color`: the value is a hexadecimal colour.
func (*Validator) ValidateImage ¶
ValidateImage is `image`: a complete PNG, JPEG or GIF decoded under fixed bounds, plus a well-formed SVG when the parameters carry allow_svg. Formats without an audited decoder fail closed even when their MIME can be detected.
func (*Validator) ValidateIn ¶
ValidateIn is `in`: the value is one of the parameters.
A value that is an array on a field that also declares `array` passes when every member is one of the parameters, which is how a multi-select is validated in one rule.
func (*Validator) ValidateInArray ¶
ValidateInArray is `in_array`: the value is one of the values held by the other attribute.
func (*Validator) ValidateInteger ¶
ValidateInteger is `integer`: the value reads as a whole number.
func (*Validator) ValidateIp ¶
ValidateIp is `ip`: the value is an IP address of either version.
func (*Validator) ValidateIpv4 ¶
ValidateIpv4 is `ipv4`: the value is an IPv4 address.
func (*Validator) ValidateIpv6 ¶
ValidateIpv6 is `ipv6`: the value is an IPv6 address.
func (*Validator) ValidateJson ¶
ValidateJson is `json`: the value is text that parses as JSON.
func (*Validator) ValidateList ¶
ValidateList is `list`: the value is an array with consecutive integer keys. A Data is an array with names, so it is not a list; a []any is.
func (*Validator) ValidateLowercase ¶
ValidateLowercase is `lowercase`: the value is already all lower case.
func (*Validator) ValidateLt ¶
ValidateLt is `lt`: less than a literal bound, or than another attribute.
func (*Validator) ValidateLte ¶
ValidateLte is `lte`: less than or equal to a literal bound, or to another attribute.
func (*Validator) ValidateMacAddress ¶
ValidateMacAddress is `mac_address`: the value is a MAC address.
func (*Validator) ValidateMax ¶
ValidateMax is `max`: the size is at or below the bound. An upload that did not finish fails before its size is asked for.
func (*Validator) ValidateMaxDigits ¶
ValidateMaxDigits is `max_digits`: the value is digits only, and at most the given number of them.
func (*Validator) ValidateMimes ¶
ValidateMimes is `mimes`: the extension GUESSED FROM THE CONTENT is one of the given ones, which is why a .png renamed to .jpg does not pass. jpg and jpeg each stand for the other.
func (*Validator) ValidateMimetypes ¶
ValidateMimetypes is `mimetypes`: the media type of the content is one of the given ones. A parameter of the form "image/*" matches every type in the group.
func (*Validator) ValidateMin ¶
ValidateMin is `min`: the size is at or above the bound.
func (*Validator) ValidateMinDigits ¶
ValidateMinDigits is `min_digits`: the value is digits only, and at least the given number of them.
func (*Validator) ValidateMissing ¶
ValidateMissing is `missing`: the key was not sent at all.
func (*Validator) ValidateMissingIf ¶
ValidateMissingIf is `missing_if`: the key was not sent when the other attribute holds one of the given values.
func (*Validator) ValidateMissingUnless ¶
ValidateMissingUnless is `missing_unless`: the key was not sent unless the other attribute holds one of the given values.
func (*Validator) ValidateMissingWith ¶
ValidateMissingWith is `missing_with`: the key was not sent when ANY of the named attributes was.
func (*Validator) ValidateMissingWithAll ¶
ValidateMissingWithAll is `missing_with_all`: the key was not sent when ALL of the named attributes were.
func (*Validator) ValidateMultipleOf ¶
ValidateMultipleOf is `multiple_of`: the value divides by the parameter with no remainder.
Zero on both sides fails, a zero numerator over a non-zero denominator passes, and a zero denominator fails -- three cases written out, because "is 0 a multiple of 0" has no answer worth guessing.
func (*Validator) ValidateNotIn ¶
ValidateNotIn is `not_in`: the value is none of the parameters.
func (*Validator) ValidateNotRegex ¶
ValidateNotRegex is `not_regex`: the value does not match the pattern, which is a GO pattern for the reason ValidateRegex gives.
func (*Validator) ValidateNullable ¶
ValidateNullable is `nullable`. It is a marker: Set.Validate reads it and stops the field when the value is null -- null, not empty, which is the whole of the difference from leaving `required` off.
func (*Validator) ValidateNumeric ¶
ValidateNumeric is `numeric`: the value reads as a number.
func (*Validator) ValidatePresent ¶
ValidatePresent is `present`: the key was sent, whatever it holds.
func (*Validator) ValidatePresentIf ¶
ValidatePresentIf is `present_if`: the key was sent when the other attribute holds one of the given values.
func (*Validator) ValidatePresentUnless ¶
ValidatePresentUnless is `present_unless`: the key was sent unless the other attribute holds one of the given values.
func (*Validator) ValidatePresentWith ¶
ValidatePresentWith is `present_with`: the key was sent when ANY of the named attributes was.
func (*Validator) ValidatePresentWithAll ¶
ValidatePresentWithAll is `present_with_all`: the key was sent when ALL of the named attributes were.
func (*Validator) ValidateProhibited ¶
ValidateProhibited is `prohibited`: the attribute holds no answer.
func (*Validator) ValidateProhibitedIf ¶
ValidateProhibitedIf is `prohibited_if`: prohibited when the other attribute holds one of the given values.
func (*Validator) ValidateProhibitedIfAccepted ¶
func (v *Validator) ValidateProhibitedIfAccepted(attribute string, value any, parameters []string) bool
ValidateProhibitedIfAccepted is `prohibited_if_accepted`: prohibited when the other attribute is accepted.
func (*Validator) ValidateProhibitedIfDeclined ¶
func (v *Validator) ValidateProhibitedIfDeclined(attribute string, value any, parameters []string) bool
ValidateProhibitedIfDeclined is `prohibited_if_declined`: prohibited when the other attribute is declined.
func (*Validator) ValidateProhibitedUnless ¶
ValidateProhibitedUnless is `prohibited_unless`: prohibited unless the other attribute holds one of the given values.
func (*Validator) ValidateProhibits ¶
ValidateProhibits is `prohibits`: this attribute being present forbids the named ones.
func (*Validator) ValidateRegex ¶
ValidateRegex is `regex`: the value matches the pattern.
The pattern is a GO pattern: RE2, with no backreference and no lookaround, and with no delimiters around it. compile.go compiles it at boot, so an unclosed group is a boot failure naming the field rather than a 500 on the first form somebody submits.
func (*Validator) ValidateRequired ¶
ValidateRequired is `required`: the attribute holds an answer.
Absent is one of four things, and the four are the whole rule: null, a string that is nothing but whitespace, an array with no members, and a file that was never written. A form sending three spaces has not answered the question.
func (*Validator) ValidateRequiredArrayKeys ¶
func (v *Validator) ValidateRequiredArrayKeys(attribute string, value any, parameters []string) bool
ValidateRequiredArrayKeys is `required_array_keys`: the value is a keyed array holding every one of the named keys.
func (*Validator) ValidateRequiredIf ¶
ValidateRequiredIf is `required_if`: required when the other attribute holds one of the given values.
A key the form did not send at all passes: a form that does not carry the other field cannot be answering it.
func (*Validator) ValidateRequiredIfAccepted ¶
func (v *Validator) ValidateRequiredIfAccepted(attribute string, value any, parameters []string) bool
ValidateRequiredIfAccepted is `required_if_accepted`: required when the other attribute is accepted.
func (*Validator) ValidateRequiredIfDeclined ¶
func (v *Validator) ValidateRequiredIfDeclined(attribute string, value any, parameters []string) bool
ValidateRequiredIfDeclined is `required_if_declined`: required when the other attribute is declined.
func (*Validator) ValidateRequiredUnless ¶
ValidateRequiredUnless is `required_unless`: required unless the other attribute holds one of the given values.
func (*Validator) ValidateRequiredWith ¶
ValidateRequiredWith is `required_with`: required when ANY of the named attributes is present.
func (*Validator) ValidateRequiredWithAll ¶
ValidateRequiredWithAll is `required_with_all`: required when ALL of the named attributes are present.
func (*Validator) ValidateRequiredWithout ¶
ValidateRequiredWithout is `required_without`: required when ANY of the named attributes is missing.
func (*Validator) ValidateRequiredWithoutAll ¶
func (v *Validator) ValidateRequiredWithoutAll(attribute string, value any, parameters []string) bool
ValidateRequiredWithoutAll is `required_without_all`: required when ALL of the named attributes are missing.
func (*Validator) ValidateSame ¶
ValidateSame is `same`: this attribute and the named one hold the same value.
func (*Validator) ValidateSize ¶
ValidateSize is `size`: the size is exactly the given one.
The size is four things under one name, as GetSize measures it: the characters of a string, the value of a number when the field declares numeric, integer or decimal, the members of an array, and the KILOBYTES of a file.
func (*Validator) ValidateSometimes ¶
ValidateSometimes is `sometimes`. It is a marker: Set.Validate skips the field when its key was not sent at all.
func (*Validator) ValidateStartsWith ¶
ValidateStartsWith is `starts_with`: the value begins with one of the given prefixes.
func (*Validator) ValidateString ¶
ValidateString is `string`: the value is text.
It is not the tautology it looks like. A JSON body carries numbers, booleans and lists, and this is the rule that refuses them where text was asked for.
func (*Validator) ValidateTimezone ¶
ValidateTimezone is `timezone`: the value names a zone the system knows.
func (*Validator) ValidateUlid ¶
ValidateUlid is `ulid`: the value is a ULID.
func (*Validator) ValidateUnique ¶
ValidateUnique is `unique`: the table holds no row with this value.
The parameters, in order: unique:table,column,exceptID,idColumn,extraColumn,extraValue...
func (*Validator) ValidateUppercase ¶
ValidateUppercase is `uppercase`: the value is already all upper case.
func (*Validator) ValidateUrl ¶
ValidateUrl is `url`. The parameters are the schemes allowed, and http and https are the default.
func (*Validator) ValidateUsingCustomRule ¶
ValidateUsingCustomRule runs one rule object and puts whatever it says on the attribute.
A compiled Set holds rule names and not objects, so the only caller is an After hook -- which is why this is exported.
func (*Validator) ValidateUuid ¶
ValidateUuid is `uuid`: the value is a UUID.
func (*Validator) ValidateWithBag ¶
ValidateWithBag is Validate with the failures named, so that two forms on one page do not draw each other's errors.
type ValidatorAwareRule ¶
type ValidatorAwareRule interface {
// SetValidator hands the rule the validator running it.
SetValidator(validator *Validator)
}
ValidatorAwareRule is implemented by a rule object that needs the validator running it -- to phrase its message through the same translator, to read the custom messages and attribute names in force, or to reach a value it was not handed. The validator passes itself in before asking whether the value passes, and the rule keeps it for the length of that run.
type ValidatorOption ¶
type ValidatorOption func(*Validator)
ValidatorOption is what a request hands a Validator that a boot-time rule set cannot hold: the context it runs under, the Grant that authorizes its queries, and the collaborators of the rules that leave the process.
func WithClock ¶
func WithClock(now func() time.Time) ValidatorOption
WithClock sets the clock the relative date keywords read, so that a test of `after:today` does not have to be run before midnight.
func WithContext ¶
func WithContext(ctx context.Context) ValidatorOption
WithContext gives the Validator the request's context, so that a lookup or a count query carries the request's deadline. Without it the context is Background, and a rule that leaves the process has no deadline at all.
func WithCurrentPassword ¶
func WithCurrentPassword(c CurrentPasswordChecker) ValidatorOption
WithCurrentPassword gives `current_password` its checker.
func WithCustomAttributes ¶
func WithCustomAttributes(attributes map[string]string) ValidatorOption
WithCustomAttributes sets how a field is named inside a sentence, which is what the validation.attributes lines of a catalogue also carry.
func WithCustomMessages ¶
func WithCustomMessages(messages map[string]any) ValidatorOption
WithCustomMessages sets the sentence one field and one rule produce, keyed "field.rule", "rule" or "field", with "*" allowed in the field.
A value is a sentence, or -- for a size rule -- a group of them keyed by "numeric", "file", "array" and "string".
func WithCustomValues ¶
func WithCustomValues(values map[string]map[string]string) ValidatorOption
WithCustomValues sets how one value of one field is spelled inside a sentence, so that ":value" reads "credit card" and not "cc".
func WithPresence ¶
func WithPresence(g auth.Grant, p PresenceVerifier) ValidatorOption
WithPresence gives `unique` and `exists` the Grant and the verifier they need.
The Grant is not optional and there is no way to pass a verifier without one: a read is authorized like any other, and "the validator only counts rows" is how a count of rows becomes a way to ask whether another tenant has a user with a given email.
func WithResolver ¶
func WithResolver(r Resolver) ValidatorOption
WithResolver gives `active_url` and `email:dns` the resolver to ask. The default is net.DefaultResolver; a test gives its own and makes no network call at all.
func WithTranslator ¶
func WithTranslator(t Translator) ValidatorOption
WithTranslator gives the Validator the catalogue its messages are read out of, which is what turns "is required" into "The name field is required.".
It is optional. Without one the compiled rule set's own sentences are used, and every other layer -- inline messages, custom attribute names, the :placeholders -- still applies.