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"}
]
endrules = [
%{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}) == :errorStarting 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}) == :errorStarting 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.Validatablewith overridablecustom_validate/1
valid?/1is deprecated in favor ofvalidate/1; starting withv1.0valid?/1will returnbooleanvalue
- module-based validators
