-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( <