Schrodinger
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.
Usage
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"})
trueFor a struct to be valid, it must match at least one valid state and match none of the invalid states.
Public API:
valid?/1returns true / falsevalid?/2returns 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/1returns{:ok, struct}or{:error, Schrodinder.Validation{}}validate/2has the same return values and can be passed a state atom or a list of states just likevalid?/2validate!/1returnsstructor raises aSchrodinder.ValidationError{}validate!/2has same arguments asvalid?/2
Validation Options
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
Installation
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