Current section

Files

Jump to
pprint src pprint.erl
Raw

src/pprint.erl

-module(pprint).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([with_config/2, debug/1, format/1, styled/1]).
-export_type([config/0, style_mode/0, bit_array_mode/0, label_mode/0]).
-type config() :: {config, style_mode(), bit_array_mode(), label_mode()}.
-type style_mode() :: styled | unstyled.
-type bit_array_mode() :: bit_arrays_as_string | keep_bit_arrays.
-type label_mode() :: labels | no_labels.
-spec wrap(
glam@doc:document(),
glam@doc:document(),
glam@doc:document(),
binary()
) -> glam@doc:document().
wrap(Document, Open, Close, Trailing) ->
_pipe = Document,
_pipe@1 = glam@doc:prepend_docs(
_pipe,
[Open, {break, <<""/utf8>>, <<""/utf8>>}]
),
_pipe@2 = glam@doc:nest(_pipe@1, 2),
_pipe@3 = glam@doc:append_docs(
_pipe@2,
[glam@doc:break(<<""/utf8>>, Trailing), Close]
),
glam@doc:group(_pipe@3).
-spec ansi(binary(), binary(), config()) -> glam@doc:document().
ansi(Text, Code, Config) ->
Text_doc = glam@doc:from_string(Text),
case erlang:element(2, Config) of
unstyled ->
Text_doc;
styled ->
glam@doc:concat(
[glam@doc:zero_width_string(Code),
Text_doc,
glam@doc:zero_width_string(<<"\x{001b}[0m"/utf8>>)]
)
end.
-spec pretty_string(binary(), config()) -> glam@doc:document().
pretty_string(String, Config) ->
_pipe = (<<<<"\""/utf8, String/binary>>/binary, "\""/utf8>>),
ansi(_pipe, <<"\x{001b}[38;5;2m"/utf8>>, Config).
-spec pretty_bit_array(bitstring(), config()) -> glam@doc:document().
pretty_bit_array(Bits, Config) ->
_pipe = gleam@string:inspect(Bits),
ansi(_pipe, <<"\x{001b}[38;5;5m"/utf8>>, Config).
-spec pretty_tuple(list(gleam@dynamic:dynamic_()), config()) -> glam@doc:document().
pretty_tuple(Items, Config) ->
_pipe = gleam@list:map(
Items,
fun(_capture) -> pretty_dynamic(_capture, Config) end
),
_pipe@1 = glam@doc:concat_join(
_pipe,
[glam@doc:from_string(<<","/utf8>>), {break, <<" "/utf8>>, <<""/utf8>>}]
),
wrap(
_pipe@1,
glam@doc:from_string(<<"#("/utf8>>),
glam@doc:from_string(<<")"/utf8>>),
<<","/utf8>>
).
-spec pretty_dynamic(gleam@dynamic:dynamic_(), config()) -> glam@doc:document().
pretty_dynamic(Value, Config) ->
_pipe = Value,
_pipe@1 = pprint@decoder:classify(_pipe),
pretty_type(_pipe@1, Config).
-spec pretty_type(pprint@decoder:type(), config()) -> glam@doc:document().
pretty_type(Value, Config) ->
case Value of
{t_string, S} ->
pretty_string(S, Config);
{t_int, I} ->
_pipe = gleam@int:to_string(I),
ansi(_pipe, <<"\x{001b}[38;5;3m"/utf8>>, Config);
{t_float, F} ->
_pipe@1 = gleam@float:to_string(F),
ansi(_pipe@1, <<"\x{001b}[38;5;3m"/utf8>>, Config);
{t_bool, B} ->
_pipe@2 = gleam@bool:to_string(B),
ansi(_pipe@2, <<"\x{001b}[38;5;4m"/utf8>>, Config);
{t_bit_array, B@1} ->
case erlang:element(3, Config) of
keep_bit_arrays ->
pretty_bit_array(B@1, Config);
bit_arrays_as_string ->
case gleam@bit_array:to_string(B@1) of
{ok, S@1} ->
pretty_string(S@1, Config);
{error, nil} ->
pretty_bit_array(B@1, Config)
end
end;
t_nil ->
ansi(<<"Nil"/utf8>>, <<"\x{001b}[38;5;4m"/utf8>>, Config);
{t_list, Items} ->
pretty_list(Items, Config);
{t_dict, D} ->
pretty_dict(D, Config);
{t_tuple, Items@1} ->
pretty_tuple(Items@1, Config);
{t_custom, Name, Fields} ->
pretty_custom_type(Name, Fields, Config);
{t_foreign, F@1} ->
ansi(F@1, <<"\x{001b}[2m"/utf8>>, Config)
end.
-spec with_config(any(), config()) -> binary().
with_config(Value, Config) ->
_pipe = Value,
_pipe@1 = gleam@dynamic:from(_pipe),
_pipe@2 = pretty_dynamic(_pipe@1, Config),
glam@doc:to_string(_pipe@2, 40).
-spec debug(JBU) -> JBU.
debug(Value) ->
_pipe = Value,
_pipe@1 = with_config(_pipe, {config, styled, keep_bit_arrays, labels}),
gleam@io:println_error(_pipe@1),
Value.
-spec format(any()) -> binary().
format(Value) ->
with_config(Value, {config, unstyled, bit_arrays_as_string, no_labels}).
-spec styled(any()) -> binary().
styled(Value) ->
with_config(Value, {config, styled, bit_arrays_as_string, no_labels}).
-spec pretty_list(list(gleam@dynamic:dynamic_()), config()) -> glam@doc:document().
pretty_list(Items, Config) ->
Items@1 = gleam@list:map(Items, fun pprint@decoder:classify/1),
Space = case Items@1 of
[{t_int, _} | _] ->
{flex_break, <<" "/utf8>>, <<""/utf8>>};
[{t_float, _} | _] ->
{flex_break, <<" "/utf8>>, <<""/utf8>>};
_ ->
{break, <<" "/utf8>>, <<""/utf8>>}
end,
_pipe = gleam@list:map(
Items@1,
fun(_capture) -> pretty_type(_capture, Config) end
),
_pipe@1 = glam@doc:concat_join(
_pipe,
[glam@doc:from_string(<<","/utf8>>), Space]
),
wrap(
_pipe@1,
glam@doc:from_string(<<"["/utf8>>),
glam@doc:from_string(<<"]"/utf8>>),
<<","/utf8>>
).
-spec pretty_dict(
gleam@dict:dict(pprint@decoder:type(), pprint@decoder:type()),
config()
) -> glam@doc:document().
pretty_dict(D, Config) ->
_pipe = maps:to_list(D),
_pipe@1 = gleam@list:sort(
_pipe,
fun(One_field, Other_field) ->
{One_key, _} = One_field,
{Other_key, _} = Other_field,
gleam@string:compare(
gleam@string:inspect(One_key),
gleam@string:inspect(Other_key)
)
end
),
_pipe@3 = gleam@list:map(
_pipe@1,
fun(Field) ->
_pipe@2 = [glam@doc:from_string(<<"#("/utf8>>),
pretty_type(erlang:element(1, Field), Config),
glam@doc:from_string(<<", "/utf8>>),
pretty_type(erlang:element(2, Field), Config),
glam@doc:from_string(<<")"/utf8>>)],
glam@doc:concat(_pipe@2)
end
),
_pipe@4 = glam@doc:concat_join(
_pipe@3,
[glam@doc:from_string(<<","/utf8>>), {break, <<" "/utf8>>, <<""/utf8>>}]
),
wrap(
_pipe@4,
glam@doc:from_string(<<"dict.from_list(["/utf8>>),
glam@doc:from_string(<<"])"/utf8>>),
<<","/utf8>>
).
-spec pretty_custom_type(binary(), list(pprint@decoder:field()), config()) -> glam@doc:document().
pretty_custom_type(Name, Fields, Config) ->
Style = case Name of
<<"Ok"/utf8>> ->
<<"\x{001b}[1m"/utf8>>;
<<"Error"/utf8>> ->
<<"\x{001b}[1m"/utf8>>;
<<"Some"/utf8>> ->
<<"\x{001b}[1m"/utf8>>;
<<"None"/utf8>> ->
<<"\x{001b}[1m"/utf8>>;
_ ->
<<""/utf8>>
end,
Fields@1 = gleam@list:map(
Fields,
fun(Field) -> case {Field, erlang:element(4, Config)} of
{{positional, Value}, labels} ->
pretty_dynamic(Value, Config);
{{positional, Value}, no_labels} ->
pretty_dynamic(Value, Config);
{{labelled, _, Value}, no_labels} ->
pretty_dynamic(Value, Config);
{{labelled, Label, Value@1}, labels} ->
glam@doc:concat(
[ansi(
<<Label/binary, ": "/utf8>>,
<<"\x{001b}[2m"/utf8>>,
Config
),
pretty_dynamic(Value@1, Config)]
)
end end
),
Name@1 = ansi(Name, Style, Config),
Open = glam@doc:concat([Name@1, glam@doc:from_string(<<"("/utf8>>)]),
Close = glam@doc:from_string(<<")"/utf8>>),
case Fields@1 of
[] ->
Name@1;
[Single] ->
glam@doc:concat([Open, Single, Close]);
_ ->
_pipe = Fields@1,
_pipe@1 = glam@doc:concat_join(
_pipe,
[glam@doc:from_string(<<","/utf8>>),
{break, <<" "/utf8>>, <<""/utf8>>}]
),
wrap(_pipe@1, Open, Close, <<","/utf8>>)
end.