Validixir (validixir v0.1.0)

Module containing all basic functionality needed for validation.

Link to this section Summary

Functions

Takes a validation_result_t() and a functions that takes the candidate in case of a success and returns a validation_result_t() again. This function is used to chain validations.

Augments a failure's contexts if a failure is passed, else returns the success.

Augments a failure's messages if a failure is passed, else returns the success.

Takes a validation result and two functions that are applied as in map_success/2 and map_failure/2 respectivly.

Applies a function to the errors of a failure. If a success is passed it is returned unchanged.

Applies a function to the candidate of a success. If a failure is passed it is returned unchanged.

Overrides a failure's contexts if a failure is passed, else returns the success.

Overrides a failure's messages if a failure is passed, else returns the success.

Takes a value and lifts it in a validation result, returning a success with the value as its candidate.

This function applies a function wrapped in a validation success to the candidate of a validation success. If both validation results are failures it returns them combined. If only the first one is a failure, this failure is returned unchanged.

Takes a list of validation results and returns a validation success containing list of all candidates, if all validation results are successes. Else all failures are combined and a validation failure is returned.

Does the same as Validixir.sequence/1 but applies a validation function to all candidates first. Takes an optional context to augment the results, including the index. Uses :seq if none is given.

Takes a function that is called iff all validation results are Successes. The call parameters are then the candidates in the respective order. Returns a validation success then, with the candidate being the return value of this function. If there is at least one failure, errors get accumulated and a validation failure is returned.

Applies a list of validation functions to a candidate. Returns a success containing the candidate if each validation function returns a success. Else returns a validation failure containing errors of each failed validation.

Returns true if a value is either a [[Validixir.Success]] or a [[Validixir.Failure]], returns false else.

Link to this section Types

Link to this type

validate_all_return_t(inner_t)

@type validate_all_return_t(inner_t) ::
  {:ok, validation_result_t(inner_t)} | {:error, :no_validators}
Link to this type

validation_fun_t(result_t)

@type validation_fun_t(result_t) :: (any() -> validation_result_t(result_t))
Link to this type

validation_result_t(inner_t)

@type validation_result_t(inner_t) ::
  Validixir.Failure.t() | Validixir.Success.t(inner_t)

Link to this section Functions

Link to this function

and_then(validation_result, f)

Takes a validation_result_t() and a functions that takes the candidate in case of a success and returns a validation_result_t() again. This function is used to chain validations.

examples

Examples

iex> Validixir.Success.make(0) |> Validixir.and_then(fn x -> Validixir.Success.make(x + 1) end)
%Validixir.Success{candidate: 1}

iex> Validixir.Failure.make([]) |> Validixir.and_then(fn x -> x + 1 end)
%Validixir.Failure{errors: []}
Link to this function

augment_contexts(s, additional_context)

Augments a failure's contexts if a failure is passed, else returns the success.

examples

Examples

iex> Validixir.pure(12) |> Validixir.augment_contexts(Hello)
%Validixir.Success{candidate: 12}

iex> error_1 = Validixir.Error.make(1, :message, Context)
iex> error_2 = Validixir.Error.make(2, :message, AnotherContext)
iex> failure = Validixir.Failure.make([error_1, error_2])
iex> Validixir.augment_contexts(failure, AdditionalContext)
%Validixir.Failure{
    errors: [
        %Validixir.Error{candidate: 1, message: :message, context: {AdditionalContext, Context}},
        %Validixir.Error{candidate: 2, message: :message, context: {AdditionalContext, AnotherContext}},
    ]
}
Link to this function

augment_messages(s, additional_message)

Augments a failure's messages if a failure is passed, else returns the success.

examples

Examples

iex> Validixir.pure(12) |> Validixir.augment_messages(Hello)
%Validixir.Success{candidate: 12}

iex> error_1 = Validixir.Error.make(1, :message, Context)
iex> error_2 = Validixir.Error.make(2, :another_message, Context)
iex> failure = Validixir.Failure.make([error_1, error_2])
iex> Validixir.augment_messages(failure, :additional_message)
%Validixir.Failure{
    errors: [
        %Validixir.Error{candidate: 1, message: {:additional_message, :message}, context: Context},
        %Validixir.Error{candidate: 2, message: {:additional_message, :another_message}, context: Context}
    ]
}
Link to this function

