arianna documentation
->>
macro
Creates a validator that chains the result of one validator into the next. Validators that are tests, such as is will have output the same as their input. Any failed validation or sucessful is-optional test will terminate the evaluation. The validation error will contain a key :chain which contains the chain of validation results that led to the error.
->> is a macro that has a number of interpretation rules that transform normal clojure syntax into validators.
string?becomes(v/is string?)incbecomes(v/as inc):keybecomes(v/as-key :key)["City" "Zip"]becomes(v/as-key ["City" "Zip"])
is is used if the name of the function ends with a question mark or if it's a comparison operator in clojure.core.
Chaining these together gives you the ability to do things like this:
(v/->> :should-be-even v/required v/number even?)
;;; Input should be a map with a key :should-be-even
;;; that can be read as a number and that number is even.
(v/->> :email v/optional v/email?)
;;; Input should be an email address or blank.
(v/->> keys (v/are keyword?))
;;; Input should be a map where all the keys are keywords
Next, if you follow a validator with a map, it will be merged into the validator.
(v/->> :email {:not-found "xjobcon@phx.cam.ac.uk"})
;;; Provides a default email address
;;; see also `as-key` for more details
Finally, strings are treated as maps with a :arianna/message key. These are used to provide human readable feedback by using stencil/mustache on the validation errors.
(v/->> :email
v/required "You must provide an email."
v/email? "The input {{value}} doesn't appear to be an email address.")
absent?
fn
Method that is used to determine if the value is absent in some way. Rules should be a set. The possible values of the set are:
:nil- return true if the value isnil:blank- return true if the value is an empty string:missing- return true if the value is:arianna/missing
The last, :missing checks for the special value :arianna/missing returned by as-key when it fails to find the key.
and
macro
Takes a sequence of validators and creates a validator that applies them all, terminating if one fails.
and has similar interpretation rules to ->>:
string?becomes(v/is string?)incbecomes(v/is inc):keybecomes(v/has :key)["City" "Zip"]becomes(v/as-key ["City" "Zip"])
Note the differences:
incis treated as a test (since a transform would make no sense)- if
:keycannot be found, it's treated as a validation failure.
and-all
macro
Takes a sequence of validators and creates a validator that applies them all, failing but not terminating if one fails. It will return all validation errors, while and will only return the first.
Uses the same interpretation rules as and.
are
macro
Returns a validator which will call (predicate ~@args x) on every element x in the input value. Can use clojure's % syntax like an anonymous function, so (v/are < % 10) will call (< input 10) on each element.
predicate must be a symbol.
as
macro
Returns a validator which will call (projection ~@args input). This will fail if the returned value is equal to :arianna/fail. By default, this means it will fail if the returned value is nil.
(v/as number)
;;; will fail if the input was not a number or a string
;;; representing a number
(assoc (v/as inc) :arianna/fail 3)
;;; Will fail if the input was equal to 2
Supports use of the % symbol, same as is.
as-key
fn
Returns a validator which will look into a map. Takes a keyword or a vector. as-key never fails and if the map doesn't have the key specified the result will be the special value :arianna/missing. You can test for this with v/required, v/optional or (v/is v/absent? #{:missing}). (The first two also test for nil and blank strings.)
Expands to one of
(as get-in % v :arianna/missing)
(as get % v :arianna/missing)
And sets :arianna/fail to :arianna/never.
The :not-found key is the value returned if the value is missing.
(v/as-key :x)
;;; Returns :arianna/missing if :x is not present
(assoc (v/as-key :x) :not-found 3)
;;; Returns 3 if :x is not present
(v/->> :x {:not-found 3})
;;; Exactly the same as the last example
Note that get will be used if as-key is given a vector with one element. (This makes reporting the results simpler later, since get-in [:x] is functionally identical to get :x.)
assert-valid
macro
Tests the value of expr with validators. If it passes, returns the value. If not, throws an exception with validation, line and file information attached.
Applies and-all to validators.
Note that this takes the expr first, making it suitable for use with ->, and can be used to validate that long chains of -> have usable intermediate values.
(-> x
inc
(* 4)
(v/assert-valid even?)
(/ 2))
comp
macro
Functionally identical to ->> except that it evaluates the validators right to left instead of left to right.
cond
macro
Creates a validator function that checks multiple conditions. Each clause is a pair of a predicate and a validator. Like cond, you can put :else as the last predicate. If you fail a clause, you get back that clause's validator as a failure. If no clauses match you get back the cond validator.
Uses the same rules as and on the predicate clauses, and the same rules as ->> on the validator clauses. That said, adding a message to the predicate is pretty pointless.
contains-in?
fn
The equivalent of contains? for vectors. The counterpart of get-in and get. Normally you won't want to call it directly, but v/has uses it.
every
macro
Returns a validator that applies the validators to each element of the input collection.
Uses the same interpretation rules as and.
field
fn
Identifies the field associated with a validation error. One of the following:
- The
:arianna/fieldof the validator, if any. - The projection of
v/as-key.
If the :arianna/field property isn't available, it will scan back through the validation chain for:arianna/field. If that fails, it will scan forward through the chain for a projection. Only then will it check the current validator for a projection.
has
fn
has behaves the same as as-key, expect that if the projection does not have a value, the validator fails.
Expands to one of
(is m/contains-in? % v)
(is contains? % v)
in-range?
fn
Method that checks if its value is numeric and is between min, inclusive, and max, exclusive.
is
macro
Returns a validator which will call (predicate ~@args input). Can use clojure's % syntax like an anonymous function, so (v/is < % 10) will call (< input 10).
predicate must be a symbol.
Example usages
(v/is string?)
(v/is < % 10)
is-not
macro
Returns a validator, like is, which will call (not (predicate ~@args input)). Supports % the same way as is.
predicate must be a symbol.
is-optional
macro
Returns a validator, like is, which will call (predicate ~@args input). The validation result is always true, but if the test is true the composite predicate will immediately short-circuit. Supports % the same way as is.
Example usage:
(v/is-optional v/absent? #{:nil :blank})
Which prevents evaluation of subsequent validators if the value is nil or blank.
Although callable anywhere, it only really makes sense to use it within v/->>.
predicate must be a symbol.
optional
var
Shorthand for (v/is-optional absent? #{:missing :nil :blank}).
Example usage:
(v/->> :email v/optional v/email?)
A rule that says that either :email is a valid email or it's not present.
or
macro
Takes a sequence of validators and creates a validator that applies them all, terminating if one succeeds. If it does not succeed, it will have a validation error that keys the or validator and an :errors key that contains a list of all of the constituent errors.
Uses the same interpretation rules as and.
render-message
fn
Generates a human readable message from a validation error specified by the failing validator.
The message rule is specified by the :arianna/message key in the validator. It can be either a function that takes a validation error or an implementation of the ValidationMessage protocol. Importantly, strings implement the protocol and work as mustache templates.
Stuck together with the interpretation rules of composites, the easiest way to set a message is by putting a string after the validation expression.
(v/and number? "Input should be a number."
even? "{{value}} should have been even."
(< % 10) "{{value}} should have been less than {{validator.y}}.")
Usually, you won't call this method directly, but just get the results from v/summarize.
required
var
Shorthand for (v/is-not absent? #{:missing :nil :blank}).
Example usage:
(v/->> :email v/required v/email?)
A rule that says that :email is both present and a valid email.
summarize
fn
Arity 1: Turns a validation result into a map of field, list of message. Returns nil on success.
Arity 2: Summarizes the result of validating the input.
Check the documentation for render-message and field for how this gets generated.
valid?
fn
Arity 1: Returns true if the validation result is a pass.
Arity 2: Returns true if value passes the validator.
validate
fn
Validates a value against a validator. Exceptions thrown during validation will be reported as validation failures with the exception in an :exception key of the validation error.
validate-debug
fn
Validates a value against a validator. Will not catch exceptions the way that validate does. Intended to assist with tracking down errors.
when
macro
Returns a validator that only checks the following validators when the first validates. Interpets all validators using the same rules as and.
within?
fn
Method that checks if its value is between min-incl and max-incl, both inclusive. Uses clojure.core/compare to compare values.