1defmodule Protobuf.DefineEnum do
2  @moduledoc false
3
4  @doc """
5  Defines a new module which contains two functions, atom(value) and value(atom), for
6  getting either the name or value of an enumeration value.
7  """
8  def def_enum(name, values, [inject: inject, doc: doc]) do
9    enum_atoms = Enum.map values, fn {a, _} -> a end
10    enum_values = Enum.map values, fn {_, v} -> v end
11    contents = for {atom, value} <- values do
12      quote do
13        def value(unquote(atom)), do: unquote(value)
14        def atom(unquote(value)), do: unquote(atom)
15      end
16    end
17    contents = contents ++ [
18      quote do
19        def values, do: unquote(enum_values)
20        def atoms, do: unquote(enum_atoms)
21      end
22    ]
23    if inject do
24      quote do
25        unquote(contents)
26        def value(_), do: nil
27        def atom(_),  do: nil
28      end
29    else
30      quote do
31        defmodule unquote(name) do
32          @moduledoc false
33          unquote(Protobuf.Config.doc_quote(doc))
34          unquote(contents)
35          def value(_), do: nil
36          def atom(_), do: nil
37        end
38      end
39    end
40  end
41
42end
43