lib/ecto/atom.ex

# Copyright (c) 2021 Anand Panchapakesan
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT

defmodule Ecto.Atom do
  @moduledoc """
  An Ecto type for ULID (Universally Unique Lexicographically Sortable Identifier) bitstring.
  This format is binary compatible with UUID, but also provides lexicographic sorting
  capability. The spec for ULID can be found [here](https://github.com/ulid/spec)
  """
  use Ecto.Type

  @doc """
  `c:Ecto.Type.type/0` callback implementation

  ## Examples
      iex> type()
      :string
  """
  @impl Ecto.Type
  @spec type() :: :string
  def type, do: :string

  @doc """
  `c:Ecto.Type.embed_as/1` callback implementation

  ## Examples
      iex> embed_as(:any)
      :self
  """
  @impl Ecto.Type
  @spec embed_as(atom()) :: :self
  def embed_as(_), do: :self

  @doc """
  `c:Ecto.Type.equal?/2` callback implementation
  """
  @impl Ecto.Type
  @spec equal?(t1, t2) :: boolean() when t1: binary() | atom(), t2: t1
  def equal?(t1, t2) when is_binary(t1) and is_binary(t2), do: t1 === t2
  def equal?(t1, t2) when is_atom(t1) and is_atom(t2), do: t1 === t2
  def equal?(_, _), do: false

  @doc """
  `c:Ecto.Type.dump/1` callback implementation
  """
  @impl Ecto.Type
  @spec dump(atom()) :: {:ok, binary()} | :error
  def dump(value) when is_atom(value), do: {:ok, value |> Atom.to_string()}
  def dump(_), do: :error

  @doc """
  `c:Ecto.Type.load/1` callback implementation
  """
  @impl Ecto.Type
  @spec load(binary()) :: {:ok, atom()}
  def load(bin), do: {:ok, bin |> String.to_existing_atom()}

  @doc """
  `c:Ecto.Type.cast/1` callback implementation
  """
  @impl Ecto.Type
  @spec cast(atom()) :: {:ok, atom()} | :error
  def cast(value) when is_atom(value), do: {:ok, value}
  def cast(_), do: :error
end