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]