defmodule QuackDB.KeyLookup do @moduledoc false @spec fetch(map() | keyword() | nil, atom() | String.t()) :: term() def fetch(nil, _name), do: nil def fetch(row, name) when is_list(row) do if Keyword.keyword?(row), do: keyword_value(row, name) end def fetch(row, name) when is_map(row) do cond do Map.has_key?(row, name) -> Map.fetch!(row, name) is_atom(name) and Map.has_key?(row, to_string(name)) -> Map.fetch!(row, to_string(name)) is_binary(name) -> find_atom_key(row, name) true -> nil end end def fetch(_row, _name), do: nil defp keyword_value(row, name) do cond do is_atom(name) and Keyword.has_key?(row, name) -> Keyword.fetch!(row, name) is_binary(name) -> find_atom_key(row, name) true -> nil end end defp find_atom_key(row, name) do Enum.find_value(row, fn {key, value} when is_atom(key) -> if Atom.to_string(key) == name, do: {:value, value} _entry -> nil end) |> case do {:value, value} -> value nil -> nil end end end