Elixir Code Generation

paradox generate --elixir [--path PATH]

Product Types

Input:

type Person
  name: Text
  age: Integer
  admin: Boolean

Output:

defmodule Dox.Product do
  @moduledoc false

  defmodule Person do
    @type t :: %__MODULE__{
      name: String.t(),
      age: integer(),
      admin: boolean(),
    }

    defstruct [:name, :age, :admin]
  end

  def from_json_person(json) when is_map(json) do
    %Person{
      name: Map.get(json, "name"),
      age: Map.get(json, "age"),
      admin: Map.get(json, "admin"),
    }
  end

  def to_json_person(%Person{} = s) do
    %{
      "name" => s.name,
      "age" => s.age,
      "admin" => s.admin,
    }
  end
end

Products become Elixir structs with typespecs. JSON serialization functions are generated for each type.

Validators

def valid_person(x) do
  field_errors = []
  field_errors = if not is_binary(x.name),
    do: field_errors ++ ["field `name` must be String.t()"],
    else: field_errors
  field_errors = if not is_integer(x.age),
    do: field_errors ++ ["field `age` must be integer()"],
    else: field_errors
  errors = field_errors ++ Enum.filter([], &(&1 != nil))
  if errors == [], do: {:ok, x}, else: {:error, Enum.join(errors, "; ")}
end

def valid_person?(x) do
  match?({:ok, _}, valid_person(x))
end

Validators return {:ok, value} or {:error, message} tuples.

Module Naming

Source file product.dox generates module Dox.Product with inner modules for each type.