Skip to main content

lib/chat_code/header.ex

defmodule GW2.ChatCode.Header do
  @moduledoc false

  @type type ::
          :item
          # | :coin
          # | :npc_text
          # | :map
          # | :pvp_game
          # | :skill
          # | :trait
          # | :user
          # | :recipe
          # | :wardrobe
          # | :outfit
          # | :wvw_objective
          # | :build_template
          # | :achievement
          | :wardrobe_template
  # | :travel_template

  @types %{
    # 0x01 => :coin,
    0x02 => :item,
    # 0x03 => :npc_text,
    # 0x04 => :map,
    # 0x05 => :pvp_game,
    # 0x06 => :skill,
    # 0x07 => :trait,
    # 0x08 => :user,
    # 0x09 => :recipe,
    # 0x0A => :wardrobe,
    # 0x0B => :outfit,
    # 0x0C => :wvw_objective,
    # 0x0D => :build_template,
    # 0x0E => :achievement,
    0x0F => :wardrobe_template
    # 0x10 => :travel_template
  }

  @by_type Map.new(@types, fn {code, type} -> {type, code} end)

  @spec encode_type(type()) :: {:ok, binary()} | {:error, :unknown_type}
  def encode_type(type) do
    case Map.fetch(@by_type, type) do
      {:ok, code} ->
        {:ok, <<code::size(8)>>}

      :error ->
        {:error, :unknown_type}
    end
  end

  @spec decode_type(binary()) :: {:ok, {type(), binary()}} | {:error, :unknown_type}
  def decode_type(<<header, rest::binary>>) do
    case Map.fetch(@types, header) do
      {:ok, type} ->
        {:ok, {type, rest}}

      :error ->
        {:error, :unknown_type}
    end
  end

  def decode_type(_), do: {:error, :unknown_type}
end