Check any struct against multiple valid and invalid state definitions.
This library is a lightweight alternative to using Ecto Changesets or other more involved libraries, when all you want is to validate whether a struct is within acceptable parameters, and keep the definition of "what is acceptable" in the same place where the struct is defined.
I originally envisioned this as being a quick way to define an API for a bounded context within an app, to validate what is passed in from other contexts.
Add use Schrodinger
to any module defining a struct below the defstruct
or schema
blocks. This is necessary for the library to be able to read the struct definition.
defmodule Parameters do
defstruct [:name, :email, :content]
# This could also be an Ecto Schema
use Schrodinger
end
Next, add at least one @valid_state
module attribute, and zero or more @invalid_state
module attributes to that same module. It is a tuple where the first parameter is an atom identifying the name of the state and the second is a map of the parameter validations.
@email_regex ~r/^[A-Za-z0-9._%+-+']+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/
@valid_state {:contact_form, %{email: [presence: true, format: @email_regex], content: [presence: true, type: :string]}}
@valid_state {:anonymous_comment, %{content: [presence: true, type: :string]}}
@invalid_state {:name_without_email, %{name: [presence: true], email: [presence: false]}}
And then you can query if the struct is valid
iex(1)> Parameters.valid?(%Parameters{email: "test@test.com", content: "THIS IS CONTENT"})
true
For a struct to be valid, it must match at least one valid state and match none of the invalid states.
valid?/1
returns true / falsevalid?/2
returns true / false, the second argument is an atom or list of atoms which define which valid states can be checked. There is no filtering of invalid states. This "tightens" the rules.validate/1
returns{:ok, struct}
or{:error, Schrodinger.Validation{}}
validate/2
has the same return values and can be passed a state atom or a list of states just likevalid?/2
validate!/1
returnsstruct
or raises aSchrodinger.ValidationError{}
validate!/2
has same arguments asvalid?/2
Validation options are keyword lists, the following options are available:
presence: BOOLEAN
- BOOLEAN can be true or false. Only a nil value or missing key is considered 'absent'
inclusion: [LIST OF ITEMS]
exclusion: [LIST OF ITEMS]
format: [REGEX]
- This will also check that the value is present and that it is a string
type: TYPE
- TYPE can be one of :atom, :string, :integer, :boolean, :list, :map, :number, :struct
- atoms do not include true, false, and nil
- a struct is a map, but a map is not a struct
This library can be installed by adding schrodinger
to your list of dependencies in mix.exs
. It has no dependencies.
def deps do
[
{:schrodinger, "~> 0.1.0"}
]
end