generator for blazingly fast validators of maps based on sets of predefined rules
Simply add exvalibur
to your list of dependencies in mix.exs
:
def deps do
[
{:exvalibur, "~> 0.1"}
]
end
rules = [
%{matches: %{currency_pair: "EURUSD"},
conditions: %{rate: %{min: 1.0, max: 2.0}}}]
Exvalibur.validator!(rules, module_name: Exvalibur.Validator)
Exvalibur.Validator.valid?(%{currency_pair: "EURUSD", rate: 1.5})
#⇒ {:ok, %{currency_pair: "EURUSD", rate: 1.5}}
Exvalibur.Validator.valid?(%{currency_pair: "EURGBP", rate: 1.5})
#⇒ :error
Exvalibur.Validator.valid?(%{currency_pair: "EURUSD", rate: 0.5})
#⇒ :error
rules = [
%{matches: %{currency_pair: "EURGBP"},
conditions: %{rate: %{min: 1.0, max: 2.0}}}]
Exvalibur.validator!(rules, module_name: Exvalibur.Validator)
Exvalibur.Validator.valid?(%{currency_pair: "EURGBP", rate: 1.5})
#⇒ {:ok, %{currency_pair: "EURGBP", rate: 1.5}}
Exvalibur.Validator.valid?(%{currency_pair: "EURUSD", rate: 1.5})
#⇒ {:ok, %{currency_pair: "EURUSD", rate: 1.5}}
Starting with v0.4.0
we support ~q
and ~Q
sigils to use validator with
pattern matching.
import Exvalibur.Sigils
starting_with = "bar"
rules = [%{matches: %{foo: ~q[<<"#{starting_with}", _::binary>>]}}]
Exvalibur.validator!(rules, module_name: TestValidator)
assert TestValidator.valid?(%{foo: "bar"}) == {:ok, %{foo: "bar"}}
assert TestValidator.valid?(%{foo: "zzz"}) == :error
assert TestValidator.valid?(%{foo: 42}) == :error
Starting with v0.5.0
we support binary conditions for the declared guards.
import Exvalibur.Sigils
rules = [%{conditions: "num >= 0 and num <= 100"}]
Exvalibur.validator!(rules, module_name: TestValidator)
assert TestValidator.valid?(%{num: "bar"}) == :error
assert TestValidator.valid?(%{num: 200}) == :error
assert TestValidator.valid?(%{num: 42}) == {:ok, %{num: 42}}
Any match expression allowed in function head matching clause is allowed here.
import Exvalibur.Sigils
rules = [%{matches: %{foo: ~Q[%{} = _]}}]
Exvalibur.validator!(rules, module_name: TestValidator)
assert TestValidator.valid?(%{foo: %{bar: "baz"}}) == {:ok, %{foo: %{bar: "baz"}}}
assert TestValidator.valid?(%{foo: 42}) == :error
Starting with v0.6.0
we support arbitrary custom guards in rules. The variables
used in these guards should be explicitly declared under the matches
key in rules,
in the form foo: ~Q[foo]
.
import Exvalibur.Sigils
rules = [%{
matches: %{num: ~Q[num]},
guards: ["num >= 0 and num <= 100"]
}]
Exvalibur.validator!(rules, module_name: TestValidator)
assert TestValidator.valid?(%{num: "bar"}) == :error
assert TestValidator.valid?(%{num: 200}) == :error
assert TestValidator.valid?(%{num: 42}) == {:ok, %{num: 42}}
defmodule Validator do
use Exvalibur, rules: [
%{
matches: %{currency_pair: <<"EUR", _ :: binary>>},
conditions: %{foo: %{min: 0, max: 100}},
guards: %{num: num > 0 and num < 100}}]
end
Validator.valid?(%{currency_pair: "EURUSD", foo: 50, num: 50})
#⇒ {:ok, %{currency_pair: "EURUSD", foo: 50, num: 50}}
Validator.valid?(%{currency_pair: "USDEUR", foo: 50, num: 50})
#⇒ :error
Validator.valid?(%{currency_pair: "EURUSD", foo: -50, num: 50})
#⇒ :error
Validator.valid?(%{currency_pair: "EURUSD", foo: 50, num: -50})
#⇒ :error
- Descriptive errors
@behaviour Exvalibur.Validatable
with overridablecustom_validate/1
valid?/1
is deprecated in favor ofvalidate/1
; starting withv1.0
valid?/1
will returnboolean
value
- module-based validators