valid/experimental
Types
A validator is a function that takes an input
and returns a tuple of #(output, errors)
.
A validator always need to return an output of the desired type. So default values are used for this.
When the errors list is empty, the validation is considered successful.
pub type Validator(input, output, e) =
fn(input) -> #(output, List(e))
Functions
pub fn check(
input input: a,
validator validator: fn(a) -> #(b, List(c)),
next next: fn(b) -> #(d, List(c)),
) -> #(d, List(c))
Add a field validator to the validator pipeline
fn validator(input: Int) {
use out <- valid.check(input, valid.int_max(12, "Error"))
valid.ok(out)
}
pub fn fail(default: a, error: b) -> #(a, List(b))
A validator that fails with the given default and error.
pub fn int_max(
max max: Int,
error error: a,
) -> fn(Int) -> #(Int, List(a))
e.g.
fn validator(input) {
use out <- valid.check(input, valid.int_max(12, "Cannot be higher than 12"))
valid.ok(out)
}
pub fn int_min(
min min: Int,
error error: a,
) -> fn(Int) -> #(Int, List(a))
e.g.
fn validator(input) {
use out <- valid.check(input, valid.int_min(12, "Must be more than 12"))
valid.ok(out)
}
pub fn is_some(
default default: a,
validator validator: fn(b) -> #(a, List(c)),
error error: c,
) -> fn(Option(b)) -> #(a, List(c))
Validate that a value is not None.
The validator fails if None.
Runs the nested validator when Some.
This validator requires a default
value to be provided.
fn validator(input) {
use out <- valid.check(input, valid.is_some("", valid.ok, "Input"))
valid.ok(out)
}
pub fn list_all(
validator validator: fn(a) -> #(b, List(c)),
) -> fn(List(a)) -> #(List(b), List(c))
Runs the validator for each item in a list
fn validator(input) {
use out <- valid.check(input, valid.list_all(valid.string_is_not_empty("Empty")))
valid.ok(out)
}
pub fn optional(
validator validator: fn(a) -> #(b, List(c)),
) -> fn(Option(a)) -> #(Option(b), List(c))
Run a validator only when the value is Some Otherwise succeed with None
pub fn string_is_email(
error error: a,
) -> fn(String) -> #(String, List(a))
This checks if a string follows a simple pattern _@_
.
pub fn string_is_float(
error error: a,
) -> fn(String) -> #(Float, List(a))
Validate if a string parses to an Float. Returns the Float if so.
pub fn string_is_float_strict(
error error: a,
) -> fn(String) -> #(Float, List(a))
Validate if a string parses to an Float. Returns the Float if so.
pub fn string_is_int(
error error: a,
) -> fn(String) -> #(Int, List(a))
Validate if a string parses to an Int. Returns the Int if so.
pub fn string_is_not_empty(
error error: a,
) -> fn(String) -> #(String, List(a))
Validate that a string is not empty
pub fn string_max_length(
max max: Int,
error error: a,
) -> fn(String) -> #(String, List(a))
Validate the max length of a string
pub fn string_min_length(
min min: Int,
error error: a,
) -> fn(String) -> #(String, List(a))
Validate the min length of a string
pub fn then(
first_validator first_validator: fn(a) -> #(b, List(c)),
second_validator second_validator: fn(b) -> #(b, List(c)),
) -> fn(a) -> #(b, List(c))
Compose two validators. This will only return the first error found.
e.g.
fn validator(input_name) {
use name <- valid.check(
input_name,
valid.string_min_length(2, "Min 2")
|> valid.then(valid.string_max_length(20, "Max 20")),
)
valid.ok(name)
}
pub fn validate(
input input: a,
validator validator: fn(a) -> #(b, List(c)),
) -> Result(b, List(c))
Run a validator
fn name_validator(input) {
use name <- valid.check(input, valid.string_min_length(2, "Min 2"))
valid.ok(name)
}
let result = "Sally"
|> valid.validate(name_validator)
result == Ok("Sally")
let result = ""
|> valid.validate(name_validator)
result == Error(["Min 2"])