Current section
Files
Jump to
Current section
Files
inspect_overrides/1_6.ex
if Scribe.compile_auto_inspect?() do
import Kernel, except: [inspect: 1]
import Inspect.Algebra, warn: false
defimpl Inspect, for: List do
alias Code.Identifier
def inspect([], opts) do
color("[]", :list, opts)
end
def inspect([head | _rest] = term, opts) when is_map(head) do
if do_inspect?(term) do
do_inspect(term, opts)
else
Scribe.format(term)
end
end
def inspect(term, opts) do
do_inspect(term, opts)
end
defp do_inspect?(term) do
Enum.any?(term, &(!is_map(&1))) or not Scribe.auto_inspect?()
end
def do_inspect(term, opts) do
%Inspect.Opts{
charlists: lists,
char_lists: lists_deprecated,
printable_limit: printable_limit
} = opts
lists =
if lists == :infer and lists_deprecated != :infer do
case lists_deprecated do
:as_char_lists ->
IO.warn(
"the :char_lists inspect option and its :as_char_lists " <>
"value are deprecated, use the :charlists option and its " <>
":as_charlists value instead"
)
:as_charlists
_ ->
IO.warn(
"the :char_lists inspect option is deprecated, use :charlists instead"
)
lists_deprecated
end
else
lists
end
open = color("[", :list, opts)
sep = color(",", :list, opts)
close = color("]", :list, opts)
cond do
lists == :as_charlists or
(lists == :infer and List.ascii_printable?(term, printable_limit)) ->
inspected =
case Identifier.escape(
IO.chardata_to_string(term),
?',
printable_limit
) do
{escaped, ""} -> [?', escaped, ?']
{escaped, _} -> [?', escaped, ?', " ++ ..."]
end
IO.iodata_to_binary(inspected)
keyword?(term) ->
container_doc(
open,
term,
close,
opts,
&keyword/2,
separator: sep,
break: :strict
)
true ->
container_doc(open, term, close, opts, &to_doc/2, separator: sep)
end
end
@doc false
def keyword({key, value}, opts) do
key = color(Identifier.inspect_as_key(key), :atom, opts)
concat(key, concat(" ", to_doc(value, opts)))
end
@doc false
def keyword?([{key, _value} | rest]) when is_atom(key) do
case Atom.to_charlist(key) do
'Elixir.' ++ _ -> false
_ -> keyword?(rest)
end
end
def keyword?([]), do: true
def keyword?(_other), do: false
end
defimpl Inspect, for: Map do
import Inspect.Algebra
def inspect(map, opts) do
inspect(map, "", opts)
end
def inspect(map, name, opts) do
if Scribe.auto_inspect?() do
Scribe.format([map])
else
map = :maps.to_list(map)
open = color("%" <> name <> "{", :map, opts)
sep = color(",", :map, opts)
close = color("}", :map, opts)
container_doc(
open,
map,
close,
opts,
traverse_fun(map, opts),
separator: sep,
break: :strict
)
end
end
defp traverse_fun(list, opts) do
if Inspect.List.keyword?(list) do
&Inspect.List.keyword/2
else
sep = color(" => ", :map, opts)
&to_map(&1, &2, sep)
end
end
defp to_map({key, value}, opts, sep) do
concat(concat(to_doc(key, opts), sep), to_doc(value, opts))
end
end
defimpl Inspect, for: Any do
def inspect(%module{} = struct, opts) do
try do
module.__struct__
rescue
_ -> Inspect.Map.inspect(struct, opts)
else
dunder ->
if :maps.keys(dunder) == :maps.keys(struct) do
pruned =
if Scribe.auto_inspect?() do
:maps.remove(:__exception__, struct)
else
:maps.remove(:__exception__, :maps.remove(:__struct__, struct))
end
colorless_opts = %{opts | syntax_colors: []}
Inspect.Map.inspect(
pruned,
Inspect.Atom.inspect(module, colorless_opts),
opts
)
else
Inspect.Map.inspect(struct, opts)
end
end
end
end
end