Justify (justify v1.2.0)
Justify makes it easy to validate unstructured data.
Inspired heavily by Ecto.Changeset, Justify allows you to pipe a plain map into a series of validation functions using a simple and familiar API. No schemas or casting required.
Example
dataset =
%{email: "madebyanthony"}
|> Justify.validate_required(:email)
|> Justify.validate_format(:email, ~r/S+@S+/)
dataset.errors #=> [email: {"has invalid format", validation: :format}]
dataset.valid? #=> false
Each validation function will return a Justify.Dataset
struct which can be
passed into the next function. If a validation error is encountered the dataset
will be marked as invalid and an error will be added to the struct.
Custom Validations
You can provide your own custom validations using the Justify.add_error/4
function.
Example
defmodule MyValidator do
def validate_color(data, field, color) do
dataset = Justify.Dataset.new(data)
value = Map.get(dataset.data, :field)
if value == color do
dataset
else
Justify.add_error(dataset, field, "wrong color", validation: :color)
end
end
end
Your custom validation can be used as part of a validation pipeline.
Example
dataset =
%{color: "brown"}
|> Justify.validation_required(:color)
|> MyValidator.validate_color(:color, "green")
dataset.errors #=> [color: {"wrong color", validation: :color}]
dataset.valid? #=> false
Supported Validations
Link to this section Summary
Functions
Adds an error to the dataset.
Validates the given field has a value of true
.
Validates the value of a given field matches it's confirmation field.
Applies a validator function to a field containing an embedded value.
Validates the value for the given field is not contained within the provided enumerable.
Validates the value of the given field matches the provided format.
Validates the value for the given field is contained within the provided enumerable.
Validates the length of a string or list.
Validates that one or more fields has a value.
Validates that the value of a field is a specific type.
Link to this section Types
type_t()
Specs
type_t() :: :boolean | :float | :integer | :non_neg_integer | :pos_integer | :string
Link to this section Functions
add_error(dataset, field, message, keys \\ [])
Specs
add_error(Justify.Dataset.t(), atom(), String.t(), Keyword.t()) :: Justify.Dataset.t()
Adds an error to the dataset.
An optional keyword list can be used to provide additional contextual information about the error.
validate_acceptance(dataset, field, opts \\ [])
Specs
validate_acceptance(map(), atom(), Keyword.t()) :: Justify.Dataset.t()
Validates the given field has a value of true
.
Options
:message
- error message, defaults to "must be accepted"
validate_confirmation(dataset, field, opts \\ [])
Specs
validate_confirmation(map(), atom(), Keyword.t()) :: Justify.Dataset.t()
Validates the value of a given field matches it's confirmation field.
By default, the field will be checked against a field with the same name
but appended with _confirmation
. It’s possible to provide a custom field by
providing a value to the :confirmation_field
option.
Note that if the confirmation field is nil
or missing, by default, an error
will not be added. You can specify that the confirmation field is required in
the options (see below).
Options
:confirmation_field
- name of the field to validate against:message
- error message, defaults to "does not match":required?
- whether the confirmation field must contain a value
validate_embed(dataset, field, validator)
Specs
validate_embed(map(), atom(), (... -> any())) :: Justify.Dataset.t()
Applies a validator function to a field containing an embedded value.
An embedded value can be either a map or a list of maps.
Example
validator = fn(metadata) -> Justify.validate_required(metadata, :key) end
data = %{metadata: [%{value: "a value"}]}
validate_embed(data, :metadata, validator)
#> %Justify.Dataset{errors: [metadata: [[key: {"can't be blank", validation: :required}]]], valid?: false}
validate_exclusion(dataset, field, enum, opts \\ [])
Specs
validate_exclusion(map(), atom(), Enum.t(), Keyword.t()) :: Justify.Dataset.t()
Validates the value for the given field is not contained within the provided enumerable.
Options
:message
- error message, defaults to "is reserved"
validate_format(dataset, field, format, opts \\ [])
Specs
validate_format(map(), atom(), Regex.t(), Keyword.t()) :: Justify.Dataset.t()
Validates the value of the given field matches the provided format.
Options
:message
- error message, defaults to "has invalid format"
validate_inclusion(dataset, field, enum, opts \\ [])
Specs
validate_inclusion(map(), atom(), Enum.t(), Keyword.t()) :: Justify.Dataset.t()
Validates the value for the given field is contained within the provided enumerable.
Options
:message
- error message, defaults to "is invalid"
validate_length(dataset, field, opts)
Specs
validate_length(map(), atom(), Keyword.t()) :: Justify.Dataset.t()
Validates the length of a string or list.
Options
:count
- how to calculate the length of a string. Must be one of`:codepoints`, `:graphemes` or `:bytes`. Defaults to `:graphemes`.
:is
- the exact length match:min
- match a length greater than or equal to:max
- match a length less than or equal to:message
- error message, defaults to one of the following variants:- for strings
- “should be %{count} character(s)”
- “should be at least %{count} character(s)”
- “should be at most %{count} character(s)”
- for binary
- “should be %{count} byte(s)”
- “should be at least %{count} byte(s)”
- “should be at most %{count} byte(s)”
- for lists
- “should have %{count} item(s)”
- “should have at least %{count} item(s)”
- “should have at most %{count} item(s)”
- for strings
validate_required(dataset, fields, opts \\ [])
Specs
validate_required(map(), atom() | [atom()], Keyword.t()) :: Justify.Dataset.t()
Validates that one or more fields has a value.
Options
:message
- error message, defaults to "must be accepted":trim?
- remove whitespace before validating, defaults totrue
validate_type(dataset, field, type, opts \\ [])
Specs
validate_type(map(), atom(), type_t(), Keyword.t()) :: Justify.Dataset.t()
Validates that the value of a field is a specific type.
Supported types:
:boolean
:float
:integer
:non_neg_integer
:pos_integer
:string
Options
:message
- error message, defaults to "has invalid type"