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