String-based Enum View Source

To define a string-based Enumeration, you can just use a keyword of strings as the enumerator-list.

NOTE: For a string-based Enumeration, every enumerator must have an initializer.

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

Example

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

  # Define String-based Enumeration
  defenum :gender, man: "M", woman: "W", unspecified: "U"

  defstruct [:gender, :first_name, :last_name]

  @type t :: %__MODULE__{
         # We want only keys in our structs...
         gender: gender_keys(),
         first_name: String.t(),
         last_name: String.t()
       }

  def cast(%{gender: gender_value, first_name: first_name, last_name: last_name}) do
    %__MODULE__{
      # ... so let's lookup only the key
      gender: gender(gender_value, :key),
      first_name: first_name,
      last_name: last_name
    }
  end
end

iex> MyApp.Person.cast(%{gender: :man, first_name: "John", last_name: "Doe"})
%MyApp.Person{first_name: "John", gender: :man, last_name: "Doe"}

iex> MyApp.Person.cast(%{gender: "M", first_name: "John", last_name: "Doe"})
%MyApp.Person{first_name: "John", gender: :man, last_name: "Doe"}

iex> MyApp.Person.cast(%{gender: "W", first_name: "Jane", last_name: "Doe"})
%MyApp.Person{first_name: "Jane", gender: :woman, last_name: "Doe"}

iex> MyApp.Person.cast(%{gender: "U", first_name: "", last_name: ""})
%MyApp.Person{first_name: "", gender: :unspecified, last_name: ""}

iex> MyApp.Person.cast(%{gender: "?", first_name: "", last_name: ""})
** (ArgumentError) invalid value "?" for Enum MyApp.Person.gender/2. Expected one of [:man, :woman, :unspecified, "M", "W", "U"]