Validixir (validixir v0.1.1)
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
validate_all_return_t(inner_t)
@type validate_all_return_t(inner_t) :: {:ok, validation_result_t(inner_t)} | {:error, :no_validators}
validation_fun_t(result_t)
@type validation_fun_t(result_t) :: (any() -> validation_result_t(result_t))
validation_result_t(inner_t)
@type validation_result_t(inner_t) :: Validixir.Failure.t() | Validixir.Success.t(inner_t)
Link to this section Functions
and_then(validation_result, f)
@spec and_then( validation_result_t(Validixir.Success.some_inner_t()), (Validixir.Success.some_inner_t() -> validation_result_t(any())) ) :: validation_result_t(any())
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: []}
augment_contexts(s, additional_context)
@spec augment_contexts(validation_result_t(Validixir.Success.some_inner_t()), any()) :: validation_result_t(Validixir.Success.some_inner_t())
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}},
]
}
augment_messages(s, additional_message)
@spec augment_messages(validation_result_t(Validixir.Success.some_inner_t()), any()) :: validation_result_t(Validixir.Success.some_inner_t())
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}
]
}
map(f, f_success, f_failure)
@spec map( validation_result_t(Validixir.Success.some_inner_t()), (Validixir.Success.some_inner_t() -> any()), (Validixir.Error.t() -> Validixir.Error.t()) ) :: validation_result_t(any())
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)]}
map_failure(failure, f)
@spec map_failure( validation_result_t(Validixir.Success.some_inner_t()), (Validixir.Error.t() -> Validixir.Error.t()) ) :: validation_result_t(Validixir.Success.some_inner_t())
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)]}
map_success(success, f)
@spec map_success( validation_result_t(Validixir.Success.some_inner_t()), (Validixir.Success.some_inner_t() -> any()) ) :: validation_result_t(any())
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: []}
override_contexts(s, context)
@spec override_contexts(validation_result_t(Validixir.Success.some_inner_t()), any()) :: validation_result_t(Validixir.Success.some_inner_t())
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}
]
}
override_messages(s, message)
@spec override_messages(validation_result_t(Validixir.Success.some_inner_t()), any()) :: validation_result_t(Validixir.Success.some_inner_t())
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}
]
}
pure(value)
@spec pure(Validixir.Success.some_inner_t()) :: Validixir.Success.t(Validixir.Success.some_inner_t())
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}
seq(f1, f2)
@spec seq( validation_result_t((Validixir.Success.some_inner_t() -> any())), validation_result_t(Validixir.Success.some_inner_t()) ) :: validation_result_t(any())
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]}
sequence(list)
@spec sequence([validation_result_t(Validixir.Success.some_inner_t())]) :: validation_result_t([Validixir.Success.some_inner_t()])
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]}
sequence_of(candidates, validation_f)
@spec sequence_of([any()], validation_fun_t(Validixir.Success.some_inner_t())) :: validation_result_t(Validixir.Success.some_inner_t())
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)]}
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]}
validate_all(validation_fs, candidate)
@spec validate_all([validation_fun_t(Validixir.Success.some_inner_t())], any()) :: validate_all_return_t(Validixir.Success.some_inner_t())
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)]}
validation_result?(thing)
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