# Integer-based Enum

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]
