exchema v0.4.0 Exchema.Predicates

Exschema default predicates library

Link to this section Summary

Functions

Ensure the value is not in a list of values

Checks the types of specific fields of a Map or Keyword List

Checks against a specific regex format

Just applies the function as if it was a predicate. It also checks for exceptions to allow simpler functions

Checks if something is greater than a value

Checks if something is greater than or equal to a value

Ensure the value is in a list of values

Checks against system guards like is_integer or is_float

Checks whether or not the given value is a struct or a specific struct

Checks the key types of a map

Checks the length of the input. You can pass a max, a min, a range or a specific lenght

Checks the list type It can also check the types of the elemsts of the list by passing the :element_type param

Checks if something is lesser than a value

Checks if something is lesser than or equal a value

Checks the types of the values of a Map or Keyword List

Link to this section Types

Link to this type error()
error() :: {:error, any()}
Link to this type failure()
failure() :: false | error() | [error(), ...]
Link to this type result()
result() :: failure() | success()
Link to this type success()
success() :: :ok | true | []

Link to this section Functions

Link to this function exclusion(val, values)

Ensure the value is not in a list of values

Examples

iex> Exchema.Predicates.exclusion("apple", ["apple", "banana"])
{:error, :invalid}

iex> Exchema.Predicates.exclusion(5, 1..10)
{:error, :invalid}

iex> Exchema.Predicates.exclusion("horse", ["apple", "banana"])
:ok
Link to this function fields(map, fields)

Checks the types of specific fields of a Map or Keyword List

Examples

iex> Exchema.Predicates.fields(%{foo: 1}, foo: Exchema.Types.Integer)
:ok

iex> Exchema.Predicates.fields([foo: 1], foo: Exchema.Types.Integer)
:ok

iex> Exchema.Predicates.fields(%{foo: :bar}, foo: Exchema.Types.Integer)
{:error, {
  :nested_errors,
  [{:foo, [{{Exchema.Predicates, :is}, :integer, :not_an_integer}]}]
}}
Link to this function format(val, regex)

Checks against a specific regex format

Examples

iex> Exchema.Predicates.format("starts-with", ~r/^starts-/)
:ok

iex> Exchema.Predicates.format("does-not-starts-with", ~r/^starts-/)
{:error, :invalid}
Link to this function fun(val, fun)
fun(any(), (any() -> result())) :: result()

Just applies the function as if it was a predicate. It also checks for exceptions to allow simpler functions.

Examples

iex> Exchema.Predicates.fun(1, &is_integer/1)
true

iex> Exchema.Predicates.fun("1", &is_integer/1)
false

iex> Exchema.Predicates.fun(1, &(&1 > 0))
true

iex> Exchema.Predicates.fun(0, &(&1 > 0))
false

iex> Exchema.Predicates.fun(1, fn _ -> {:error, :custom_error} end)
{:error, :custom_error}

iex> Exchema.Predicates.fun(1, fn _ -> raise RuntimeError end)
{:error, :thrown}

Checks if something is greater than a value

iex> Exchema.Predicates.gt(2, 1)
:ok

iex> Exchema.Predicates.gt(2, 2)
{:error, :not_greater}

iex> Exchema.Predicates.gt(2, 3)
{:error, :not_greater}

iex> Exchema.Predicates.gt("b", "a")
:ok

iex> Exchema.Predicates.gt("a", "b")
{:error, :not_greater}

Checks if something is greater than or equal to a value

iex> Exchema.Predicates.gte(2, 1)
:ok

iex> Exchema.Predicates.gte(2, 2)
:ok

iex> Exchema.Predicates.gte(2, 3)
{:error, :not_greater_or_equal}

iex> Exchema.Predicates.gte("b", "a")
:ok

iex> Exchema.Predicates.gte("a", "b")
{:error, :not_greater_or_equal}
Link to this function inclusion(val, values)

Ensure the value is in a list of values

Examples

iex> Exchema.Predicates.inclusion("apple", ["apple", "banana"])
:ok

iex> Exchema.Predicates.inclusion(5, 1..10)
:ok

iex> Exchema.Predicates.inclusion("horse", ["apple", "banana"])
{:error, :invalid}

Checks against system guards like is_integer or is_float.

Examples

iex> Exchema.Predicates.is(1, :integer)
:ok

iex> Exchema.Predicates.is(1.0, :float)
:ok

iex> Exchema.Predicates.is(1, :nil)
{:error, :not_nil}

iex> Exchema.Predicates.is(1, :atom)
{:error, :not_an_atom}

iex> Exchema.Predicates.is(nil, :binary)
{:error, :not_a_binary}

iex> Exchema.Predicates.is(nil, :bitstring)
{:error, :not_a_bitstring}

iex> Exchema.Predicates.is(nil, :boolean)
{:error, :not_a_boolean}

iex> Exchema.Predicates.is(nil, :float)
{:error, :not_a_float}

iex> Exchema.Predicates.is(nil, :function)
{:error, :not_a_function}

iex> Exchema.Predicates.is(nil, :integer)
{:error, :not_an_integer}

iex> Exchema.Predicates.is(nil, :list)
{:error, :not_a_list}

iex> Exchema.Predicates.is(nil, :map)
{:error, :not_a_map}

iex> Exchema.Predicates.is(nil, :number)
{:error, :not_a_number}

iex> Exchema.Predicates.is(nil, :pid)
{:error, :not_a_pid}

iex> Exchema.Predicates.is(nil, :port)
{:error, :not_a_port}

