package valid import "fmt" // MessageProvider maps a validation failure to a human-readable message. // // - field: the struct field name (e.g. "Email") // - tag: the failing validation rule (e.g. "required", "email", "min") // - param: the rule parameter if any (e.g. "18" for min=18), or "" if none type MessageProvider interface { Message(field, tag, param string) string } // DefaultMessages is the built-in English message provider. // Used automatically when no WithMessageProvider option is given. var DefaultMessages MessageProvider = defaultMessages{} // SpanishMessages is an opt-in Spanish message provider. var SpanishMessages MessageProvider = spanishMessages{} // OverrideProvider returns a MessageProvider that resolves messages from handlers // for specific tags, delegating to base for any tag not in handlers. // // Use it to supply messages for custom validators or to override individual tags: // // p := valid.OverrideProvider( // map[string]func(field, param string) string{ // "strongpassword": func(field, _ string) string { // return fmt.Sprintf("field '%s' must contain a letter, digit, and symbol", field) // }, // }, // valid.DefaultMessages, // ) func OverrideProvider(handlers map[string]func(field, param string) string, base MessageProvider) MessageProvider { return &overrideProvider{handlers: handlers, base: base} } type overrideProvider struct { handlers map[string]func(field, param string) string base MessageProvider } func (p *overrideProvider) Message(field, tag, param string) string { if fn, ok := p.handlers[tag]; ok { return fn(field, param) } return p.base.Message(field, tag, param) } // --------------------------------------------------------------- // English (default) // --------------------------------------------------------------- type defaultMessages struct{} func (defaultMessages) Message(field, tag, param string) string { switch tag { // Required case "required": return fmt.Sprintf("field '%s' is required", field) case "required_if", "required_unless": return fmt.Sprintf("field '%s' is required", field) case "required_with": return fmt.Sprintf("field '%s' is required when %s is present", field, param) case "required_with_all": return fmt.Sprintf("field '%s' is required when all of [%s] are present", field, param) case "required_without": return fmt.Sprintf("field '%s' is required when %s is absent", field, param) case "required_without_all": return fmt.Sprintf("field '%s' is required when all of [%s] are absent", field, param) // Excluded case "excluded_if", "excluded_unless": return fmt.Sprintf("field '%s' must not be set in this context", field) case "excluded_with": return fmt.Sprintf("field '%s' must not be set when %s is present", field, param) case "excluded_with_all": return fmt.Sprintf("field '%s' must not be set when all of [%s] are present", field, param) case "excluded_without": return fmt.Sprintf("field '%s' must not be set when %s is absent", field, param) case "excluded_without_all": return fmt.Sprintf("field '%s' must not be set when all of [%s] are absent", field, param) // Size / value case "len": return fmt.Sprintf("field '%s' must be exactly %s characters long", field, param) case "min": return fmt.Sprintf("field '%s' is too short (minimum %s)", field, param) case "max": return fmt.Sprintf("field '%s' is too long (maximum %s)", field, param) case "eq": return fmt.Sprintf("field '%s' must equal %s", field, param) case "eq_ignore_case": return fmt.Sprintf("field '%s' must equal %s (case-insensitive)", field, param) case "ne": return fmt.Sprintf("field '%s' must not equal %s", field, param) case "ne_ignore_case": return fmt.Sprintf("field '%s' must not equal %s (case-insensitive)", field, param) case "gt": return fmt.Sprintf("field '%s' must be greater than %s", field, param) case "gte": return fmt.Sprintf("field '%s' must be greater than or equal to %s", field, param) case "lt": return fmt.Sprintf("field '%s' must be less than %s", field, param) case "lte": return fmt.Sprintf("field '%s' must be less than or equal to %s", field, param) case "oneof": return fmt.Sprintf("field '%s' must be one of [%s]", field, param) case "noneof": return fmt.Sprintf("field '%s' must not be any of [%s]", field, param) case "unique": return fmt.Sprintf("field '%s' must contain unique values", field) case "isdefault": return fmt.Sprintf("field '%s' must be the default (zero) value", field) case "validateFn": return fmt.Sprintf("field '%s' failed custom validation", field) // Cross-field comparisons case "eqfield", "eqcsfield": return fmt.Sprintf("field '%s' must equal %s", field, param) case "nefield", "necsfield": return fmt.Sprintf("field '%s' must not equal %s", field, param) case "gtfield", "gtcsfield": return fmt.Sprintf("field '%s' must be greater than %s", field, param) case "gtefield", "gtecsfield": return fmt.Sprintf("field '%s' must be greater than or equal to %s", field, param) case "ltfield", "ltcsfield": return fmt.Sprintf("field '%s' must be less than %s", field, param) case "ltefield", "ltecsfield": return fmt.Sprintf("field '%s' must be less than or equal to %s", field, param) case "fieldcontains": return fmt.Sprintf("field '%s' must contain '%s'", field, param) case "fieldexcludes": return fmt.Sprintf("field '%s' must not contain '%s'", field, param) // String format case "alpha": return fmt.Sprintf("field '%s' must contain only letters", field) case "alphaspace": return fmt.Sprintf("field '%s' must contain only letters and spaces", field) case "alphanum": return fmt.Sprintf("field '%s' must contain only letters and digits", field) case "alphanumspace": return fmt.Sprintf("field '%s' must contain only letters, digits, and spaces", field) case "alphanumunicode": return fmt.Sprintf("field '%s' must contain only unicode letters and digits", field) case "alphaunicode": return fmt.Sprintf("field '%s' must contain only unicode letters", field) case "ascii": return fmt.Sprintf("field '%s' must contain only ASCII characters", field) case "printascii": return fmt.Sprintf("field '%s' must contain only printable ASCII characters", field) case "multibyte": return fmt.Sprintf("field '%s' must contain multi-byte characters", field) case "boolean": return fmt.Sprintf("field '%s' must be a boolean value", field) case "number": return fmt.Sprintf("field '%s' must be a number", field) case "numeric": return fmt.Sprintf("field '%s' must be a numeric string", field) case "lowercase": return fmt.Sprintf("field '%s' must be lowercase", field) case "uppercase": return fmt.Sprintf("field '%s' must be uppercase", field) // String content case "contains": return fmt.Sprintf("field '%s' must contain '%s'", field, param) case "containsany": return fmt.Sprintf("field '%s' must contain at least one of '%s'", field, param) case "containsrune": return fmt.Sprintf("field '%s' must contain the character '%s'", field, param) case "excludes": return fmt.Sprintf("field '%s' must not contain '%s'", field, param) case "excludesall": return fmt.Sprintf("field '%s' must not contain any of '%s'", field, param) case "excludesrune": return fmt.Sprintf("field '%s' must not contain the character '%s'", field, param) case "startswith": return fmt.Sprintf("field '%s' must start with '%s'", field, param) case "startsnotwith": return fmt.Sprintf("field '%s' must not start with '%s'", field, param) case "endswith": return fmt.Sprintf("field '%s' must end with '%s'", field, param) case "endsnotwith": return fmt.Sprintf("field '%s' must not end with '%s'", field, param) // Network case "ip", "ip_addr": return fmt.Sprintf("field '%s' must be a valid IP address", field) case "ipv4", "ip4_addr": return fmt.Sprintf("field '%s' must be a valid IPv4 address", field) case "ipv6", "ip6_addr": return fmt.Sprintf("field '%s' must be a valid IPv6 address", field) case "cidr": return fmt.Sprintf("field '%s' must be a valid CIDR notation address", field) case "cidrv4": return fmt.Sprintf("field '%s' must be a valid IPv4 CIDR notation address", field) case "cidrv6": return fmt.Sprintf("field '%s' must be a valid IPv6 CIDR notation address", field) case "mac": return fmt.Sprintf("field '%s' must be a valid MAC address", field) case "hostname": return fmt.Sprintf("field '%s' must be a valid RFC 952 hostname", field) case "hostname_rfc1123": return fmt.Sprintf("field '%s' must be a valid RFC 1123 hostname", field) case "hostname_port": return fmt.Sprintf("field '%s' must be a valid host:port pair", field) case "port": return fmt.Sprintf("field '%s' must be a valid port number", field) case "fqdn": return fmt.Sprintf("field '%s' must be a fully qualified domain name", field) case "tcp4_addr": return fmt.Sprintf("field '%s' must be a valid TCPv4 address", field) case "tcp6_addr": return fmt.Sprintf("field '%s' must be a valid TCPv6 address", field) case "tcp_addr": return fmt.Sprintf("field '%s' must be a valid TCP address", field) case "udp4_addr": return fmt.Sprintf("field '%s' must be a valid UDPv4 address", field) case "udp6_addr": return fmt.Sprintf("field '%s' must be a valid UDPv6 address", field) case "udp_addr": return fmt.Sprintf("field '%s' must be a valid UDP address", field) case "unix_addr": return fmt.Sprintf("field '%s' must be a valid Unix domain socket address", field) case "uds_exists": return fmt.Sprintf("field '%s' must be an existing Unix domain socket", field) case "uri": return fmt.Sprintf("field '%s' must be a valid URI", field) case "url": return fmt.Sprintf("field '%s' must be a valid URL", field) case "http_url": return fmt.Sprintf("field '%s' must be a valid HTTP or HTTPS URL", field) case "https_url": return fmt.Sprintf("field '%s' must be a valid HTTPS URL", field) case "url_encoded": return fmt.Sprintf("field '%s' must be a valid URL-encoded string", field) case "origin": return fmt.Sprintf("field '%s' must be a valid web origin", field) case "urn_rfc2141": return fmt.Sprintf("field '%s' must be a valid URN (RFC 2141)", field) case "datauri": return fmt.Sprintf("field '%s' must be a valid data URI", field) // Format / identity case "email": return fmt.Sprintf("field '%s' must be a valid email address", field) case "uuid": return fmt.Sprintf("field '%s' must be a valid UUID", field) case "uuid3": return fmt.Sprintf("field '%s' must be a valid version 3 UUID", field) case "uuid3_rfc4122": return fmt.Sprintf("field '%s' must be a valid RFC 4122 version 3 UUID", field) case "uuid4": return fmt.Sprintf("field '%s' must be a valid version 4 UUID", field) case "uuid4_rfc4122": return fmt.Sprintf("field '%s' must be a valid RFC 4122 version 4 UUID", field) case "uuid5": return fmt.Sprintf("field '%s' must be a valid version 5 UUID", field) case "uuid5_rfc4122": return fmt.Sprintf("field '%s' must be a valid RFC 4122 version 5 UUID", field) case "uuid_rfc4122": return fmt.Sprintf("field '%s' must be a valid RFC 4122 UUID", field) case "ulid": return fmt.Sprintf("field '%s' must be a valid ULID", field) case "e164": return fmt.Sprintf("field '%s' must be a valid E.164 phone number", field) case "isbn": return fmt.Sprintf("field '%s' must be a valid ISBN", field) case "isbn10": return fmt.Sprintf("field '%s' must be a valid ISBN-10", field) case "isbn13": return fmt.Sprintf("field '%s' must be a valid ISBN-13", field) case "issn": return fmt.Sprintf("field '%s' must be a valid ISSN", field) case "credit_card": return fmt.Sprintf("field '%s' must be a valid credit card number", field) case "ssn": return fmt.Sprintf("field '%s' must be a valid Social Security Number", field) case "ein": return fmt.Sprintf("field '%s' must be a valid EIN", field) case "latitude": return fmt.Sprintf("field '%s' must be a valid latitude", field) case "longitude": return fmt.Sprintf("field '%s' must be a valid longitude", field) case "timezone": return fmt.Sprintf("field '%s' must be a valid IANA timezone", field) case "datetime": return fmt.Sprintf("field '%s' must match the datetime format '%s'", field, param) case "json": return fmt.Sprintf("field '%s' must be valid JSON", field) case "jwt": return fmt.Sprintf("field '%s' must be a valid JWT", field) case "semver": return fmt.Sprintf("field '%s' must be a valid semantic version", field) case "cve": return fmt.Sprintf("field '%s' must be a valid CVE identifier", field) case "cron": return fmt.Sprintf("field '%s' must be a valid cron expression", field) case "spicedb": return fmt.Sprintf("field '%s' must be a valid SpiceDB identifier", field) // Encoding / hash case "base64": return fmt.Sprintf("field '%s' must be a valid base64-encoded string", field) case "base64url": return fmt.Sprintf("field '%s' must be a valid base64url-encoded string", field) case "base64rawurl": return fmt.Sprintf("field '%s' must be a valid base64rawurl-encoded string", field) case "hexadecimal": return fmt.Sprintf("field '%s' must be a valid hexadecimal string", field) case "md4": return fmt.Sprintf("field '%s' must be a valid MD4 hash", field) case "md5": return fmt.Sprintf("field '%s' must be a valid MD5 hash", field) case "sha256": return fmt.Sprintf("field '%s' must be a valid SHA-256 hash", field) case "sha384": return fmt.Sprintf("field '%s' must be a valid SHA-384 hash", field) case "sha512": return fmt.Sprintf("field '%s' must be a valid SHA-512 hash", field) case "ripemd128": return fmt.Sprintf("field '%s' must be a valid RIPEMD-128 hash", field) case "ripemd160": return fmt.Sprintf("field '%s' must be a valid RIPEMD-160 hash", field) case "tiger128": return fmt.Sprintf("field '%s' must be a valid TIGER-128 hash", field) case "tiger160": return fmt.Sprintf("field '%s' must be a valid TIGER-160 hash", field) case "tiger192": return fmt.Sprintf("field '%s' must be a valid TIGER-192 hash", field) case "luhn_checksum": return fmt.Sprintf("field '%s' must pass the Luhn checksum", field) // Color case "hexcolor": return fmt.Sprintf("field '%s' must be a valid hexadecimal color code", field) case "rgb": return fmt.Sprintf("field '%s' must be a valid RGB color", field) case "rgba": return fmt.Sprintf("field '%s' must be a valid RGBA color", field) case "hsl": return fmt.Sprintf("field '%s' must be a valid HSL color", field) case "hsla": return fmt.Sprintf("field '%s' must be a valid HSLA color", field) case "cmyk": return fmt.Sprintf("field '%s' must be a valid CMYK color", field) case "iscolor": return fmt.Sprintf("field '%s' must be a valid color (hex, RGB, RGBA, HSL, HSLA, or CMYK)", field) // HTML case "html": return fmt.Sprintf("field '%s' must contain valid HTML", field) case "html_encoded": return fmt.Sprintf("field '%s' must be HTML-encoded", field) // International standards case "iso3166_1_alpha2": return fmt.Sprintf("field '%s' must be a valid ISO 3166-1 alpha-2 country code", field) case "iso3166_1_alpha3": return fmt.Sprintf("field '%s' must be a valid ISO 3166-1 alpha-3 country code", field) case "iso3166_1_alpha_numeric": return fmt.Sprintf("field '%s' must be a valid ISO 3166-1 numeric country code", field) case "iso3166_2": return fmt.Sprintf("field '%s' must be a valid ISO 3166-2 subdivision code", field) case "iso4217": return fmt.Sprintf("field '%s' must be a valid ISO 4217 currency code", field) case "country_code": return fmt.Sprintf("field '%s' must be a valid ISO 3166 country code", field) case "bcp47_language_tag": return fmt.Sprintf("field '%s' must be a valid BCP 47 language tag", field) case "bcp47_strict_language_tag": return fmt.Sprintf("field '%s' must be a valid BCP 47 language tag (RFC 5646)", field) case "postcode_iso3166_alpha2", "postcode_iso3166_alpha2_field": return fmt.Sprintf("field '%s' must be a valid postcode", field) // Crypto / blockchain case "btc_addr": return fmt.Sprintf("field '%s' must be a valid Bitcoin address", field) case "btc_addr_bech32": return fmt.Sprintf("field '%s' must be a valid Bitcoin Bech32 address", field) case "eth_addr": return fmt.Sprintf("field '%s' must be a valid Ethereum address", field) // Database case "mongodb": return fmt.Sprintf("field '%s' must be a valid MongoDB ObjectID", field) case "mongodb_connection_string": return fmt.Sprintf("field '%s' must be a valid MongoDB connection string", field) // Business identity case "bic_iso_9362_2014": return fmt.Sprintf("field '%s' must be a valid BIC (ISO 9362:2014)", field) case "bic": return fmt.Sprintf("field '%s' must be a valid BIC (ISO 9362:2022)", field) // File system case "dir": return fmt.Sprintf("field '%s' must be an existing directory", field) case "dirpath": return fmt.Sprintf("field '%s' must be a valid directory path", field) case "file": return fmt.Sprintf("field '%s' must be an existing file", field) case "filepath": return fmt.Sprintf("field '%s' must be a valid file path", field) case "image": return fmt.Sprintf("field '%s' must be a valid image file", field) case "mimetype": return fmt.Sprintf("field '%s' must have MIME type '%s'", field, param) default: return fmt.Sprintf("field '%s' failed validation rule '%s'", field, tag) } } // --------------------------------------------------------------- // Spanish (opt-in) // --------------------------------------------------------------- type spanishMessages struct{} func (spanishMessages) Message(field, tag, param string) string { switch tag { // Required case "required": return fmt.Sprintf("El campo '%s' es obligatorio", field) case "required_if", "required_unless": return fmt.Sprintf("El campo '%s' es obligatorio", field) case "required_with": return fmt.Sprintf("El campo '%s' es obligatorio cuando %s está presente", field, param) case "required_with_all": return fmt.Sprintf("El campo '%s' es obligatorio cuando todos los [%s] están presentes", field, param) case "required_without": return fmt.Sprintf("El campo '%s' es obligatorio cuando %s está ausente", field, param) case "required_without_all": return fmt.Sprintf("El campo '%s' es obligatorio cuando todos los [%s] están ausentes", field, param) // Excluded case "excluded_if", "excluded_unless": return fmt.Sprintf("El campo '%s' no debe estar definido en este contexto", field) case "excluded_with": return fmt.Sprintf("El campo '%s' no debe estar definido cuando %s está presente", field, param) case "excluded_with_all": return fmt.Sprintf("El campo '%s' no debe estar definido cuando todos los [%s] están presentes", field, param) case "excluded_without": return fmt.Sprintf("El campo '%s' no debe estar definido cuando %s está ausente", field, param) case "excluded_without_all": return fmt.Sprintf("El campo '%s' no debe estar definido cuando todos los [%s] están ausentes", field, param) // Size / value case "len": return fmt.Sprintf("El campo '%s' debe tener exactamente %s caracteres", field, param) case "min": return fmt.Sprintf("El campo '%s' es demasiado corto (mínimo %s)", field, param) case "max": return fmt.Sprintf("El campo '%s' es demasiado largo (máximo %s)", field, param) case "eq": return fmt.Sprintf("El campo '%s' debe ser igual a %s", field, param) case "eq_ignore_case": return fmt.Sprintf("El campo '%s' debe ser igual a %s (sin distinción de mayúsculas)", field, param) case "ne": return fmt.Sprintf("El campo '%s' no debe ser igual a %s", field, param) case "ne_ignore_case": return fmt.Sprintf("El campo '%s' no debe ser igual a %s (sin distinción de mayúsculas)", field, param) case "gt": return fmt.Sprintf("El campo '%s' debe ser mayor que %s", field, param) case "gte": return fmt.Sprintf("El campo '%s' debe ser mayor o igual a %s", field, param) case "lt": return fmt.Sprintf("El campo '%s' debe ser menor que %s", field, param) case "lte": return fmt.Sprintf("El campo '%s' debe ser menor o igual a %s", field, param) case "oneof": return fmt.Sprintf("El campo '%s' debe ser uno de [%s]", field, param) case "noneof": return fmt.Sprintf("El campo '%s' no debe ser ninguno de [%s]", field, param) case "unique": return fmt.Sprintf("El campo '%s' debe contener valores únicos", field) case "isdefault": return fmt.Sprintf("El campo '%s' debe ser el valor predeterminado", field) case "validateFn": return fmt.Sprintf("El campo '%s' no superó la validación personalizada", field) // Cross-field comparisons case "eqfield", "eqcsfield": return fmt.Sprintf("El campo '%s' debe ser igual a %s", field, param) case "nefield", "necsfield": return fmt.Sprintf("El campo '%s' no debe ser igual a %s", field, param) case "gtfield", "gtcsfield": return fmt.Sprintf("El campo '%s' debe ser mayor que %s", field, param) case "gtefield", "gtecsfield": return fmt.Sprintf("El campo '%s' debe ser mayor o igual a %s", field, param) case "ltfield", "ltcsfield": return fmt.Sprintf("El campo '%s' debe ser menor que %s", field, param) case "ltefield", "ltecsfield": return fmt.Sprintf("El campo '%s' debe ser menor o igual a %s", field, param) case "fieldcontains": return fmt.Sprintf("El campo '%s' debe contener '%s'", field, param) case "fieldexcludes": return fmt.Sprintf("El campo '%s' no debe contener '%s'", field, param) // String format case "alpha": return fmt.Sprintf("El campo '%s' solo debe contener letras", field) case "alphaspace": return fmt.Sprintf("El campo '%s' solo debe contener letras y espacios", field) case "alphanum": return fmt.Sprintf("El campo '%s' solo debe contener letras y dígitos", field) case "alphanumspace": return fmt.Sprintf("El campo '%s' solo debe contener letras, dígitos y espacios", field) case "alphanumunicode": return fmt.Sprintf("El campo '%s' solo debe contener letras y dígitos Unicode", field) case "alphaunicode": return fmt.Sprintf("El campo '%s' solo debe contener letras Unicode", field) case "ascii": return fmt.Sprintf("El campo '%s' solo debe contener caracteres ASCII", field) case "printascii": return fmt.Sprintf("El campo '%s' solo debe contener caracteres ASCII imprimibles", field) case "multibyte": return fmt.Sprintf("El campo '%s' debe contener caracteres multibyte", field) case "boolean": return fmt.Sprintf("El campo '%s' debe ser un valor booleano", field) case "number": return fmt.Sprintf("El campo '%s' debe ser un número", field) case "numeric": return fmt.Sprintf("El campo '%s' debe ser una cadena numérica", field) case "lowercase": return fmt.Sprintf("El campo '%s' debe estar en minúsculas", field) case "uppercase": return fmt.Sprintf("El campo '%s' debe estar en mayúsculas", field) // String content case "contains": return fmt.Sprintf("El campo '%s' debe contener '%s'", field, param) case "containsany": return fmt.Sprintf("El campo '%s' debe contener al menos uno de '%s'", field, param) case "containsrune": return fmt.Sprintf("El campo '%s' debe contener el carácter '%s'", field, param) case "excludes": return fmt.Sprintf("El campo '%s' no debe contener '%s'", field, param) case "excludesall": return fmt.Sprintf("El campo '%s' no debe contener ninguno de '%s'", field, param) case "excludesrune": return fmt.Sprintf("El campo '%s' no debe contener el carácter '%s'", field, param) case "startswith": return fmt.Sprintf("El campo '%s' debe comenzar con '%s'", field, param) case "startsnotwith": return fmt.Sprintf("El campo '%s' no debe comenzar con '%s'", field, param) case "endswith": return fmt.Sprintf("El campo '%s' debe terminar con '%s'", field, param) case "endsnotwith": return fmt.Sprintf("El campo '%s' no debe terminar con '%s'", field, param) // Network case "ip", "ip_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección IP válida", field) case "ipv4", "ip4_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección IPv4 válida", field) case "ipv6", "ip6_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección IPv6 válida", field) case "cidr": return fmt.Sprintf("El campo '%s' debe ser una dirección CIDR válida", field) case "cidrv4": return fmt.Sprintf("El campo '%s' debe ser una dirección CIDR IPv4 válida", field) case "cidrv6": return fmt.Sprintf("El campo '%s' debe ser una dirección CIDR IPv6 válida", field) case "mac": return fmt.Sprintf("El campo '%s' debe ser una dirección MAC válida", field) case "hostname": return fmt.Sprintf("El campo '%s' debe ser un nombre de host válido (RFC 952)", field) case "hostname_rfc1123": return fmt.Sprintf("El campo '%s' debe ser un nombre de host válido (RFC 1123)", field) case "hostname_port": return fmt.Sprintf("El campo '%s' debe ser un par host:puerto válido", field) case "port": return fmt.Sprintf("El campo '%s' debe ser un número de puerto válido", field) case "fqdn": return fmt.Sprintf("El campo '%s' debe ser un nombre de dominio completamente calificado", field) case "tcp4_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección TCPv4 válida", field) case "tcp6_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección TCPv6 válida", field) case "tcp_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección TCP válida", field) case "udp4_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección UDPv4 válida", field) case "udp6_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección UDPv6 válida", field) case "udp_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección UDP válida", field) case "unix_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección de socket Unix válida", field) case "uds_exists": return fmt.Sprintf("El campo '%s' debe ser un socket de dominio Unix existente", field) case "uri": return fmt.Sprintf("El campo '%s' debe ser un URI válido", field) case "url": return fmt.Sprintf("El campo '%s' debe ser una URL válida", field) case "http_url": return fmt.Sprintf("El campo '%s' debe ser una URL HTTP o HTTPS válida", field) case "https_url": return fmt.Sprintf("El campo '%s' debe ser una URL HTTPS válida", field) case "url_encoded": return fmt.Sprintf("El campo '%s' debe ser una cadena codificada en URL válida", field) case "origin": return fmt.Sprintf("El campo '%s' debe ser un origen web válido", field) case "urn_rfc2141": return fmt.Sprintf("El campo '%s' debe ser un URN válido (RFC 2141)", field) case "datauri": return fmt.Sprintf("El campo '%s' debe ser un URI de datos válido", field) // Format / identity case "email": return fmt.Sprintf("El campo '%s' debe ser un correo electrónico válido", field) case "uuid": return fmt.Sprintf("El campo '%s' debe ser un UUID válido", field) case "uuid3": return fmt.Sprintf("El campo '%s' debe ser un UUID versión 3 válido", field) case "uuid3_rfc4122": return fmt.Sprintf("El campo '%s' debe ser un UUID RFC 4122 versión 3 válido", field) case "uuid4": return fmt.Sprintf("El campo '%s' debe ser un UUID versión 4 válido", field) case "uuid4_rfc4122": return fmt.Sprintf("El campo '%s' debe ser un UUID RFC 4122 versión 4 válido", field) case "uuid5": return fmt.Sprintf("El campo '%s' debe ser un UUID versión 5 válido", field) case "uuid5_rfc4122": return fmt.Sprintf("El campo '%s' debe ser un UUID RFC 4122 versión 5 válido", field) case "uuid_rfc4122": return fmt.Sprintf("El campo '%s' debe ser un UUID RFC 4122 válido", field) case "ulid": return fmt.Sprintf("El campo '%s' debe ser un ULID válido", field) case "e164": return fmt.Sprintf("El campo '%s' debe ser un número de teléfono E.164 válido", field) case "isbn": return fmt.Sprintf("El campo '%s' debe ser un ISBN válido", field) case "isbn10": return fmt.Sprintf("El campo '%s' debe ser un ISBN-10 válido", field) case "isbn13": return fmt.Sprintf("El campo '%s' debe ser un ISBN-13 válido", field) case "issn": return fmt.Sprintf("El campo '%s' debe ser un ISSN válido", field) case "credit_card": return fmt.Sprintf("El campo '%s' debe ser un número de tarjeta de crédito válido", field) case "ssn": return fmt.Sprintf("El campo '%s' debe ser un número de seguro social válido", field) case "ein": return fmt.Sprintf("El campo '%s' debe ser un EIN válido", field) case "latitude": return fmt.Sprintf("El campo '%s' debe ser una latitud válida", field) case "longitude": return fmt.Sprintf("El campo '%s' debe ser una longitud válida", field) case "timezone": return fmt.Sprintf("El campo '%s' debe ser una zona horaria IANA válida", field) case "datetime": return fmt.Sprintf("El campo '%s' debe coincidir con el formato de fecha '%s'", field, param) case "json": return fmt.Sprintf("El campo '%s' debe ser JSON válido", field) case "jwt": return fmt.Sprintf("El campo '%s' debe ser un JWT válido", field) case "semver": return fmt.Sprintf("El campo '%s' debe ser una versión semántica válida", field) case "cve": return fmt.Sprintf("El campo '%s' debe ser un identificador CVE válido", field) case "cron": return fmt.Sprintf("El campo '%s' debe ser una expresión cron válida", field) case "spicedb": return fmt.Sprintf("El campo '%s' debe ser un identificador SpiceDB válido", field) // Encoding / hash case "base64": return fmt.Sprintf("El campo '%s' debe ser una cadena base64 válida", field) case "base64url": return fmt.Sprintf("El campo '%s' debe ser una cadena base64url válida", field) case "base64rawurl": return fmt.Sprintf("El campo '%s' debe ser una cadena base64rawurl válida", field) case "hexadecimal": return fmt.Sprintf("El campo '%s' debe ser una cadena hexadecimal válida", field) case "md4": return fmt.Sprintf("El campo '%s' debe ser un hash MD4 válido", field) case "md5": return fmt.Sprintf("El campo '%s' debe ser un hash MD5 válido", field) case "sha256": return fmt.Sprintf("El campo '%s' debe ser un hash SHA-256 válido", field) case "sha384": return fmt.Sprintf("El campo '%s' debe ser un hash SHA-384 válido", field) case "sha512": return fmt.Sprintf("El campo '%s' debe ser un hash SHA-512 válido", field) case "ripemd128": return fmt.Sprintf("El campo '%s' debe ser un hash RIPEMD-128 válido", field) case "ripemd160": return fmt.Sprintf("El campo '%s' debe ser un hash RIPEMD-160 válido", field) case "tiger128": return fmt.Sprintf("El campo '%s' debe ser un hash TIGER-128 válido", field) case "tiger160": return fmt.Sprintf("El campo '%s' debe ser un hash TIGER-160 válido", field) case "tiger192": return fmt.Sprintf("El campo '%s' debe ser un hash TIGER-192 válido", field) case "luhn_checksum": return fmt.Sprintf("El campo '%s' debe pasar la suma de verificación Luhn", field) // Color case "hexcolor": return fmt.Sprintf("El campo '%s' debe ser un código de color hexadecimal válido", field) case "rgb": return fmt.Sprintf("El campo '%s' debe ser un color RGB válido", field) case "rgba": return fmt.Sprintf("El campo '%s' debe ser un color RGBA válido", field) case "hsl": return fmt.Sprintf("El campo '%s' debe ser un color HSL válido", field) case "hsla": return fmt.Sprintf("El campo '%s' debe ser un color HSLA válido", field) case "cmyk": return fmt.Sprintf("El campo '%s' debe ser un color CMYK válido", field) case "iscolor": return fmt.Sprintf("El campo '%s' debe ser un color válido (hex, RGB, RGBA, HSL, HSLA o CMYK)", field) // HTML case "html": return fmt.Sprintf("El campo '%s' debe contener HTML válido", field) case "html_encoded": return fmt.Sprintf("El campo '%s' debe estar codificado en HTML", field) // International standards case "iso3166_1_alpha2": return fmt.Sprintf("El campo '%s' debe ser un código de país ISO 3166-1 alpha-2 válido", field) case "iso3166_1_alpha3": return fmt.Sprintf("El campo '%s' debe ser un código de país ISO 3166-1 alpha-3 válido", field) case "iso3166_1_alpha_numeric": return fmt.Sprintf("El campo '%s' debe ser un código de país ISO 3166-1 numérico válido", field) case "iso3166_2": return fmt.Sprintf("El campo '%s' debe ser un código de subdivisión ISO 3166-2 válido", field) case "iso4217": return fmt.Sprintf("El campo '%s' debe ser un código de moneda ISO 4217 válido", field) case "country_code": return fmt.Sprintf("El campo '%s' debe ser un código de país ISO 3166 válido", field) case "bcp47_language_tag": return fmt.Sprintf("El campo '%s' debe ser una etiqueta de idioma BCP 47 válida", field) case "bcp47_strict_language_tag": return fmt.Sprintf("El campo '%s' debe ser una etiqueta de idioma BCP 47 válida (RFC 5646)", field) case "postcode_iso3166_alpha2", "postcode_iso3166_alpha2_field": return fmt.Sprintf("El campo '%s' debe ser un código postal válido", field) // Crypto / blockchain case "btc_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección Bitcoin válida", field) case "btc_addr_bech32": return fmt.Sprintf("El campo '%s' debe ser una dirección Bitcoin Bech32 válida", field) case "eth_addr": return fmt.Sprintf("El campo '%s' debe ser una dirección Ethereum válida", field) // Database case "mongodb": return fmt.Sprintf("El campo '%s' debe ser un ObjectID de MongoDB válido", field) case "mongodb_connection_string": return fmt.Sprintf("El campo '%s' debe ser una cadena de conexión de MongoDB válida", field) // Business identity case "bic_iso_9362_2014": return fmt.Sprintf("El campo '%s' debe ser un BIC válido (ISO 9362:2014)", field) case "bic": return fmt.Sprintf("El campo '%s' debe ser un BIC válido (ISO 9362:2022)", field) // File system case "dir": return fmt.Sprintf("El campo '%s' debe ser un directorio existente", field) case "dirpath": return fmt.Sprintf("El campo '%s' debe ser una ruta de directorio válida", field) case "file": return fmt.Sprintf("El campo '%s' debe ser un archivo existente", field) case "filepath": return fmt.Sprintf("El campo '%s' debe ser una ruta de archivo válida", field) case "image": return fmt.Sprintf("El campo '%s' debe ser un archivo de imagen válido", field) case "mimetype": return fmt.Sprintf("El campo '%s' debe tener el tipo MIME '%s'", field, param) default: return fmt.Sprintf("Error en el campo '%s': regla '%s' no cumplida", field, tag) } }