defmodule Archeometer.Repo.Result do
@moduledoc """
A query result with a nicer API to manipulate the data.
"""
defstruct [:headers, :rows]
defimpl String.Chars do
@vsep " |"
@hsep "-"
@vprefix " |"
def to_string(%Archeometer.Repo.Result{headers: headers, rows: rows}) do
widths = widths([headers | rows])
hsep = Enum.map(widths, fn w -> String.duplicate(@hsep, w) end)
[headers, hsep | rows]
|> Enum.map_join(&(@vprefix <> format_row(&1, widths) <> "\n"))
end
defp format_row(row, widths) do
Enum.zip(row, widths)
|> Enum.map_join(fn {r, w} ->
r
|> Kernel.to_string()
|> String.pad_trailing(w)
|> Kernel.<>(@vsep)
end)
end
defp widths(rows) do
rows
|> Enum.zip()
|> Enum.map(fn tpl ->
tpl
|> Tuple.to_list()
|> Enum.map(&(Kernel.to_string(&1) |> String.length()))
|> Enum.max()
end)
end
end
end