Build StatusCoverage Status

<img src="http://funbox.ru/badges/sponsored_by_funbox_compact.svg" alt="Sponsored by FunBox" width=250 />

Edantic

Eduntic is a library for casting «plain» JSON-originated data into Elixir data structures with nessesary validations.

Example

Assume there is a module with a corresponding struct:

defmodule Person do
  defstruct [
    :age, :name, :department
  ]

  @type first_name() :: String.t
  @type second_name() :: String.t

  @type t :: %__MODULE__{
    age: non_neg_integer(),
    name: {first_name(), second_name()},
    department: :finance | :it
  }
end

And there is some JSON-originated data:

data = %{
  "age" => 23,
  "name" => ["girolamo", "savonarola"],
  "department" => "it"
}

With Edantic we can simultaneously validate this data and convert it into Elixir structures:


{:ok, person} = Edantic.cast(Person, :t, data)

person == %Person{
  age: 23,
  name: {"girolamo", "savonarola"},
  department: :it
}
data_bad_department = %{
  "age" => 23,
  "name" => ["girolamo", "savonarola"],
  "department" => "unknown"
}

assert {:error, error} = Edantic.cast(Person, :t, data_bad_department)

IO.puts(Edantic.CastError.format(error))
key-value pair does not match to any of the specified for the map
  data: %{"department" => "unknown"}
  type: %Edantic.Support.Types.Person{age: non_neg_integer(), department: :finance | :it, name: {first_name(), second_name()}}}

JSON

By «JSON-originated data» is denoted all the data matching the following type t:

@type key :: String.t
@type value :: String.t | nil | boolean | integer | float | %{optional(key) => value} | [value]
@type t :: value

Primitive convertions

Since plain data structures are rather poor, there are some automatic enrichments allowed while casting:

Usage in releases

Since type info is located in seperate beam chunks which are stripped by default, be sure your releases do not strip them.

For example, by setting strip_beams option to false.

  def project do
    [
      ...
      deps: deps(),
      releases: [
        release_name: [
          strip_beams: false,
          ...
        ]
      ]
    ]
  end

Installation

If available in Hex, the package can be installed by adding edantic to your list of dependencies in mix.exs:

def deps do
  [
    {:edantic, "~> 0.1.0"}
  ]
end

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