map(f, f_success, f_failure)

Takes a validation result and two functions that are applied as in map_success/2 and map_failure/2 respectivly.

examples

Examples

iex> success = Validixir.Success.make(0)
iex> Validixir.map(success, fn a -> a + 1 end, fn _ -> :does_nothing end)
%Validixir.Success{candidate: 1}

iex> failure = Validixir.Failure.make([Validixir.Error.make(1, :hello, :hello)])
iex> Validixir.map(failure, fn _ -> :does_nothing end, fn err -> %Validixir.Error{ err | candidate: 2} end)
%Validixir.Failure{errors: [Validixir.Error.make(2, :hello, :hello)]}
Link to this function

map_failure(failure, f)

Applies a function to the errors of a failure. If a success is passed it is returned unchanged.

examples

Examples

iex> success = Validixir.Success.make(0)
iex> Validixir.map_failure(success, fn a -> a + 1 end)
%Validixir.Success{candidate: 0}

iex> failure = Validixir.Failure.make([Validixir.Error.make(1, :hello, :hello)])
iex> Validixir.map_failure(failure, fn err -> %Validixir.Error{ err | candidate: 2} end)
%Validixir.Failure{errors: [Validixir.Error.make(2, :hello, :hello)]}
Link to this function

map_success(success, f)

Applies a function to the candidate of a success. If a failure is passed it is returned unchanged.

examples

Examples

iex> success = Validixir.Success.make(0)
iex> Validixir.map_success(success, fn a -> a + 1 end)
%Validixir.Success{candidate: 1}

iex> failure = Validixir.Failure.make([])
iex> Validixir.map_success(failure, fn a -> a + 1 end)
%Validixir.Failure{errors: []}
Link to this function

override_contexts(s, context)

Overrides a failure's contexts if a failure is passed, else returns the success.

examples

Examples

iex> Validixir.pure(12) |> Validixir.override_contexts(Hello)
%Validixir.Success{candidate: 12}

iex> error_1 = Validixir.Error.make(1, :message, Context)
iex> error_2 = Validixir.Error.make(2, :another_message, Context)
iex> failure = Validixir.Failure.make([error_1, error_2])
iex> Validixir.override_contexts(failure, NewContext)
%Validixir.Failure{
    errors: [
    %Validixir.Error{candidate: 1, message: :message, context: NewContext},
    %Validixir.Error{candidate: 2, message: :another_message, context: NewContext}
    ]
}
Link to this function

override_messages(s, message)

Overrides a failure's messages if a failure is passed, else returns the success.

examples

Examples

iex> Validixir.pure(12) |> Validixir.override_messages(Hello)
%Validixir.Success{candidate: 12}

iex> error_1 = Validixir.Error.make(1, :message, Context)
iex> error_2 = Validixir.Error.make(2, :another_message, Context)
iex> failure = Validixir.Failure.make([error_1, error_2])
iex> Validixir.override_messages(failure, :additional_message)
%Validixir.Failure{
    errors: [
        %Validixir.Error{candidate: 1, message: :additional_message, context: Context},
        %Validixir.Error{candidate: 2, message: :additional_message, context: Context}
    ]
}

Takes a value and lifts it in a validation result, returning a success with the value as its candidate.

examples

Examples

iex> Validixir.pure(12)
%Validixir.Success{candidate: 12}

This function applies a function wrapped in a validation success to the candidate of a validation success. If both validation results are failures it returns them combined. If only the first one is a failure, this failure is returned unchanged.

This function is key in implementing applicatives.

examples

Examples

iex> s1 = Validixir.Success.make(fn a -> a + 1 end)
iex> s2 = Validixir.Success.make(0)
iex> Validixir.seq(s1, s2)
%Validixir.Success{candidate: 1}

iex> error = Validixir.Error.make(:hello, "not allowed", nil)
iex> failure = Validixir.Failure.make([error])
iex> success = Validixir.Success.make(1)
iex> Validixir.seq(failure, success)
%Validixir.Failure{errors: [error]}

