View Source Parameter.Enum (Parameter v0.14.1)

Enum type represents a group of constants that have a value with an associated key.

Examples

defmodule MyApp.UserParam do
  use Parameter.Schema

  enum Status do
    value :user_online, key: "userOnline"
    value :user_offline, key: "userOffline"
  end

  param do
    field :first_name, :string, key: "firstName"
    field :status, MyApp.UserParam.Status
  end
end

The Status enum should automatically translate the userOnline and userOffline values when loading to the respective atom values.

Parameter.load(MyApp.UserParam, %{"firstName" => "John", "status" => "userOnline"})
{:ok, %{first_name: "John", status: :user_online}}

Parameter.dump(MyApp.UserParam, %{first_name: "John", status: :user_online})
{:ok, %{"firstName" => "John", "status" => "userOnline"}}

Using enum

When you use the enum macro, Parameter creates a module under the hood, injecting under the current module. For this reason, when referencing the enum in a Parameter field, it's required to use the full module name as shown in the examples.

Enum also supports a shorter version if the key and value are already the same:

defmodule MyApp.UserParam do
  ...
  enum Status, values: [:user_online,  :user_offline]
  ...
end

Parameter.load(MyApp.UserParam, %{"firstName" => "John", "status" => "user_online"})
{:ok, %{first_name: "John", status: :user_online}}

Using numbers is also allowed in enums:

enum Status do
  value :active, key: 1
  value :pending_request, key: 2
end

Parameter.load(MyApp.UserParam, %{"status" => 1})
{:ok, %{status: :active}}

It's also possible to create enums in different modules by using the enum/1 macro:

defmodule MyApp.Status do
  import Parameter.Enum

  enum do
    value :user_online, key: "userOnline"
    value :user_offline, key: "userOffline"
  end
end

defmodule MyApp.UserParam do
  use Parameter.Schema
  alias MyApp.Status

  param do
    field :first_name, :string, key: "firstName"
    field :status, Status
  end
end

And the short version:

enum values: [:user_online,  :user_offline]

Dump and validate

Enums can also be used for validate and dump the data. The Parameter.validate/3 function will do strict validation, checking if the value correspond to the enum values, which are internally stored as atoms. Parameter.dump/3 will stringify the enum atom value. By design the Parameter.dump/3 doesn't perform strict validations but for enums, it checks at least if the value exists in the enum definition before dumping.

Consider the following Parameter.Enum implementation:

defmodule Currency do
  use Parameter.Schema
  enum Currencies, values: [:EUR, :USD]

  param do
    field :currency, __MODULE__.Currencies
  end
end

It's possible to check if the value provided it's a valid enum in parameter:

iex> Parameter.validate(Currency, %{currency: :EUR})
:ok
iex> Parameter.validate(Currency, %{currency: :BRL})
{:error, %{currency: "invalid enum type"}}
# Using the string version should also return an error since it's expected enum values to be atoms
iex> Parameter.validate(Currency, %{currency: "EUR"})
{:error, %{currency: "invalid enum type"}}

And for dump the data:

iex> Parameter.dump(Currency, %{currency: :EUR})
{:ok, %{"currency" => "EUR"}}
iex> Parameter.dump(Currency, %{currency: :BRL})
{:error, %{currency: "invalid enum type"}}
# Using the string version should also return an error since it's expected enum values to be atoms
iex> Parameter.dump(Currency, %{currency: "EUR"})
{:error, %{currency: "invalid enum type"}}