1 package DX::TraceFormatter;
3 use Scalar::Util qw(blessed);
5 use List::Util qw(min);
11 has ambient_indent_level => (
12 is => 'rwp', lazy => 1, clearer => 1, default => 0
20 my ($self, $thing) = @_;
21 local our $Indent_Level = $self->ambient_indent_level;
22 my $unindented = $self->_format($thing);
23 my $indent_level = min($Indent_Level, $self->ambient_indent_level);
24 (my $indented = $unindented)
25 =~ s/^/${\($self->indent_by x $indent_level)}/mg;
30 my ($self, $thing) = @_;
31 my ($as, $data) = @{blessed($thing) ? $thing->for_deparse : $thing};
33 my $spaced = $self->${\"_format_as_${as}"}($data);#
37 ((length($self->indent_by) * our $Indent_Level) + $Extra)))
41 return $self->${\"_format_as_${as}"}($data);
46 sub _format_as_word_and_body {
48 my ($word, $body) = @$wb;
49 my $word_f = $self->_format_as_maybe_bareword($word).' ';
50 local $Extra = length($word_f);
51 return $word_f.$self->_format($body);
54 sub _format_indented {
56 return $cb->() if $WS eq ' ';
58 local $Indent_Level = $Indent_Level + 1;
59 my $unindented = $cb->();
60 (my $indented = $unindented) =~ s/^/${\$self->indent_by}/mg;
64 sub _format_as_string {
65 my ($self, $val) = @_;
66 # TODO: multiline handling
67 if ($val =~ /^\w+$/) {
74 sub _format_as_symbol { $_[1] }
76 sub _format_as_maybe_bareword {
77 my ($self, $maybe_bareword) = @_;
78 # should stringify if required
79 return $maybe_bareword;
82 sub _format_as_number { $_[1] }
84 sub _format_as_boolean { $_[1] ? 'true' : 'false' }
86 sub _format_as_unset { 'unset' }
88 sub _format_as_array {
89 my ($self, $members) = @_;
92 (map $self->_format_indented($self->curry::_format($_)), @$members)
97 my ($self, $members) = @_;
99 map $self->_format_indented($self->curry::_format(
100 [ word_and_body => [ $_, $members->{$_} ] ],
101 )), sort keys %$members
105 sub _format_as_statement {
106 my ($self, $parts) = @_;
107 join ' ', map $self->_format($_), @$parts;
110 sub _format_as_value_path {
111 my ($self, $parts) = @_;
112 join '.', map $self->_format_as_maybe_bareword($_), @$parts;
115 sub _format_as_list {
116 my ($self, $members) = @_;
118 map $self->_format_indented($self->curry::_format($_)), @$members
122 sub _format_as_pairs {
123 my ($self, $members) = @_;
125 map $self->_format_indented($self->curry::_format(
126 [ word_and_body => $_ ]
131 sub _format_as_block {
132 my ($self, $members) = @_;
134 join +($WS eq ' ' ? '; ' : $WS),
135 map $self->_format_indented($self->curry::_format($_)), @$members
139 sub _format_as_enter_block {
141 $self->_set_ambient_indent_level($self->ambient_indent_level + 1);
145 sub _format_as_leave_block {
147 $self->_set_ambient_indent_level($self->ambient_indent_level - 1);