iex> error1 = Validixir.Error.make(:hello, "not allowed", nil)
iex> error2 = Validixir.Error.make(:world, "not allowed", nil)
iex> failure1 = Validixir.Failure.make([error1])
iex> failure2 = Validixir.Failure.make([error2])
iex> Validixir.seq(failure1, failure2)
%Validixir.Failure{errors: [error1, error2]}

Takes a list of validation results and returns a validation success containing list of all candidates, if all validation results are successes. Else all failures are combined and a validation failure is returned.

examples

Examples

iex> Validixir.sequence([Validixir.Success.make(1), Validixir.Success.make(2)])
%Validixir.Success{candidate: [1,2]}

iex> error1 = Validixir.Error.make(:hello, "not allowed", nil)
iex> error2 = Validixir.Error.make(:world, "not allowed", nil)
iex> failure1 = Validixir.Failure.make([error1])
iex> failure2 = Validixir.Failure.make([error2])
iex> Validixir.sequence([failure1, failure2])
%Validixir.Failure{errors: [error1, error2]}
Link to this function

sequence_of(candidates, validation_f)

Does the same as Validixir.sequence/1 but applies a validation function to all candidates first. Takes an optional context to augment the results, including the index. Uses :seq if none is given.

examples

Examples

iex> success_fn = fn c -> Validixir.Success.make(c) end
iex> Validixir.sequence_of([1, 2], success_fn)
%Validixir.Success{candidate: [1,2]}

iex> failure_fn = fn c -> [Validixir.Error.make(c, "not allowed", nil)] |> Validixir.Failure.make() end
iex> Validixir.sequence_of([:hello, :world], failure_fn)
%Validixir.Failure{
    errors: [Validixir.Error.make(:hello, {{:index, 0}, "not allowed"}, nil),
             Validixir.Error.make(:world, {{:index, 1}, "not allowed"}, nil)]}
Link to this function

validate(result_f, validations)

@spec validate(function(), [validation_result_t(any())]) :: validation_result_t(any())

Takes a function that is called iff all validation results are Successes. The call parameters are then the candidates in the respective order. Returns a validation success then, with the candidate being the return value of this function. If there is at least one failure, errors get accumulated and a validation failure is returned.

examples

Examples

iex> Validixir.validate(fn a, b -> {a, b} end, [Validixir.Success.make(1), Validixir.Success.make(2)])
%Validixir.Success{candidate: {1,2}}

iex> error1 = Validixir.Error.make(:hello, "not allowed", nil)
iex> error2 = Validixir.Error.make(:world, "not allowed", nil)
iex> failure1 = Validixir.Failure.make([error1])
iex> failure2 = Validixir.Failure.make([error2])
iex> Validixir.validate(fn a, b -> {a, b} end, [failure1, failure2])
%Validixir.Failure{errors: [error1, error2]}
Link to this function

validate_all(validation_fs, candidate)

Applies a list of validation functions to a candidate. Returns a success containing the candidate if each validation function returns a success. Else returns a validation failure containing errors of each failed validation.

Takes an optional context as in Validixir.sequence_of/3.

examples

Examples

iex> success_fn_1 = fn c -> Validixir.Success.make(c) end
iex> success_fn_2 = fn _ -> Validixir.Success.make(12) end
iex> Validixir.validate_all([success_fn_1, success_fn_2], 1)
%Validixir.Success{candidate: 1}

iex> failure_fn = fn c -> [Validixir.Error.make(c, "not allowed", nil)] |> Validixir.Failure.make() end
iex> success_fn = fn _ -> Validixir.Success.make(12) end
iex> Validixir.validate_all([failure_fn, success_fn], :hello)
%Validixir.Failure{errors: [Validixir.Error.make(:hello, {{:index, 0}, "not allowed"}, nil)]}
Link to this function

validation_result?(thing)

@spec validation_result?(any()) :: boolean()

Returns true if a value is either a [[Validixir.Success]] or a [[Validixir.Failure]], returns false else.

examples

Examples

iex> Validixir.validation_result?(Validixir.Success.make(12))
true

iex> Validixir.validation_result?(Validixir.Failure.make([]))
true

iex> Validixir.validation_result?(%{})
false