SimpleEnum (svelixir v0.11.0)

Copy Markdown

SimpleEnum is a simple library that implements Enumerations in Elixir.

An Enumeration is a user-defined type that consists of a set of several named constants that are known as Enumerators.
The purpose of SimpleEnum is to provide an equivalent for the Elixir language.

SimpleEnum is:

  • fast: being based on a macro system, access to the Enum will be resolved at compile time when it is possible (see. Fast vs Slow access)
  • simple: the use of the library has been designed to be as simple as possible for a developer to use. In addition to providing Enums, it automatically defines their types, helpers and guards.

Installation

The package can be installed by adding simple_enum to your list of dependencies in mix.exs:

# my_app/mix.exs
def deps do
  [
    {:simple_enum, "~> 1.0"}
  ]
end

Then, update your dependencies:

$ mix deps.get

Optionally, if you use the formatter, add this line to .formatter.exs:

# my_app/.formatter.exs
[
  import_deps: [:simple_enum]
]

Basic Usage

iex> defmodule MyEnums do
...>   import SimpleEnum, only: [defenum: 2]
...>
...>   defenum :color, [:blue, :green, :red]
...>   defenum :day, monday: "MON", tuesday: "TUE", wednesday: "WED"
...> end

iex> require MyEnums

iex> MyEnums.color(:blue)
0
iex> MyEnums.color(0)
:blue
iex> MyEnums.day(:monday)
"MON"
iex> MyEnums.day("MON")
:monday
iex> MyEnums.day("MONN")
** (ArgumentError) invalid value "MONN" for Enum MyEnums.day/1. Expected one of [:monday, :tuesday, :wednesday, "MON", "TUE", "WED"]

iex> MyEnums.color_keys()
[:blue, :green, :red]
iex> MyEnums.color_values()
[0, 1, 2]
iex> MyEnums.color_enumerators()
[blue: 0, green: 1, red: 2]

iex> MyEnums.is_color(:blue)
true
iex> MyEnums.is_color(:nope)
false
iex> MyEnums.is_color_key(:blue)
true
iex> MyEnums.is_color_key(0)
false
iex> MyEnums.is_color_value(0)
true
iex> MyEnums.is_color_value(:blue)
false

Summary

Functions

Defines a set of macros to create and access Enumerations.

Functions

defenum(name, opts \\ [], enumerators)

(macro)

Defines a set of macros to create and access Enumerations.

The name of the generated macros and types will be name (which has to be an atom).
The enumerators argument has to be either:

  • A keyword list composed of strings (to create a string-based Enumeration)
  • A keyword list composed of integers (to create an integer-based Enumeration)
  • A list of atoms (to create an integer-based Enumeration)

For more details about string-based Enumeration and integer-based Enumeration, you can check the corresponding guide.

Options

  • :allow_duplicate_keys - when true, allows duplicate keys in the enumerators list. Defaults to false. Note: when duplicates exist, name/1 and name/2 will return the value of the first match (standard Keyword list behavior). name_keys/0 returns deduplicated keys.
  • :allow_duplicate_values - when true, allows duplicate values in the enumerators list. Defaults to false. Note: when duplicates exist, name/1 will return the first matching key for a given value. name_values/0 returns deduplicated values.

The following macros are generated:

  • name/1 for bidirectional key/value lookup
  • name/2 to access a key, a value or its tuple by specifying the return type
  • name_keys/0 to get the list of all keys
  • name_values/0 to get the list of all values
  • name_enumerators/0 to get the keyword list of all enumerators
  • is_name/1 guard to check if a value is a valid key or value
  • is_name_key/1 guard to check if a value is a valid key
  • is_name_value/1 guard to check if a value is a valid value

The following types are generated:

  • @type enum :: :key1 | :key2 | :value1 | :value2

  • @type enum_keys :: :key1 | :key2

  • @type enum_values :: :value1 | :value2

For more details about types you can also check the corresponding guide.

All these macros are public macros (as defined by defmacro/2).

See the "Examples" section for examples on how to use these macros.

Examples

defmodule MyApp.Enums do
  import SimpleEnum, only: [defenum: 2]
  defenum :color, [:blue, :green, :red]
end

In the example above, a set of macros named color but with different arities will be defined to manipulate the underlying Enumeration.

# Import the module to make the color macros locally available
import MyApp.Enums

# Bidirectional key/value lookup
color(:blue)    #=> 0
color(:green)   #=> 1
color(:red)     #=> 2
color(0)        #=> :blue
color(1)        #=> :green
color(2)        #=> :red

# Lookup with explicit return type
color(:red, :key)   #=> :red
color(2, :key)      #=> :red
color(:red, :value) #=> 2
color(2, :value)    #=> 2
color(:red, :tuple) #=> {:red, 2}
color(2, :tuple)    #=> {:red, 2}

Helpers allow inspecting the Enumeration:

color_keys()         #=> [:blue, :green, :red]
color_values()       #=> [0, 1, 2]
color_enumerators()  #=> [blue: 0, green: 1, red: 2]

Guards are also generated to check membership:

is_color(:blue) #=> true
is_color(0)     #=> true
is_color(:nope) #=> false

is_color_key(:blue) #=> true
is_color_key(0)     #=> false

is_color_value(0)     #=> true
is_color_value(:blue) #=> false