Skip to content

Latest commit

 

History

History
82 lines (61 loc) · 2.92 KB

README.md

File metadata and controls

82 lines (61 loc) · 2.92 KB

Constructor

An Elixir DSL for defining and validating structs.

Usage

defmodule ConstructorExampleUser do
  use Constructor

  constructor do
    field :id, :integer, constructor: &is_integer/1, enforce: true
    field :role,  :user | :admin, constructor: &is_valid_role/1, enforce: true
    field :first_name, :string, default: "", constructor: &is_string/1
    field :last_name, :string, default: "", constructor: &is_string/1
  end

  def is_valid_role(value) do
    case value do
      :admin -> {:ok, value}
      :user -> {:ok, value}
      _ -> {:error, "invalid role!"}
    end
  end
end

iex> ConstructorExampleUser.new(id: "foo", role: :admin, first_name: 37)
{:error, {:constructor, %{id: "must be an integer", first_name: "must be an integer"}}}

iex> ConstructorExampleUser.new(id: 12, role: :admin, first_name: "Chris")
{:ok, %ConstructorExampleUser{id: 12, first_name: "Chris", last_name: ""}}

iex> ConstructorExampleUser.new!(id: 12, role: :admin, first_name: "Chris")
%ConstructorExampleUser{id: 12, first_name: "Chris", last_name: ""}

Check out the docs to learn more.

Installation

Add constructor to your list of dependencies in mix.exs:

def deps do
  [
    {:constructor, "~> 1.0"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/constructor.

But why?

Before writing the first iteration of this, I was using Vex for projects that didn't have an Ecto dependency, or Ecto.Changeset if I did. It worked, but there were a couple of issues.

  1. Vex has some performance issues that seem difficult to resolve in a way that won't break existing users. More concerning, it seems like Vex is without a clear maintainer.
  2. You can do most of what Constructor does with Ecto.Changesets, but you bring a lot of ORM baggage along with it. Much of it may not be applicable if your project is not using an RDBMS. Constructor provides a richer and more concise way of doing validations and type casting

Acknowledgments

This library was born from the lack of a lightweight and flexible validation library in Elixir. However, the design of the constructor/2 macro and indeed much of the functionality is provided by the excellent TypedStruct library.

Existing TypedStruct users

If you already depend on TypedStruct, you will need to remove that dependency from your mix.exs until the plugin system is released. You can track progress here