Build StatusCoverage Status

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

Edantic

Edantic 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:


import Edantic

{: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"
}

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

error
|> Edantic.CastError.format()
|> IO.puts()
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.

License

This software is licensed under MIT License.