defmodule Ecto.ShortUUID do
alias Ecto.UUID
@moduledoc """
An Ecto type for Short UUID strings.
"""
@behaviour Ecto.Type
@typedoc """
A hex-encoded UUID string.
"""
@type uuid :: <<_::288>>
@typedoc """
A base57 ShortUUID string.
"""
@type shortuuid57 :: <<_::176>>
@typedoc """
A raw binary representation of a UUID.
"""
@type raw :: <<_::128>>
@doc """
The Ecto type.
"""
def type, do: :uuid
@doc """
Casts the given input to ShortUUID
https://hexdocs.pm/ecto/Ecto.Type.html#c:cast/1
"""
@spec cast(shortuuid57 | uuid | any) :: {:ok, shortuuid57} | :error
def cast(<<_::176>> = shortuuid) when is_binary(shortuuid) do
case ShortUUID.decode(shortuuid) do
{:ok, _} -> {:ok, shortuuid}
{:error, _} -> :error
end
end
def cast(<<_::288>> = uuid) do
case UUID.cast(uuid) do
:error -> :error
{:ok, casted} -> ShortUUID.encode(casted)
end
end
def cast(_), do: :error
@doc """
Loads a binary UUID into a ShortUUID string.
https://hexdocs.pm/ecto/Ecto.Type.html#c:load/1
"""
@spec load(binary) :: {:ok, binary} | :error
def load(uuid) do
case UUID.load(uuid) do
{:ok, uuid} -> ShortUUID.encode(uuid)
_ -> :error
end
end
@doc """
Dumps the given string representing a ShortUUID or UUID into a binary.
https://hexdocs.pm/ecto/Ecto.Type.html#c:dump/1
"""
@spec dump(shortuuid57 | uuid | any) :: {:ok, raw} | :error
def dump(<<_::288>> = uuid), do: Ecto.UUID.dump(uuid)
def dump(<<_::176>> = shortuuid) do
with {:ok, uuid} <- ShortUUID.decode(shortuuid),
{:ok, binary_uuid} <- Ecto.UUID.dump(uuid) do
{:ok, binary_uuid}
else
_ -> :error
end
end
def dump(_), do: :error
@doc """
Ecto v3 callback
Dictates how the type should be treated inside embeds.
https://hexdocs.pm/ecto/Ecto.Type.html#c:embed_as/1
"""
def embed_as(_), do: :self
@doc """
Ecto v3 callback
Checks if two terms are semantically equal.
https://hexdocs.pm/ecto/Ecto.Type.html#c:equal?/2
"""
def equal?(term1, term2), do: term1 == term2
@doc """
Generates a ShortUUID string based on a version 4 (random) UUID.
"""
# @spec generate() :: t
def generate do
{:ok, shortuuid} =
UUID.generate()
|> ShortUUID.encode()
shortuuid
end
# Callback invoked by autogenerate fields.
@doc false
def autogenerate, do: generate()
end