validated
This module provides the Validated type and associated functions
to accumulate errors in an ergonomic way.
Example
fn validate_form(email: String, age: Int) -> Validated(Form, String) {
use email <- v.do(validate_email(email))
use age <- v.do(validate_age(age))
Valid(Form(email:, age:))
}
validated_form("lucy@example.com", 20)
// -> Valid(Form("lucy@example.com", 20))
validated_form("asdf", 5)
// -> Invalid(Form("", 0), ["not a valid email", "must be 18 or older"])
This API is possible because a Validated requires a “default” value
in case of failure. That way, the default value is passed through to
continue the validation.
Since a value within a validation block may or may not be the default value, it is important to never perform side-effects inside the validation.
Types
Validated represents the result of something that may succeed or not.
It is similar to Result, except that it will accumulate multiple errors
instead of stopping at the first error.
Valid means it was successful, Invalid means it was not successful.
pub type Validated(a, e) {
Valid(a)
Invalid(a, List(e))
}
Constructors
-
Valid(a) -
Invalid(a, List(e))Invalid requires a default value to enable validation in
useexpressions
Functions
pub fn all(
validateds: List(Validated(a, b)),
) -> Validated(List(a), b)
Combines a list of Validateds into a single Validated.
If all elements in the list are Valid then the function returns a Valid
holding the list of values.
Otherwise an Invalid is returned that combines all the errors.
Valid([]) is returned if the list is empty.
pub fn bit_array(
value: Result(BitArray, a),
) -> Validated(BitArray, a)
Creates a Validated from a Result.
It uses an empty BitArray as the default value in case of failure.
pub fn bool(value: Result(Bool, a)) -> Validated(Bool, a)
Creates a Validated from a Result.
It uses False as the default value in case of failure.
pub fn dict(
value: Result(Dict(a, b), c),
) -> Validated(Dict(a, b), c)
Creates a Validated from a Result.
It uses an empty Dict as the default value in case of failure.
pub fn do(
validated: Validated(a, b),
next: fn(a) -> Validated(c, b),
) -> Validated(c, b)
“Updates” a Valid value by passing its value to a function that yields a Validated,
and returning the yielded Validated. (This may “replace” the Valid with an Invalid.)
If the input is an Invalid rather than an Valid, the function is still called using the default
value from the Invalid. If the function succeeds, the Invalid’s default is replaced with the Valid value.
If the function fails, the first Invalid errors are combined with the returned Invalid errors.
This function is useful in use expressions to ergonomically validate fields of a record
Examples
use a <- do(Valid(1))
use b <- do(Valid(2))
Valid(#(a, b))
// -> Valid(#(1, 2))
use a <- do(Invalid(0, [Nil]))
use b <- do(Valid(2))
use c <- do(Invalid(0, [Nil]))
Valid(#(a, b, c))
// -> Invalid(#(0, 2, 0), [Nil, Nil])
pub fn flatten(
validated: Validated(Validated(a, b), b),
) -> Validated(a, b)
Merges a nested Validated into a single layer.
pub fn float(value: Result(Float, a)) -> Validated(Float, a)
Creates a Validated from a Result.
It uses 0.0 as the default value in case of failure.
pub fn guard(
validated: Validated(a, b),
default: c,
continue: fn(a) -> Validated(c, b),
) -> Validated(c, b)
Like do, but does not continue accumulating further errors if the
Validated is Invalid.
pub fn int(value: Result(Int, a)) -> Validated(Int, a)
Creates a Validated from a Result.
It uses 0 as the default value in case of failure.
pub fn is_invalid(validated: Validated(a, b)) -> Bool
Checks whether the Validated is Invalid
pub fn is_valid(validated: Validated(a, b)) -> Bool
Checks whether the Validated is Valid
pub fn lazy_guard(
validated: Validated(a, b),
default: fn() -> c,
continue: fn(a) -> Validated(c, b),
) -> Validated(c, b)
Like guard but accepts a callback for the default value in case the
Validated is Invalid.
pub fn list(value: Result(List(a), b)) -> Validated(List(a), b)
Creates a Validated from a Result.
It uses an empty list as the default value in case of failure.
pub fn map(
validated: Validated(a, b),
f: fn(a) -> c,
) -> Validated(c, b)
Updates a value held within the Valid of a Validated by calling a given function on it.
If the Validated is an Invalid rather than Valid, the function is called on the default value.
pub fn map_error(
validated: Validated(a, b),
f: fn(List(b)) -> List(c),
) -> Validated(a, c)
Updates a value held within the Invalid of a Validated by calling a given function on it.
If the result is Valid rather than Invalid the function is not called and the result stays the same.
pub fn optional(
value: Result(Option(a), b),
) -> Validated(Option(a), b)
Creates a Validated from a Result.
It uses None as the default value in case of failure.
pub fn replace(
validated: Validated(a, b),
value: c,
) -> Validated(c, b)
Replace the value within a Validated
pub fn result(value: Result(a, b), default: a) -> Validated(a, b)
Creates a Validated from a Result.
It requires a default value in case of failure.
pub fn run(
validator: fn(a) -> Validated(b, c),
input: a,
) -> Validated(b, c)
Run a Validator function.
pub fn run_all(
validators: List(fn(a) -> Validated(b, c)),
input: a,
) -> Validated(Nil, c)
Run all the Validators in order on the given input.
It will accumulate all the errors from all of the Validators.
If there are no errors, or if the list is empty, Valid(Nil) is returned.
pub fn string(value: Result(String, a)) -> Validated(String, a)
Creates a Validated from a Result.
It uses an empty string as the default value in case of failure.
pub fn to_result(
validated: Validated(a, b),
) -> Result(a, List(b))
Convert a Validated into a Result