Integer-based Enum View Source

There are 2 ways to define an enumerator for integer-based Enumerations:

  • Without specifying a default value
  • With a defaut value

Without default value

If the first enumerator does not have an initializer, the associated value is zero. For any other enumerator whose definition does not have an initializer, the associated value is the value of the previous enumerator plus one.

...>
iex> defenum :color, [:blue, :green, :red]
...>
iex> color(:blue, :value)
0
iex> color(:green, :value)
1
iex> color(:red, :value)
2

With default value

When enumerators have values assigned SimpleEnum will simply use them.

...>
iex> defenum :color, [blue: 1, green: 2, red: 4]
...>
iex> color(:blue, :value)
1
iex> color(:green, :value)
2
iex> color(:red, :value)
4

It is of course possible to mix both ways:

...>
iex> defenum :role, [:default, {:support, 10}, :moderator, {:admin, 999}]
...>
iex> role(:default, :value)
0
iex> role(:support, :value)
10
iex> role(:moderator, :value)
11
iex> role(:admin, :value)
999

For more details about macros generated by SimpleEnum.defenum/2, feels free to check it's documentation.

Example

Let's see a more complete example.

# lib/my_app/account.ex
defmodule MyApp.Account do
  import SimpleEnum, only: [defenum: 2]

  # Define Integer-based Enumeration
  defenum :type, [:user, :admin, banned: -1]

  defstruct [:type, :username]

  @type t :: %__MODULE__{
         # We want only keys in our structs...
         type: type_keys(),
         username: String.t()
       }

  def cast(%{type: type_value, username: username}) do
    %__MODULE__{
      # ... so let's lookup only the key
      type: type(type_value, :key),
      username: username
    }
  end
end

iex> MyApp.Account.cast(%{type: :user, username: "John Doe"})
%MyApp.Account{type: :user, username: "John Doe"}

iex> MyApp.Account.cast(%{type: 0, username: "John Doe"})
%MyApp.Account{type: :user, username: "John Doe"}

iex> MyApp.Account.cast(%{type: 1, username: "John Admin"})
%MyApp.Account{type: :admin, username: "John Admin"}

iex> MyApp.Account.cast(%{type: -1, username: "John Banned"})
%MyApp.Account{type: :banned, username: "John Banned"}

iex> MyApp.Account.cast(%{type: 999, username: "John Invalid"})
** (ArgumentError) invalid value 999 for Enum MyApp.Account.type/2. Expected one of [:user, :admin, :banned, 0, 1, -1]