valid
Types
A non empty list. Errors returned by a validator are returned in this format.
pub type NonEmptyList(a) =
non_empty_list.NonEmptyList(a)
A Validator is a function that takes an input and returns a ValidatorResult
pub type Validator(input, output, error) =
fn(input) -> ValidatorResult(output, error)
pub type ValidatorResult(output, error) =
Result(output, NonEmptyList(error))
Functions
pub fn all(
validators: List(fn(a) -> Result(a, NonEmptyList(b))),
) -> fn(a) -> Result(a, NonEmptyList(b))
Validate a value using a list of validators. This runs all the validators in the list.
The initial input is passed to all validators. All these validators must have the same input and output types.
Returns Ok when all validators pass. Returns Error when any validator fails. The error will have all failures.
Example
See <test/composition_test.gleam>
pub fn build1(constructor: a) -> Result(a, b)
Build a validator for a type that has one attribute
Example
type Person { Person(name: String) }
let validator = fn(person: Person) {
valid.build1(person)
|> valid.check(person.name, name_validator)
}
pub fn build2(
constructor: fn(a, b) -> c,
) -> Result(fn(a) -> fn(b) -> c, d)
Build a validator for a type that has two attributes
Example
type Person { Person(name: String, age: Int) }
let validator = fn(person: Person) {
valid.build2(person)
|> valid.check(person.name, name_validator)
|> valid.check(person.age, ...)
}
pub fn build3(
constructor: fn(a, b, c) -> d,
) -> Result(fn(a) -> fn(b) -> fn(c) -> d, e)
Build a validator for a type that has three attributes
Example
type Person { Person(name: String, age: Int, email: String) }
let validator = fn(person: Person) {
valid.build3(person)
|> valid.check(person.name, name_validator)
|> valid.check(person.age, ...)
|> valid.check(person.email, ...)
}
pub fn build4(
constructor: fn(a, b, c, d) -> e,
) -> Result(fn(a) -> fn(b) -> fn(c) -> fn(d) -> e, f)
Build a validator for a type that has four attributes
pub fn build5(
constructor: fn(a, b, c, d, e) -> f,
) -> Result(fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f, g)
Build a validator for a type that has five attributes
pub fn build6(
constructor: fn(a, b, c, d, e, f) -> g,
) -> Result(
fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g,
h,
)
Build a validator for a type that has six attributes
pub fn check(
accumulator: Result(fn(a) -> b, NonEmptyList(c)),
input: d,
validator: fn(d) -> Result(a, NonEmptyList(c)),
) -> Result(b, NonEmptyList(c))
Validate an attribute.
Example
let validator = fn(person: Person) {
valid.build1(Person)
|> valid.check(person.name, valid.string_is_not_empty(ErrorEmpty))
}
pub fn check_only(
accumulator: Result(fn(a) -> b, NonEmptyList(c)),
input: d,
validator: fn(d) -> Result(d, NonEmptyList(c)),
) -> Result(fn(a) -> b, NonEmptyList(c))
Performs a validation, but discards the resulting type. So the resulting type is not passed to the final constructor.
pub fn check_whole(
accumulator: Result(a, NonEmptyList(b)),
validator: fn(a) -> Result(c, NonEmptyList(b)),
) -> Result(c, NonEmptyList(b))
Validate the resulting type as a whole.
Sometimes we need to validate a property in relation to another. This validator must be at the end of the pipeline, so it receives the final type.
For example see <test/check_whole_test.gleam>
pub fn if_some(
validator: fn(a) -> Result(b, NonEmptyList(c)),
) -> fn(Option(a)) -> Result(Option(b), NonEmptyList(c))
Validate an optional value.
Run the validator only if the value is Some. If the value is None then return None back.
Example
See <test/validator_optional_test.gleam>
pub fn int_min(
min: Int,
error: a,
) -> fn(Int) -> Result(Int, NonEmptyList(a))
Integer checks
pub fn is_some(
error: a,
) -> fn(Option(b)) -> Result(b, NonEmptyList(a))
Option checks
Validate that a value is not None. Returns the value if Some.
Example
See <test/validator_option_test.gleam
pub fn keep(
accumulator: Result(fn(a) -> b, NonEmptyList(c)),
value: a,
) -> Result(b, NonEmptyList(c))
Keep a value as is
Example
See <test/check_other_test.gleam
pub fn list_every(
validator: fn(a) -> Result(b, NonEmptyList(c)),
) -> fn(List(a)) -> Result(List(b), NonEmptyList(c))
Validate a list of items.
Run the given validator for each item returning all the errors.
Example
See <test/composition_test.gleam
pub fn list_is_not_empty(
error: a,
) -> fn(List(b)) -> Result(List(b), NonEmptyList(a))
List checks
Validate that a list is not empty
pub fn list_max_length(
max: Int,
error: a,
) -> fn(List(b)) -> Result(List(b), NonEmptyList(a))
Validate the max number of items in a list
pub fn list_min_length(
min: Int,
error: a,
) -> fn(List(b)) -> Result(List(b), NonEmptyList(a))
Validate the min number of items in a list
pub fn optional_in(
get: fn(a) -> Result(b, c),
) -> fn(a) -> Result(Option(b), NonEmptyList(d))
pub fn optional_in_dict(
key: a,
) -> fn(Dict(a, b)) -> Result(Option(b), NonEmptyList(c))
Validate an optional attribute in a dict
Example
See <test/validator_optional_test.gleam>
pub fn required_in(
get: fn(a) -> Result(b, c),
error: d,
) -> fn(a) -> Result(b, NonEmptyList(d))
Validate an attribute required in a data type
Here you provide your own accessor
The accessor should return a Result
Example
See <test/validator_required_test.gleam>
pub fn required_in_dict(
key: String,
error: a,
) -> fn(Dict(String, b)) -> Result(b, NonEmptyList(a))
Validate an attribute required in a dictionary If you have a dictionary instead of a custom type, use this.
Example
See <test/dictionary_test.gleam>
pub fn string_is_email(
error: a,
) -> fn(String) -> Result(String, NonEmptyList(a))
Validate if a string is an email.
This checks if a string follows a simple pattern _@_
.
pub fn string_is_float(
error: a,
) -> fn(String) -> Result(Float, NonEmptyList(a))
Validate if a string parses to an Float. Returns the Float if so.
pub fn string_is_int(
error: a,
) -> fn(String) -> Result(Int, NonEmptyList(a))
Validate if a string parses to an Int. Returns the Int if so.
pub fn string_is_not_empty(
error: a,
) -> fn(String) -> Result(String, NonEmptyList(a))
String checks
Validate that a string is not empty
pub fn string_max_length(
max: Int,
error: a,
) -> fn(String) -> Result(String, NonEmptyList(a))
Validate the max length of a string
pub fn string_min_length(
min: Int,
error: a,
) -> fn(String) -> Result(String, NonEmptyList(a))
Validate the min length of a string
pub fn then(
validator1: fn(a) -> Result(b, NonEmptyList(c)),
validator2: fn(b) -> Result(d, NonEmptyList(c)),
) -> fn(a) -> Result(d, NonEmptyList(c))
Compose validators
Run the first validator and if successful then the second. This short circuits, so only returns the first error.
Example
See <test/composition_test.gleam>