Validate ops
v0.1.4
Validate ops check a value and report an error when it fails. This page lists the 65 built-in validate ops. You write them in the validate(...) group of a derive string, as in "validate(string, max_len=80)". A failing op adds an error whose action is the op's name, with the exceptions listed under Failure actions.
Types
Each of these passes when the value is of the named kind. The error message reads The <field> field must be <op>.
| Op | Passes when the value is |
|---|---|
string | A binary. |
integer | An integer. |
float | A float. |
number | An integer or a float. |
boolean | true or false. |
atom | An atom. |
bitstring | A bitstring. |
list | A list. |
map | A map. A struct is a map. |
tuple | A tuple. |
struct | A struct. |
exception | An exception struct. |
function | A function. |
pid | A pid. |
port | A port. |
reference | A reference. |
nil_value | nil. |
not_nil_value | Anything but nil. |
A field that is nil is skipped before any op runs, apart from sanitize(default_when_nil=...), so nil_value and not_nil_value only see values that are not nil. A struct in the input stays a struct inside builder/1, so struct and exception see it. See How the builder works.
Other structures
| Op | Passes when the value is |
|---|---|
queue | An Erlang queue, as :queue.is_queue/1 decides. |
record | A non-empty tuple whose first element is an atom. |
record=tag | A tuple like the above whose first element is tag. record=user accepts {:user, "Alice", 30}. |
range | A Range. |
Emptiness and size
| Op | Passes when the value is |
|---|---|
not_empty | A string, list or map that is not empty. Any other kind of value fails. |
not_empty_string | A string that is not empty. |
not_flatten_empty | A list that still has an item after List.flatten/1. |
not_flatten_empty_item | A list that still has an item after flattening and has no [] as a direct item. |
max_len=N | At most N. A string is measured by String.length/1, a list by length/1, an integer or float by its value, and a range by its last element. |
min_len=N | At least N, measured the same way. A range is measured by its first element. |
Text and format
| Op | Passes when the value is |
|---|---|
email_r | A string that matches ^[A-Za-z0-9\._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$. It makes no network call. |
email | An address that EmailChecker.valid?/1 accepts. It can query DNS. Needs the email_checker package. |
url | A string with a scheme and a host, where the scheme is http or https, the port is 80 or 443 (the default of the scheme counts), and :inet.gethostbyname/1 resolves the host. It makes a lookup. |
tell | A phone number such as +4930123456, without spaces, checked as a tel: URL. Needs ex_url. |
tell=code | A phone number whose country calling code is code. tell=49 accepts +4930123456. Needs ex_url and ex_phone_number. |
geo_url | Latitude and longitude such as 48.198634,-16.371648. A value that already starts with geo: fails. Needs ex_url. |
location | The same as geo_url, with spaces removed first, so 48.198634, -16.371648 passes. Optional parts such as ;crs=wgs84 are accepted. Needs ex_url. |
uuid | A string of 8-4-4-4-12 hexadecimal digits, in any case. |
ipv4 | Four dot-separated integers from 0 to 255. |
ipv6 | An IPv6 address. It must contain a colon, so an IPv4 address fails. |
ip | An IPv4 or IPv6 address, as :inet.parse_address/1 decides. |
regex=pattern | A string that matches the pattern. |
username | A string of 5 to 34 characters that starts with a letter and holds only letters, digits and underscores. |
full_name | A string of lower-case letters a to z and spaces that does not start with a space. |
slug | A string that matches ^[a-z0-9]+(?:-[a-z0-9]+)*$. |
hostname | A string of at most 253 bytes with no underscore that :inet_parse.domain/1 accepts. |
port_number | An integer from 1 to 65535. |
hex_color | A string of # and 3 or 6 hexadecimal digits. |
semver | A string that Version.parse/1 accepts. 1.2.3-rc.1 passes and 1.2 fails. |
language_code | A string of 2 or 3 letters, followed by optional - parts of 2 to 8 letters or digits, such as en, en-US or zh-Hant. |
string_boolean | The string "true" or "false". |
string_float | A string that String.to_float/1 reads completely. "1.5" passes. "1" and "1.5abc" fail. |
string_integer | A string that String.to_integer/1 reads completely. "15" passes and "1.5" fails. |
some_string_float | A string that starts with a float, as Float.parse/1 reads it. "1.5abc" passes and "abc" fails. |
some_string_integer | A string that starts with an integer, as Integer.parse/1 reads it. |
Dates and times
| Op | Passes when the value is |
|---|---|
datetime | An ISO 8601 string with an offset that DateTime.from_iso8601/1 accepts. A DateTime struct fails. |
date | An ISO 8601 date string such as 2026-05-14. A Date struct fails. |
utc_datetime | A DateTime struct, or an ISO 8601 string with an offset. |
naive_datetime | A NaiveDateTime struct, or an ISO 8601 string. |
date_struct | A Date struct, or an ISO 8601 date string. |
time_struct | A Time struct, or an ISO 8601 time string such as 10:00:00. |
past_datetime | A DateTime, NaiveDateTime or Date struct, or an ISO 8601 string of one of those kinds, at or before the current time. |
future_datetime | The same kinds as past_datetime, at or after the current time. |
Choices and combinators
| Op | Passes when the value is |
|---|---|
enum=Type[a::b] | One of the listed values, of that type. See Derive string syntax for the types. |
equal=N | Equal to the integer N, compared with ===. |
equal=Type::value | Equal to a value of that type: equal=Float::1.5, equal=String::hello, equal=Atom::name, equal=Map::%{a: 1}, equal=Tuple::{:a, 1}. See Derive string syntax. |
custom=[Module, function] | A value for which Module.function(value) returns true. Any other result, or an exception, fails. |
either=[ops] | A value that passes at least one inner op. |
optional=[ops] | nil, or a value that passes all inner ops. |
each=[ops] | A list whose every item passes all inner ops. A failing item adds errors with an __index__ key. |
Failure actions
- An op that is given a kind of value it does not handle reports the action
typefor these ops:min_len,max_len,regex,date,location,not_flatten_emptyandnot_flatten_empty_item. Any other op reports its own name. - An op name that nothing defines reports the action
typewith the messageUnexpected type error in <field> field. email,tell,geo_urlandlocationneed an optional package. The package is looked up when the op runs, so the order of your dependencies does not matter. Without the package the op fails with its own name as the action, and the message names the package to add, such as{:ex_url, "~> 2.0"}.- When a validate op is the first in its group, the value it returns replaces the field's value.
locationandgeo_urlreturn thegeo:URL, andenumreturns the matching item of its list, so2againstFloat[1.5::2.0]becomes2.0.