Skip to main content

lib/quack_db/source_ref.ex

defmodule QuackDB.SourceRef do
  @moduledoc false

  @type t :: module() | atom() | String.t() | {atom() | String.t(), atom() | String.t()}

  @spec name(t()) :: String.t()
  def name({prefix, source}), do: Enum.map_join([prefix, source], ".", &part/1)

  def name(source) when is_atom(source) do
    if Code.ensure_loaded?(source) and function_exported?(source, :__schema__, 1) do
      schema_name(source)
    else
      Atom.to_string(source)
    end
  end

  def name(source) when is_binary(source), do: source

  defp schema_name(schema) do
    case apply(schema, :__schema__, [:prefix]) do
      nil -> apply(schema, :__schema__, [:source])
      prefix -> name({prefix, apply(schema, :__schema__, [:source])})
    end
  rescue
    FunctionClauseError -> apply(schema, :__schema__, [:source])
  end

  defp part(value) when is_atom(value), do: Atom.to_string(value)
  defp part(value) when is_binary(value), do: value
end