ExValidator v0.1.0 ExValidator View Source
Helpers for validating and normalizing Elixir data structures.
All the examples below asume that the ExValidator
module is imported.
The validation works as simple composable functions, allowing simple validations…
iex> validator = integer(max: 2)
iex> validator.(2)
{:ok, 2}
iex> validator.(4)
{:error, "greater than 2"}
…data casting…
iex> validator = map_of(%{name: string(required: true), age: integer(min: 1)})
iex> validator.(%{"name" => "Jhon", "age": "26"})
{:ok, %{name: "Jhon", age: 26}}
iex> validator.(%{"age": "a"})
{:error, %{name: "is blank", age: "not a number"}}
…and more complex use cases:
iex> address = map_of(%{
...> city: string(required: true),
...> state: string(required: true, min: 2, max: 2)
...> })
iex> person = map_of(%{
...> name: string(required: true),
...> age: integer(min: 1),
...> addresses: list_of(address)
...> })
iex> validator = list_of(person)
iex> data = [
...> %{
...> "name" => "Jhon",
...> "age" => "aa",
...> "addresses" => [
...> %{"city" => "New York", "state" => "NY"},
...> %{"city" => "Los Angeles", "state" => "LA"},
...> ]
...> },
...> %{
...> "name" => "Alex",
...> "addresses" => [
...> %{"city" => "Chicago", "states" => "IL"},
...> %{"city" => "San Francisco", "state" => "CA"},
...> ]
...> }
...> ]
iex> validator.(data)
{:error, %{
0 => %{age: "not a number"},
1 => %{addresses: %{0 => %{state: "is blank"}}}
}}
Global options
These are the global options shared among all validators:
required
- validates if the value is presentdefault
- default result for when the value is not present
Link to this section Summary
Functions
Checks if any of the given validators allows the value
Validates and parses booleans
Allows for easy validation composition
Validates and parses floats
Validates and parses integers
Validates lists, while stripping nil
s
Validates maps
Validates and trims strings. Values that implement the String.Chars
protocol are converted
to strings
Link to this section Types
Link to this section Functions
Checks if any of the given validators allows the value.
Examples
iex> validator = any_of([integer(required: true), string(required: true, matches: ~r/^foo/)])
iex> validator.(1)
{:ok, 1}
iex> validator.("fooz")
{:ok, "fooz"}
iex> validator.("baaz")
{:error, ["not a number", "no match"]}
iex> validator.(nil)
{:error, ["is blank", "is blank"]}
Validates and parses booleans.
The parsing follows the following rule:
- truthy values: true, “true”, 1, “1”
- falsey values: false, “false”, 0, “0”
Options
message
- changes the returned error message
Examples
iex> boolean().(true)
{:ok, true}
iex> boolean().("1")
{:ok, true}
iex> boolean().("true")
{:ok, true}
iex> boolean().("0")
{:ok, false}
iex> boolean().("false")
{:ok, false}
iex> boolean().(nil)
{:ok, nil}
iex> boolean().("yes")
{:error, "not a boolean"}
Allows for easy validation composition.
Useful for customizing the error message for each kind of error.
Examples
iex> validator = compose([
...> integer(required: true, message: "WHERE'S THE NUMBER??"),
...> integer(min: 5, message: "IT'S TOO LOW!!!"),
...> integer(max: 15, message: "IT'S TOO HIGH!!!"),
...> ])
iex> validator.(10)
{:ok, 10}
iex> validator.(nil)
{:error, "WHERE'S THE NUMBER??"}
iex> validator.(3)
{:error, "IT'S TOO LOW!!!"}
iex> validator.(17)
{:error, "IT'S TOO HIGH!!!"}
Validates and parses floats
Options
min
- validates that the number is equal to or greater than the given valuemax
- validates that the number is equal to or smaller than the given valuemessage
- changes the returned error message
Examples
iex> float().(1.0)
{:ok, 1.0}
iex> float().("1")
{:ok, 1.0}
iex> float().("1a")
{:error, "not a number"}
iex> float(message: "whaaaat?").(:foo)
{:error, "whaaaat?"}
iex> float().(nil)
{:ok, nil}
iex> float(required: true).(nil)
{:error, "is blank"}
Validates and parses integers.
Options
min
- validates that the number is equal to or greater than the given valuemax
- validates that the number is equal to or smaller than the given valueone_of
- validates if the number is contained in the given enummessage
- changes the returned error message
Examples
iex> integer().(1)
{:ok, 1}
iex> integer().("1")
{:ok, 1}
iex> integer().("1a")
{:error, "not a number"}
iex> integer(message: "what is this?").(:foo)
{:error, "what is this?"}
iex> integer().(nil)
{:ok, nil}
iex> integer(required: true).(nil)
{:error, "is blank"}
Validates lists, while stripping nil
s.
Errors are returned as a map containing the index and the respective error.
Options
min
- validates that the list length is equal to or greater than the given valuemax
- validates that the list length is equal to or smaller than the given value
Examples
iex> list_of(integer()).([1, 2, 3])
{:ok, [1, 2, 3]}
iex> list_of(integer()).("")
{:error, "not a list"}
iex> list_of(integer(min: 5, max: 15)).([3, 4, 7, 8, 10, 13, 17])
{:error, %{0 => "less than 5", 1 => "less than 5", 6 => "greater than 15"}}
iex> list_of(integer()).(nil)
{:ok, nil}
iex> list_of(integer(), required: true).(nil)
{:error, "is blank"}
Validates maps.
Errors are returned as a map containing the key and the respective error.
Examples
iex> validator = map_of(%{name: string(required: true), age: integer(min: 1)})
iex> validator.(%{name: "Jhon", foo: "Bar"})
{:ok, %{name: "Jhon", age: nil}}
iex> validator.(%{"name" => "Jhon", "age" => "2"})
{:ok, %{name: "Jhon", age: 2}}
iex> validator.(%{age: 0})
{:error, %{name: "is blank", age: "less than 1"}}
iex> validator.(nil)
{:ok, nil}
iex> validator.("")
{:error, "not a map"}
iex> map_of(%{}, required: true).(nil)
{:error, "is blank"}
Validates and trims strings. Values that implement the String.Chars
protocol are converted
to strings.
Options
min
- validates that the string length is equal to or greater than the given valuemax
- validates that the string length is equal to or smaller than the given valueone_of
- validates that the string is contained in the given enummatches
- validates that the string matches the given patternmessage
- changes the returned error message
Examples
iex> string().("some text")
{:ok, "some text"}
iex> string().(" some text \n")
{:ok, "some text"}
iex> string(matches: ~r/foo|bar/).("fooz")
{:ok, "fooz"}
iex> string(matches: ~r/foo|bar/).("baz")
{:error, "no match"}
iex> string().(%{})
{:error, "not a string"}
iex> string().("")
{:ok, nil}
iex> string(required: true).("")
{:error, "is blank"}