Skip to content
Better enumerations support for Elixir and Ecto
Elixir Shell
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci
bench
config
lib
priv
scripts
test
.credo.exs
.dialyzer_ignore
.editorconfig
.formatter.exs
.gitignore
CHANGELOG.md
README.md
VERSION
coveralls.json
mix.exs
mix.lock

README.md

GenEnum

Hex Documentation

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 be nil/unset, example: OS
    • :database_type is atom (alias for database type for given enum) - can be nil/unset, example: :os
    • :values is non empty list of enum values (atoms), example: [:LINUX, :MAC, :WINDOWS]

Installation

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

Example

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:

1) OS.EctoEnum

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.

2) OS.Items

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

3) OS.Meta

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 is nil/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

4) OS.Utils

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]
You can’t perform that action at this time.