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?)
inc
becomes(v/as inc)
:key
becomes(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?)
inc
becomes(v/is inc)
:key
becomes(v/has :key)
["City" "Zip"]
becomes(v/as-key ["City" "Zip"])
Note the differences:
inc
is treated as a test (since a transform would make no sense)- if
:key
cannot 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/field
of 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.