Validators work in a pipeline (or applicative functor style), similar to the one used in
json-decode-pipeline. Values are checked and applied to a function one by one.
If everything goes well, the pipeline returns an Ok
result, otherwise it will return all the errors.
Ok ValidatedForm
|> validate (String.notEmpty "name is required") form.name
|> validate (String.isEmail "email is invalid") form.email
|> validateMany
[ String.hasLetter "password needs to contain letters"
, String.hasNumber "password needs to contain numbers"
]
form.password
|> noCheck form.message
|> checkOnly (Bool.isTrue "you need to approve") form.approved
In the example above, I used Strings as errors, but they can be any type you want.
Errors will be accumulated from top to bottom into a List. If you want to know exactly which field
had errors, take a look at the Validator.Named
module.
Result (List error) value
Validated
is simply an alias for a Result type, with errors as a list of your type, which can be
a string, or any custom error type.
You will not need to work with some exotic type, this is only here for convenience.
a -> Validated error b
Validator
is function, that checks a value, and returns a Validated
. Some validators can change the type of the value of type a
to type b
.
noCheck : a -> Validated x (a -> b) -> Validated x b
Apply a value to the pipeline without perfoming any checks.
validate : Validator x a b -> a -> Validated x (b -> c) -> Validated x c
Validate a value and apply it to the pipeline.
checkOnly : Validator x a b -> a -> Validated x c -> Validated x c
Validate a value without applying it to the pipeline.
validateMany : List (Validator x a a) -> a -> Validated x (a -> b) -> Validated x b
Validate a value using a list of validators. Checks are performed from left to right, and will stop on the first failure, returning only the first error.
Note: validateMany
is a convenience function onver validate << many
validateAll : List (Validator x a a) -> a -> Validated x (a -> b) -> Validated x b
Validate a value using a list of validators. Checks are performed from left to right, and will return all errors.
Note: validateAll
is a convenience function onver validate << all
map : (b -> c) -> Validator x a b -> a -> Validated x c
Map a function into the happy path.
andThen : Validator x b c -> Validator x a b -> a -> Validated x c
Chain together validators. Only the first error will be returned on failure.
Note: validateMany
and validateAll
provide a cleaner interface for most use cases.
mapErrors : (x -> y) -> Validator x a b -> a -> Validated y b
Transfrom error values.
many : List (Validator x a a) -> Validator x a a
Compose a list of validators for a single value. Checks are performed from left to right, and will stop on the first failure, returning only the first error.
all : List (Validator x a a) -> Validator x a a
Compose a list of validators for a single value. Checks are performed from left to right, and will return all errors.
customValidator : x -> (a -> Basics.Bool) -> a -> Validated x a
Create a custom validator, using a predicate function.