iex> Exchema.Predicates.is(nil, :reference)
{:error, :not_a_reference}

iex> Exchema.Predicates.is(nil, :tuple)
{:error, :not_a_tuple}
Link to this function is_struct(arg1, expected)

Checks whether or not the given value is a struct or a specific struct.

Note: It’s named is_struct to avoid conflict with Kernel.struct.

Examples

iex> Exchema.Predicates.is_struct(%{}, [])
{:error, :not_a_struct}

iex> Exchema.Predicates.is_struct(nil, [])
{:error, :not_a_struct}

Also, keep in mind that many internal types are actually structs

iex> Exchema.Predicates.is_struct(DateTime.utc_now, nil)
:ok

iex> Exchema.Predicates.is_struct(NaiveDateTime.utc_now, nil)
:ok

iex> Exchema.Predicates.is_struct(DateTime.utc_now, DateTime)
:ok

iex> Exchema.Predicates.is_struct(DateTime.utc_now, NaiveDateTime)
{:error, :invalid_struct}

iex> Exchema.Predicates.is_struct(NaiveDateTime.utc_now, DateTime)
{:error, :invalid_struct}

iex> Exchema.Predicates.is_struct(DateTime.utc_now, [NaiveDateTime, DateTime])
:ok

iex> Exchema.Predicates.is_struct(Date.utc_today, [NaiveDateTime, DateTime])
{:error, :invalid_struct}
Link to this function key_type(map, type)

Checks the key types of a map

Examples

iex> Exchema.Predicates.key_type("", :any)
{:error, :not_a_map}

iex > Exchema.Predicates.key_type(%{1 => "value"}, Exchema.Types.Integer)
:ok

iex > Exchema.Predicates.key_type(%{"key" => 1}, Exchema.Types.Integer)
{:error, {
  :key_errors,
  [{"key", [{{Exchema.Predicates, :is}, :integer, :not_an_integer}]}]
}}
Link to this function length(val, opts)

Checks the length of the input. You can pass a max, a min, a range or a specific lenght.

Can check length of either lists, strings or tuples.

Examples

iex> Exchema.Predicates.length("123", 3)
:ok

iex> Exchema.Predicates.length([1,2,3], 3)
:ok

iex> Exchema.Predicates.length({1,2,3}, 3)
:ok

iex> Exchema.Predicates.length([1,2,3], min: 2)
:ok

iex> Exchema.Predicates.length([1,2,3], max: 3)
:ok

iex> Exchema.Predicates.length([1,2,3], 2..4)
:ok

iex> Exchema.Predicates.length([1,2,3], min: 2, max: 4)
:ok

iex> Exchema.Predicates.length([1,2,3], min: 4)
{:error, :invalid_length}

iex> Exchema.Predicates.length([1,2,3], max: 2)
{:error, :invalid_length}

iex> Exchema.Predicates.length([1,2,3], min: 1, max: 2)
{:error, :invalid_length}

iex> Exchema.Predicates.length([1,2,3], 2)
{:error, :invalid_length}

iex> Exchema.Predicates.length([1,2,3], 1..2)
{:error, :invalid_length}
Link to this function list(list, element_type)

Checks the list type It can also check the types of the elemsts of the list by passing the :element_type param.

Examples

iex> Exchema.Predicates.list("", :any)
{:error, :not_a_list}

iex> Exchema.Predicates.list([], :any)
:ok

iex> Exchema.Predicates.list(["",1,""], Exchema.Types.Integer)
{:error, {
  :nested_errors,
  [
    {0, [{{Exchema.Predicates, :is}, :integer, :not_an_integer}]},
    {2, [{{Exchema.Predicates, :is}, :integer, :not_an_integer}]}
  ]}
}

iex> Exchema.Predicates.list([1,2,3], Exchema.Types.Integer)
:ok

Checks if something is lesser than a value

iex> Exchema.Predicates.lt(1, 2)
:ok

iex> Exchema.Predicates.lt(2, 2)
{:error, :not_lesser}

iex> Exchema.Predicates.lt(3, 2)
{:error, :not_lesser}

iex> Exchema.Predicates.lt("a", "b")
:ok

iex> Exchema.Predicates.lt("b", "a")
{:error, :not_lesser}

Checks if something is lesser than or equal a value

iex> Exchema.Predicates.lte(1, 2)
:ok

iex> Exchema.Predicates.lte(2, 2)
:ok

iex> Exchema.Predicates.lte(3, 2)
{:error, :not_lesser_or_equal}

iex> Exchema.Predicates.lte("a", "b")
:ok

iex> Exchema.Predicates.lte("b", "a")
{:error, :not_lesser_or_equal}
Link to this function value_type(map, type)

Checks the types of the values of a Map or Keyword List

Examples

iex > Exchema.Predicates.value_type(%{"key" => 1}, Exchema.Types.Integer)
:ok

iex > Exchema.Predicates.value_type([key: 1], Exchema.Types.Integer)
:ok

iex > Exchema.Predicates.value_type(%{1 => "value"}, Exchema.Types.Integer)
{:error, {
  :nested_errors,
  [{1, [{{Exchema.Predicates, :is}, :integer, :not_an_integer}]}]
}}

iex > Exchema.Predicates.value_type([foo: :bar], Exchema.Types.Integer)
{:error, {
  :nested_errors,
  [{:foo, [{{Exchema.Predicates, :is}, :integer, :not_an_integer}]}]
}}