Enumerations are common abstraction to express the limited set of values. In Elixir language enumeration values are usually expressed as atoms. &GenEnum.defenum/1 macro generates compile/runtime utilities for given enumeration. Argument is
- non empty list of enum values (atoms), example: [:LINUX, :MAC, :WINDOWS]
- OR keyword list of options
:module
is Elixir module name (main module of enumeration definition) - can benil
/unset, example: OS:database_type
is atom (alias for database type for given enum) - can benil
/unset, example: :os:values
is non empty list of enum values (atoms), example: [:LINUX, :MAC, :WINDOWS]
The package can be installed
by adding gen_enum
to your list of dependencies in mix.exs
:
def deps do
[
{:gen_enum, "~> 0.3"}
]
end
Let's use &GenEnum.defenum/1 macro and generate OS enumeration:
require GenEnum
GenEnum.defenum(module: OS, database_type: :os, values: [:LINUX, :MAC, :WINDOWS])
Under OS module namespace this expression generates 4 additional modules:
Module contains standard EctoEnum definition of given enumeration. Can be used for Ecto integration and database migrations (read EctoEnum manual). If :database_type
is nil
/unset then this module will not be generated.
Module contains macro wrappers for the every value of given enum. It's recommended to use macro wrappers instead of the atom literals to avoid runtime errors (for example, after refactoring)
iex> require OS.Items
OS.Items
iex> OS.Items.linux
:LINUX
iex> OS.Items.mac
:MAC
Module contains @type t definition for enumeration and macro helpers for guards, Ecto migrations and any other places where those macros are useful
iex> require OS.Meta
OS.Meta
- OS.Meta.t definition is useful for @type and @specs notations
defmodule Game do
require OS.Items
@spec choose_os(pos_integer) :: OS.Meta.t
def choose_os(min_fps) when (min_fps <= 30), do: OS.Items.linux
def choose_os(min_fps) when (min_fps <= 60), do: OS.Items.mac
def choose_os(_), do: OS.Items.windows
end
- database_type macro wrapper for database type of enum in Ecto migrations. If
:database_type
argument isnil
/unset then this macro will not be generated.
iex> OS.Meta.database_type
:os
- values list of all possible enumeration values
iex> OS.Meta.values
[:LINUX, :MAC, :WINDOWS]
- is_type useful macro for guard expressions
iex> OS.Meta.is_type OS.Items.mac
true
iex> OS.Meta.is_type :HELLO
false
Module contains some helper functions
- to_enum and to_enum! are polymorphic functions to convert term into enumeration value (if it is possible)
iex> OS.Utils.to_enum :mac
{:ok, :MAC}
iex> OS.Utils.to_enum "mac"
{:ok, :MAC}
iex> OS.Utils.to_enum "Mac\n"
{:ok, :MAC}
iex> OS.Utils.to_enum "MacOs"
{:error, "can not convert value to Elixir.OS, got invalid string from: \"MacOs\""}
iex> OS.Utils.to_enum! :mac
:MAC
iex> OS.Utils.to_enum! "mac"
:MAC
iex> OS.Utils.to_enum! "Mac\n"
:MAC
iex> OS.Utils.to_enum! "MacOs"
** (RuntimeError) can not convert value to Elixir.OS, got invalid string from: "MacOs"
iex:4: OS.Utils.to_enum!/1
iex> OS.Utils.values
[:LINUX, :MAC, :WINDOWS]