Documentation
¶
Overview ¶
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Package constraints provides validation constraint types and builders for pedantigo.
Index ¶
- Constants
- func BuildCrossFieldConstraintsForField(constraints map[string]string, structType reflect.Type, fieldIndex int) ([]CrossFieldConstraint, []SkipConstraint)
- func CheckTypeCompatibility(a, b any) error
- func Compare(a, b any) int
- func CompareToString(value any) string
- func CompareValues(op string, left, right any) (bool, error)
- func Dereference(t reflect.Type) reflect.Type
- func IsContextValidator(name string) bool
- func IsNumericType(t reflect.Type) bool
- func IsZeroValue(value any) bool
- func SetCtxValidatorLookup(fn func(name string) bool)
- func SetCustomValidatorLookup(fn func(name string) (CustomValidationFunc, bool))
- type CachedField
- type Constraint
- type ConstraintError
- type ContextConstraint
- type CrossFieldConstraint
- type CustomValidationFunc
- type FieldCache
- type FieldPath
- type SkipConstraint
Constants ¶
const ( // Core constraints. CMin = "min" CMax = "max" CGt = "gt" CGte = "gte" CLt = "lt" CLte = "lte" CEmail = "email" CUrl = "url" CUri = "uri" CUuid = "uuid" CUuid3 = "uuid3" CUuid4 = "uuid4" CUuid5 = "uuid5" CRegexp = "regexp" CIpv4 = "ipv4" CIpv6 = "ipv6" COneof = "oneof" COneofci = "oneofci" CEq = "eq" CNe = "ne" CEqIgnoreCase = "eq_ignore_case" CNeIgnoreCase = "ne_ignore_case" CLen = "len" // String constraints. CAscii = "ascii" CAlpha = "alpha" CAlphanum = "alphanum" CAlphaspace = "alphaspace" CAlphanumspace = "alphanumspace" CPrintascii = "printascii" CNumeric = "numeric" CNumber = "number" CHexadecimal = "hexadecimal" CAlphaunicode = "alphaunicode" CAlphanumunicode = "alphanumunicode" CContains = "contains" CExcludes = "excludes" CStartswith = "startswith" CEndswith = "endswith" CStartsnotwith = "startsnotwith" CEndsnotwith = "endsnotwith" CContainsany = "containsany" CExcludesall = "excludesall" CExcludesrune = "excludesrune" CContainsRune = "containsrune" CLowercase = "lowercase" CUppercase = "uppercase" CMultibyte = "multibyte" CUrnRfc2141 = "urn_rfc2141" CStripWhitespace = "strip_whitespace" CToLower = "to_lower" CToUpper = "to_upper" // Numeric constraints. CPositive = "positive" CNegative = "negative" CMultipleOf = "multiple_of" CMaxDigits = "max_digits" CDecimalPlaces = "decimal_places" CDisallowInfNan = "disallow_inf_nan" // Collection constraints. CUnique = "unique" CDefault = "default" // Network constraints. CIp = "ip" CCidr = "cidr" CCidrv4 = "cidrv4" CCidrv6 = "cidrv6" CMac = "mac" CHostname = "hostname" CHostnameRfc1123 = "hostname_rfc1123" CHostnamePort = "hostname_port" CFqdn = "fqdn" CPort = "port" CTcpAddr = "tcp_addr" CUdpAddr = "udp_addr" CTcp4Addr = "tcp4_addr" CHttpUrl = "http_url" CHttpsUrl = "https_url" // Finance constraints. CCreditCard = "credit_card" CBtcAddr = "btc_addr" CBtcAddrBech32 = "btc_addr_bech32" CEthAddr = "eth_addr" CLuhnChecksum = "luhn_checksum" // Identity constraints. CIsbn = "isbn" CIsbn10 = "isbn10" CIsbn13 = "isbn13" CIssn = "issn" CSsn = "ssn" CEin = "ein" CE164 = "e164" // Geo constraints. CLatitude = "latitude" CLongitude = "longitude" // Color constraints. CHexcolor = "hexcolor" CRgb = "rgb" CRgba = "rgba" CHsl = "hsl" CHsla = "hsla" // Encoding constraints. CJwt = "jwt" CJson = "json" CBase64 = "base64" CBase64url = "base64url" CBase64rawurl = "base64rawurl" CDatauri = "datauri" CBase32 = "base32" // Hash constraints. CMd4 = "md4" CMd5 = "md5" CSha256 = "sha256" CSha384 = "sha384" CSha512 = "sha512" CMongodb = "mongodb" // Misc constraints. CHtml = "html" CCron = "cron" CSemver = "semver" CUlid = "ulid" CDatetime = "datetime" CTimezone = "timezone" // Special. CRequired = "required" CSkipUnless = "skip_unless" CImage = "image" )
Constraint name constants.
const ( // Required constraints. CodeRequired = "REQUIRED" CodeRequiredIf = "REQUIRED_IF" CodeRequiredUnless = "REQUIRED_UNLESS" CodeRequiredWith = "REQUIRED_WITH" CodeRequiredWithout = "REQUIRED_WITHOUT" // Format constraints. CodeInvalidEmail = "INVALID_EMAIL" CodeInvalidURL = "INVALID_URL" CodeInvalidUUID = "INVALID_UUID" CodeInvalidIPv4 = "INVALID_IPV4" CodeInvalidIPv6 = "INVALID_IPV6" CodeInvalidIP = "INVALID_IP" CodeInvalidURI = "INVALID_URI" CodeInvalidHostname = "INVALID_HOSTNAME" CodeInvalidMAC = "INVALID_MAC" CodeInvalidCIDR = "INVALID_CIDR" CodeInvalidPort = "INVALID_PORT" CodeInvalidTCPAddr = "INVALID_TCP_ADDR" CodeInvalidUDPAddr = "INVALID_UDP_ADDR" CodeInvalidFQDN = "INVALID_FQDN" CodeInvalidHostnamePort = "INVALID_HOSTNAME_PORT" CodeInvalidHTTPURL = "INVALID_HTTP_URL" CodePatternMismatch = "PATTERN_MISMATCH" CodeInvalidDatetime = "INVALID_DATETIME" // Identity/Publishing constraints. CodeInvalidISBN = "INVALID_ISBN" CodeInvalidISBN10 = "INVALID_ISBN10" CodeInvalidISBN13 = "INVALID_ISBN13" CodeInvalidISSN = "INVALID_ISSN" CodeInvalidSSN = "INVALID_SSN" CodeInvalidEIN = "INVALID_EIN" CodeInvalidE164 = "INVALID_E164" // Finance constraints. CodeInvalidLuhn = "INVALID_LUHN" CodeInvalidCreditCard = "INVALID_CREDIT_CARD" CodeInvalidBitcoinAddress = "INVALID_BITCOIN_ADDRESS" CodeInvalidBitcoinBech32 = "INVALID_BITCOIN_BECH32" CodeInvalidEthereumAddress = "INVALID_ETHEREUM_ADDRESS" // Hash constraints. CodeInvalidMD4 = "INVALID_MD4" CodeInvalidMD5 = "INVALID_MD5" CodeInvalidSHA256 = "INVALID_SHA256" CodeInvalidSHA384 = "INVALID_SHA384" CodeInvalidSHA512 = "INVALID_SHA512" CodeInvalidMongoDB = "INVALID_MONGODB" // Miscellaneous format constraints. CodeInvalidHTML = "INVALID_HTML" CodeInvalidCron = "INVALID_CRON" CodeInvalidSemver = "INVALID_SEMVER" CodeInvalidULID = "INVALID_ULID" // Geographic constraints. CodeInvalidLatitude = "INVALID_LATITUDE" CodeInvalidLongitude = "INVALID_LONGITUDE" CodeInvalidCountryCode = "INVALID_COUNTRY_CODE" CodeInvalidPostalCode = "INVALID_POSTAL_CODE" CodeInvalidTimezone = "INVALID_TIMEZONE" // ISO code constraints. CodeInvalidCurrencyCode = "INVALID_CURRENCY_CODE" CodeInvalidLanguageTag = "INVALID_LANGUAGE_TAG" CodeInvalidSubdivision = "INVALID_SUBDIVISION_CODE" // File system constraints. CodeInvalidPath = "INVALID_PATH" CodeFileNotFound = "FILE_NOT_FOUND" CodeDirNotFound = "DIRECTORY_NOT_FOUND" CodeInvalidImage = "INVALID_IMAGE" // Color constraints. CodeInvalidHexColor = "INVALID_HEX_COLOR" CodeInvalidRGBColor = "INVALID_RGB_COLOR" CodeInvalidRGBA = "INVALID_RGBA" CodeInvalidHSL = "INVALID_HSL" CodeInvalidHSLA = "INVALID_HSLA" // Encoding constraints. CodeInvalidBase64 = "INVALID_BASE64" CodeInvalidBase64URL = "INVALID_BASE64URL" CodeInvalidBase64RawURL = "INVALID_BASE64_RAW_URL" CodeInvalidJSON = "INVALID_JSON" CodeInvalidJWT = "INVALID_JWT" CodeInvalidUUIDv3 = "INVALID_UUID_V3" CodeInvalidUUIDv4 = "INVALID_UUID_V4" CodeInvalidUUIDv5 = "INVALID_UUID_V5" CodeInvalidMultibyte = "INVALID_MULTIBYTE" CodeInvalidDataURI = "INVALID_DATA_URI" CodeInvalidBase32 = "INVALID_BASE32" CodeInvalidURN = "INVALID_URN" CodeInvalidHTTPSURL = "INVALID_HTTPS_URL" // Length constraints. CodeMinLength = "MIN_LENGTH" CodeMaxLength = "MAX_LENGTH" CodeExactLength = "EXACT_LENGTH" // Numeric constraints. CodeMinValue = "MIN_VALUE" CodeMaxValue = "MAX_VALUE" CodeExclusiveMin = "EXCLUSIVE_MIN" CodeExclusiveMax = "EXCLUSIVE_MAX" CodeMustBePositive = "MUST_BE_POSITIVE" CodeMustBeNegative = "MUST_BE_NEGATIVE" CodeMultipleOf = "MULTIPLE_OF" CodeMaxDigits = "MAX_DIGITS" CodeDecimalPlaces = "DECIMAL_PLACES" CodeInfNanNotAllowed = "INF_NAN_NOT_ALLOWED" // String constraints. CodeMustBeASCII = "MUST_BE_ASCII" CodeMustBeAlpha = "MUST_BE_ALPHA" CodeMustBeAlphanum = "MUST_BE_ALPHANUM" CodeMustBeNumeric = "MUST_BE_NUMERIC" CodeMustBeNumber = "MUST_BE_NUMBER" CodeMustBeHexadecimal = "MUST_BE_HEXADECIMAL" CodeMustBeAlphaUnicode = "MUST_BE_ALPHA_UNICODE" CodeMustBeAlphanumUnicode = "MUST_BE_ALPHANUM_UNICODE" CodeMustBeAlphaSpace = "MUST_BE_ALPHA_SPACE" CodeMustBeAlphanumSpace = "MUST_BE_ALPHANUM_SPACE" CodeMustBePrintableASCII = "MUST_BE_PRINTABLE_ASCII" CodeMustContain = "MUST_CONTAIN" CodeMustNotContain = "MUST_NOT_CONTAIN" CodeMustStartWith = "MUST_START_WITH" CodeMustEndWith = "MUST_END_WITH" CodeMustNotStartWith = "MUST_NOT_START_WITH" CodeMustNotEndWith = "MUST_NOT_END_WITH" CodeMustContainAny = "MUST_CONTAIN_ANY" CodeMustExcludeAll = "MUST_EXCLUDE_ALL" CodeMustExcludeRune = "MUST_EXCLUDE_RUNE" CodeContainsRune = "CONTAINS_RUNE" CodeMustBeLowercase = "MUST_BE_LOWERCASE" CodeMustBeUppercase = "MUST_BE_UPPERCASE" CodeMustBeStripped = "MUST_BE_STRIPPED" // Enum/const constraints. CodeInvalidEnum = "INVALID_ENUM" CodeConstMismatch = "CONST_MISMATCH" CodeEqIgnoreCase = "EQ_IGNORE_CASE" CodeNeIgnoreCase = "NE_IGNORE_CASE" // Collection constraints. CodeNotUnique = "NOT_UNIQUE" // Cross-field constraints. CodeMustEqualField = "MUST_EQUAL_FIELD" CodeMustNotEqualField = "MUST_NOT_EQUAL_FIELD" CodeMustBeGTField = "MUST_BE_GT_FIELD" CodeMustBeGTEField = "MUST_BE_GTE_FIELD" CodeMustBeLTField = "MUST_BE_LT_FIELD" CodeMustBeLTEField = "MUST_BE_LTE_FIELD" CodeExcludedIf = "EXCLUDED_IF" CodeExcludedUnless = "EXCLUDED_UNLESS" CodeExcludedWith = "EXCLUDED_WITH" CodeExcludedWithout = "EXCLUDED_WITHOUT" CodeRequiredWithAll = "REQUIRED_WITH_ALL" CodeRequiredWithoutAll = "REQUIRED_WITHOUT_ALL" CodeExcludedWithAll = "EXCLUDED_WITH_ALL" CodeExcludedWithoutAll = "EXCLUDED_WITHOUT_ALL" // OR constraints. CodeOrConstraintFailed = "OR_CONSTRAINT_FAILED" // Type errors. CodeUnknownField = "UNKNOWN_FIELD" CodeInvalidType = "INVALID_TYPE" CodeUnsupportedType = "UNSUPPORTED_TYPE" // Custom validation constraints. CodeFieldPathError = "FIELD_PATH_ERROR" // Nil pointer encountered in field path resolution CodeCustomValidation = "CUSTOM_VALIDATION" // Custom validator failed CodeContextValidation = "CONTEXT_VALIDATION" // Context-aware validator failed )
Error code constants for validation errors. Using SCREAMING_SNAKE_CASE convention.
const ( CFilepath = "filepath" // Validates file path syntax (does NOT check existence) CDirpath = "dirpath" // Validates directory path syntax (does NOT check existence) CFile = "file" // Validates file exists and is a file (checks disk) CDir = "dir" // Validates directory exists and is a directory (checks disk) )
Filesystem constraint name constants.
const ( CISO31661Alpha2 = "iso3166_1_alpha2" // ISO 3166-1 alpha-2 country code CISO3166Alpha2EU = "iso3166_alpha2_eu" // ISO 3166-1 alpha-2 EU country code CISO31661Alpha3 = "iso3166_1_alpha3" // ISO 3166-1 alpha-3 country code CISO3166Alpha3EU = "iso3166_alpha3_eu" // ISO 3166-1 alpha-3 EU country code CISO31661AlphaNumeric = "iso3166_1_alpha_numeric" // ISO 3166-1 numeric country code CISO31662 = "iso3166_2" // ISO 3166-2 subdivision code CISO4217 = "iso4217" // ISO 4217 currency code CISO4217Numeric = "iso4217_numeric" // ISO 4217 numeric currency code CPostcode = "postcode" // Postal code with country parameter CPostcodeISO3166Alpha2 = "postcode_iso3166_alpha2" // Alias for postcode CBCP47LanguageTag = "bcp47_language_tag" // BCP 47 language tag )
ISO code constraint name constants.
Variables ¶
This section is empty.
Functions ¶
func BuildCrossFieldConstraintsForField ¶
func BuildCrossFieldConstraintsForField(constraints map[string]string, structType reflect.Type, fieldIndex int) ([]CrossFieldConstraint, []SkipConstraint)
BuildCrossFieldConstraintsForField builds cross-field and skip constraint instances from parsed tags. Returns both types separately so validator can handle skip constraints before other validations.
func CheckTypeCompatibility ¶
CheckTypeCompatibility checks if two values can be compared.
func Compare ¶
Compare returns -1 if a < b, 0 if a == b, 1 if a > b This works for strings and numeric types Compare compares two values.
func CompareToString ¶
CompareToString converts any value to string for comparison.
func CompareValues ¶
CompareValues compares two values using the specified operator op values: "eq", "ne", "gt", "gte", "lt", "lte" Returns true if comparison succeeds, false otherwise CompareValues compares two values.
func Dereference ¶
Dereference removes pointer indirection from a type.
func IsContextValidator ¶
IsContextValidator checks if the given name is a registered context-aware validator.
func IsNumericType ¶
IsNumericType checks if a type is numeric.
func IsZeroValue ¶
IsZeroValue checks if a value is the zero value for its type. Returns true for nil, zero integers, empty strings, false booleans, empty slices/maps, etc. Returns false for non-zero values.
func SetCtxValidatorLookup ¶
SetCtxValidatorLookup sets the function used to check if a validator is context-aware. This should be called once by the registry package during initialization.
func SetCustomValidatorLookup ¶
func SetCustomValidatorLookup(fn func(name string) (CustomValidationFunc, bool))
SetCustomValidatorLookup sets the function used to look up custom validators. This should be called once by the registry package during initialization.
Types ¶
type CachedField ¶
type CachedField struct {
Name string // struct field name
JSONName string // JSON field name (from json tag or field name)
FieldIndex int // index in parent struct for O(1) access
// Pre-built constraints (from tags before dive)
Constraints []Constraint
CrossFieldConstraints []CrossFieldConstraint // eqfield, gtfield, etc.
ContextConstraints []ContextConstraint // context-aware validators (looked up at runtime)
// Skip constraints (evaluated BEFORE other constraints)
HasSkipConstraints bool // O(1) check - zero cost when false
SkipConstraints []SkipConstraint // skip_unless, etc.
// For collections with dive
HasDive bool
ElementConstraints []Constraint // constraints after dive
KeyConstraints []Constraint // for map keys (between keys/endkeys)
// Field type info
IsCollection bool // slice or map
IsMap bool // specifically a map
IsRequired bool // has required tag (for nested struct validation)
// IsOmitEmpty is true when the pedantigo tag contains "omitempty".
// When true, regular constraints and collection/nested recursion are
// skipped if the field is at its zero value. Cross-field constraints
// (required_with, required_if, eqfield, etc.) always run regardless.
IsOmitEmpty bool
// For nested structs (recursive cache)
NestedCache *FieldCache
}
CachedField holds pre-built validation data for a single struct field. Built once at validator creation time, used on every Validate() call.
type Constraint ¶
Constraint represents a validation constraint.
func BuildConstraints ¶
func BuildConstraints(constraints map[string]string, fieldType reflect.Type) []Constraint
BuildConstraints creates constraint instances from parsed tag map.
func BuildCustomConstraint ¶
func BuildCustomConstraint(name, param string) (Constraint, bool)
BuildCustomConstraint attempts to build a constraint for a custom validator. Returns (constraint, true) if a custom validator with the given name exists, Returns (nil, false) if no such validator is registered.
Parameters:
- name: The validator tag name (e.g., "us_phone").
- param: The parameter from the tag (e.g., "PRE_" from "has_prefix=PRE_").
type ConstraintError ¶
type ConstraintError struct {
Code string // Machine-readable error code (e.g., "INVALID_EMAIL")
Message string // Human-readable message
}
ConstraintError represents a validation error with a machine-readable code.
func NewConstraintError ¶
func NewConstraintError(code, message string) *ConstraintError
NewConstraintError creates a new ConstraintError.
func NewConstraintErrorf ¶
func NewConstraintErrorf(code, format string, args ...any) *ConstraintError
NewConstraintErrorf creates a new ConstraintError with formatted message.
func (*ConstraintError) Error ¶
func (e *ConstraintError) Error() string
Error implements the error interface.
type ContextConstraint ¶
type ContextConstraint struct {
Name string // validator name (looked up at runtime)
Param string // parameter value
}
ContextConstraint represents a context-aware validator name and its parameter.
func ExtractContextValidators ¶
func ExtractContextValidators(constraintsMap map[string]string) []ContextConstraint
ExtractContextValidators extracts context validator names and params from a constraints map. Returns a slice of ContextConstraint for validators that should be called with context.
type CrossFieldConstraint ¶
type CrossFieldConstraint interface {
ValidateCrossField(fieldValue any, structValue reflect.Value, fieldName string) error
}
CrossFieldConstraint represents a validation constraint that compares two fields.
type CustomValidationFunc ¶
CustomValidationFunc is the signature for custom validators with parameter support. Following go-playground/validator pattern, validators receive: - value: The field value being validated - param: The parameter from the tag (e.g., "PRE_" from "has_prefix=PRE_"), empty if no param
Returns nil if valid, error with message if invalid.
type FieldCache ¶
type FieldCache struct {
Fields []CachedField // indexed by struct field order
}
FieldCache holds cached validation data for all fields in a struct.
func NewFieldCache ¶
func NewFieldCache() *FieldCache
NewFieldCache creates a new instance of FieldCache.
type FieldPath ¶
type FieldPath struct {
Raw string // Original dotted path (e.g., "Inner.MinValue")
Parts []string // Split path components
TypeAtLevel []reflect.Type // Type at each level (for validation)
IndexAtLevel []int // Field index at each level (for traversal)
}
FieldPath represents a path to a possibly nested struct field. Example paths: "Name" (single field), "Inner.Value" (nested), "A.B.C.Field" (multi-level).
func ParseFieldPath ¶
ParseFieldPath parses a dotted field path (e.g., "Inner.MinValue") and validates it against the given struct type. Returns a FieldPath that can be used to resolve values at runtime.
Panics if:
- The path contains an invalid field name
- The path references an unexported field
- The path goes through a non-struct type (except pointers to structs)
Parameters:
- structType: The root struct type to validate against
- path: The dotted path string (e.g., "Inner.Value" or just "Value")
Returns: A validated FieldPath ready for use with ResolveValue.
func (*FieldPath) ResolveValue ¶
ResolveValue traverses the struct using the pre-computed indices and returns the field value. Handles pointer dereferencing at each level.
Parameters:
- structValue: A reflect.Value of the struct instance to traverse
Returns:
- The field value as any (interface{})
- Error if a nil pointer is encountered in the path
type SkipConstraint ¶
SkipConstraint is evaluated BEFORE other constraints. If ShouldSkip returns true, ALL validation on this field is bypassed.