defmodule Archeometer.Query.Term.Container do
@moduledoc """
Utility functions for dealing with "container" AST. That is, tuples, list,
keyword list and maps.
Some examples of valid containers
["regular", "lists"]
[keyword: "lists"]
{"simple", "tuples"}
%{map: "values"}
The only restriction for containers is that they can't be nested.
"""
@doc """
Wrapper to work with the AST of container terms (i.e. tuples, maps and lists).
"""
def reduce(ast, init_value, fun)
# why do 2-tuples have a different AST?
def reduce({expr1, expr2}, init, fun),
do: reduce({:{}, [], [expr1, expr2]}, init, fun)
def reduce({:{}, _meta, args}, init, fun),
do: Enum.reduce(args, init, fun)
def reduce({:%{}, _meta, args}, init, fun) do
if Keyword.keyword?(args) do
Enum.reduce(args, init, fun)
else
{:error, {:invalid_keys, args}}
end
end
def reduce(exprs, init, fun) when is_list(exprs),
do: Enum.reduce(exprs, init, fun)
def reduce(expr, init, fun),
do: reduce({:{}, [], [expr]}, init, fun)
end