lib/zig/type/enum.ex

defmodule Zig.Type.Enum do
  use Zig.Type

  defstruct [:tags, :name]
  @type t :: %__MODULE__{tags: %{optional(atom) => String.t()}, name: String.t()}

  def from_json(%{"tags" => tags, "name" => name}, module) do
    %__MODULE__{
      tags: Map.new(tags, fn {key, val} -> {String.to_atom(key), val} end),
      name: String.trim_leading(name, ".#{module}.")
    }
  end

  def to_string(enum), do: enum.name

  def to_call(enum), do: "nif." <> enum.name

  def inspect(enum, opts) do
    ~s(%Zig.Type.Enum{name: "#{enum.name}", tags: #{Kernel.inspect(enum.tags, opts)}})
  end

  def return_allowed?(_), do: true

  def spec(%{tags: tags}, _, _opts) do
    tags
    |> Map.keys()
    |> Enum.sort()
    |> Enum.reverse()
    |> Enum.reduce(fn a, b ->
      quote do
        unquote(a) | unquote(b)
      end
    end)
  end
end