defmodule QuackDB.Inspect do
@moduledoc """
Shared helpers for compact `Inspect` protocol implementations.
"""
import Inspect.Algebra
@preview_limit 3
@string_limit 80
@id_limit 12
def container(name, fields, opts) do
filtered_fields = Enum.reject(fields, fn {_key, value} -> value in [nil, [], %{}] end)
concat([
string("#"),
string(name),
string("<"),
container_doc(filtered_fields, opts),
string(">"),
empty()
])
end
def rows_summary(nil), do: nil
def rows_summary(rows), do: length(rows)
def rows_preview(nil), do: nil
def rows_preview([]), do: []
def rows_preview(rows) do
{preview, rest} = Enum.split(rows, @preview_limit)
case rest do
[] -> preview
[_ | _] -> preview |> Enum.reverse() |> then(&[:... | &1]) |> Enum.reverse()
end
end
def truncate(value, limit \\ @string_limit)
def truncate(nil, _limit), do: nil
def truncate(value, limit) do
value = IO.iodata_to_binary(value)
if String.length(value) > limit do
String.slice(value, 0, limit) <> "…"
else
value
end
end
def short_id(nil), do: nil
def short_id(value), do: truncate(value, @id_limit)
defp container_doc([], _opts), do: empty()
defp container_doc(fields, opts) do
fields
|> Enum.map(fn {key, value} -> field_doc(key, value, opts) end)
|> Enum.intersperse(concat(string(","), break(" ")))
|> concat()
end
defp field_doc(key, value, opts) do
concat([string(Atom.to_string(key)), string(": "), to_doc(value, opts)])
end
end