LIVR implementation for Erlang
Erlang Other
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
.travis.yml fix travis to use only 17.5 erlang Jan 29, 2016
Makefile add tuple with ok or error atom to resultset Aug 11, 2015
olifer.iml fixed issue #1 Oct 26, 2015


Olifer is lightweight validator supporting Language Independent Validation Rules Specification (LIVR) for Erlang

See for detailed documentation and list of supported rules.

Build Status Coverage Status


  • Rules are declarative and language independent
  • Any number of rules for each field
  • Return together errors for all fields
  • Excludes all fields that do not have validation rules described
  • Has possibility to validatate complex hierarchical structures
  • Easy to describe and undersand rules
  • Returns understandable error codes(not error messages)
  • Easy to add own rules
  • Rules are be able to change results output ("trim", "nested_object", for example)
  • Multipurpose (user input validation, configs validation, contracts programming etc)


  1. Add as a dependency in your project:
  • For rebar add to rebar.config
   {olifer, ".*",
        {git, "", {branch, master}}
  • For add to make file:
   DEPS = olifer
   dep_olifer = master
  1. Add in file in tuple applications:
    {applications, [
  2. Run olifer:start() in your project start function.
  3. Thats all, now you can validate data, register your own rules or aliased built-in rules.

#USAGE 1. Validate data

Simple example:

1> Input =  [{<<"first_name">>,<<"Vasya">>}].

2> Rule = [{<<"first_name">>,[{<<"length_between">>,[4,6]}]}].

3> olifer:validate(Input, Rule).

4> {ok, [{<<"first_name">>,<<"Vasya">>}]}

5> Input1 =  [{<<"number1">>,-1.12}].

6> Rule1 = [{<<"number1">>,<<"integer">>}].

7> olifer:validate(Input1, Rule1).

8> {errors, [{<<"number1">>,<<"NOT_INTEGER">>}]}

More complex example

1> Input =  [{<<"address">>,
                [{<<"country">>, <<"Ukraine">>},
                 {<<"zip">>, <<"12345">>},
                 {<<"street">>, <<"10">>},
                 {<<"building">>, <<"10">>},
                 {<<"extra_field">>, <<"will be removed">>}]},
            {<<"extra_field">>, <<"will be removed">>}].

2> Rules = [{<<"address">>,
                   [{<<"country">>, [<<"required">>, [{<<"one_of">>, [[<<"Ukraine">>, <<"USA">>]]}]]},
                    {<<"zip">>, <<"positive_integer">>},
                    {<<"street">>, <<"required">>},
                    {<<"building">>, [<<"required">>, <<"positive_integer">>]}]}]]}].

3> olifer:validate(Input, Rules).

4> {ok, [{<<"address">>,
           [{<<"country">>, <<"Ukraine">>},
            {<<"zip">>, <<"12345">>},
            {<<"street">>, <<"10">>},
            {<<"building">>, <<"10">>}]}]}

2. Register aliased rule

The "name" and "rules" fields is required, "error" is not required for alias definition

1> Alias1 = [[{<<"name">>, <<"adult_age">>},
              {<<"rules">>, [<<"positive_integer">>, [{<<"min_number">>, 18}]]}]].

2> Alias2 = [[{<<"name">>, <<"adult_age_with_custom_error">>},
              {<<"rules">>, [<<"positive_integer">>, [{<<"min_number">>, 18}]]},
              {<<"error">>, <<"WRONG_AGE">>}]].

3> olifer:register_aliased_rule(Alias1).
4> olifer:register_aliased_rule(Alias2).
5> Rules =  [{<<"age1">>, <<"adult_age">>}, {<<"age2">>, <<"adult_age_with_custom_error">>}].

6> Input = [{<<"age1">>, 14}].

7> Input1 = [{<<"age1">>, 32}].

8> Input2 = [{<<"age2">>, 15}].

9> olifer:validate(Input, Rules).
{errors, [{<<"age1">>,<<"TOO_LOW">>}]}

10> olifer:validate(Input1, Rules).
{ok, [{<<"age1">>, 32}]}

11> olifer:validate(Input2, Rules).
{errors, [{<<"age2">>, <<"WRONG_AGE">>}]}

3. Register new rule

You can create your own rules, for example:



strong_password(Value, [MinLength]) ->
    strong_password(Value, MinLength);
strong_password(Value, MinLength) when is_binary(Value), byte_size(Value) >= MinLength ->
    {ok, Value};
strong_password(Value, _Args) when is_binary(Value) ->
    {error, <<"WEAK_PSSSWORD">>};
strong_password(_Value, _Args) ->
    {error, <<"FORMAT_ERROR">>}.

The function that describe the rule should has 2 arguments, first argument is Value for validation and second argument is a value/list of values for rule. After creation your own rule you should register it:

1> olifer:register_rule(<<"strong_password">>, new_rules, strong_password).
2> Rules = [{<<"password1">>, [{<<"strong_password">>, 15}]}, {<<"password2">>, [{<<"strong_password">>,[15]}]}].

3> Input = [{<<"password1">>, <<"123456789012345">>}, {<<"password2">>, <<"asdasdasdasdasdasd">>}].

4> olifer:validate(Input, Rules).
{ok, [{<<"password1">>, <<"123456789012345">>}, {<<"password2">>, <<"asdasdasdasdasdasd">>}]}

5> Input1 = [{<<"password1">>, <<"1234">>}, {<<"password2">>, <<"asdasd">>}].

6> olifer:validate(Input1, Rules).
{errors, [{<<"password1">>, <<"WEAK_PSSSWORD">>}, {<<"password2">>, <<"WEAK_PSSSWORD">>}]}