Current section
Files
Jump to
Current section
Files
lib/query.ex
defmodule Cognac.Query do
@moduledoc false
alias Cognac.QueryArgument
# Pretty print delimiters
@closing %{true: "}\n", false: ?}}
@opening %{true: " {\n", false: ?{}
@separator %{true: "\n", false: " "}
def build(query, options \\ []) do
pretty? =
case options[:pretty] do
nil -> false
pretty? -> pretty?
end
[@opening[pretty?], build_fields(query, 1, pretty?), ?}]
end
defp build_fields(query, level, pretty?) when is_map(query) do
build_fields(Map.to_list(query), level, pretty?)
end
defp build_fields(query, level, pretty?), do: build_fields(query, level, pretty?, [])
defp build_fields([], _level, _pretty?, buffer), do: Enum.reverse(buffer)
defp build_fields([{field, {arguments, sub_fields}} | rest], level, pretty?, buffer) do
field = field |> to_string() |> indent(level, pretty?)
nested_fields = build_fields(sub_fields, level + 1, pretty?)
arguments = QueryArgument.build(arguments, pretty?)
closing = indent(@closing[pretty?], level, pretty?)
buffer = [closing, nested_fields, @opening[pretty?], arguments, field | buffer]
build_fields(rest, level + 1, pretty?, buffer)
end
defp build_fields([{field, sub_fields} | rest], level, pretty?, buffer) do
field = field |> to_string() |> indent(level, pretty?)
nested_fields = build_fields(sub_fields, level + 1, pretty?)
closing = indent(@closing[pretty?], level, pretty?)
buffer = [closing, nested_fields, @opening[pretty?], field | buffer]
build_fields(rest, level + 1, pretty?, buffer)
end
defp build_fields([field], level, pretty?, buffer) do
field = field |> to_string() |> indent(level, pretty?)
field = if pretty?, do: [field, "\n"], else: field
Enum.reverse([field | buffer])
end
defp build_fields([field | rest], level, pretty?, buffer) do
field = field |> to_string() |> indent(level, pretty?)
separator = @separator[pretty?]
build_fields(rest, level, pretty?, [separator, field | buffer])
end
defp indent(iodata, level, true), do: [String.duplicate(" ", level), iodata]
defp indent(iodata, _level, false), do: iodata
end