1 package DX::TraceFormatter;
3 use Scalar::Util qw(blessed);
4 use List::Util qw(min);
10 has ambient_indent_level => (
11 is => 'rwp', lazy => 1, clearer => 1, default => 0, isa => Int
19 my ($self, $thing) = @_;
20 local our $Indent_Level = $self->ambient_indent_level;
21 my $unindented = $self->_format($thing);
22 my $indent_level = min($Indent_Level, $self->ambient_indent_level);
23 (my $indented = $unindented)
24 =~ s/^/${\($self->indent_by x $indent_level)}/mg;
29 my ($self, $thing) = @_;
30 my ($as, $data) = @{blessed($thing) ? $thing->for_deparse : $thing};
32 my $spaced = $self->${\"_format_as_${as}"}($data);#
36 ((length($self->indent_by) * our $Indent_Level) + $Extra)))
40 return $self->${\"_format_as_${as}"}($data);
45 sub _format_as_word_and_body {
47 my ($word, $body) = @$wb;
48 my $word_f = $self->_format_as_maybe_bareword($word).' ';
49 local $Extra = length($word_f);
50 return $word_f.$self->_format($body);
53 sub _format_indented {
54 my ($self, $thing) = @_;
55 return $self->_format($thing) if $WS eq ' ';
57 local $Indent_Level = $Indent_Level + 1;
58 my $unindented = $self->_format($thing);
59 (my $indented = $unindented) =~ s/^/${\$self->indent_by}/mg;
63 sub _format_as_string {
64 my ($self, $val) = @_;
65 # TODO: multiline handling
66 if ($val =~ /^\w+$/) {
73 sub _format_as_symbol { $_[1] }
75 sub _format_as_maybe_bareword {
76 my ($self, $maybe_bareword) = @_;
77 # should stringify if required
78 return $maybe_bareword;
81 sub _format_as_number { $_[1] }
83 sub _format_as_boolean { $_[1] ? 'true' : 'false' }
85 sub _format_as_unset { 'unset' }
87 sub _format_as_array {
88 my ($self, $members) = @_;
91 (map $self->_format_indented($_), @$members)
96 my ($self, $members) = @_;
98 map $self->_format_indented(
99 [ word_and_body => [ $_, $members->{$_} ] ],
100 ), sort keys %$members
104 sub _format_as_statement {
105 my ($self, $parts) = @_;
106 join ' ', map $self->_format($_), @$parts;
109 sub _format_as_value_path {
110 my ($self, $parts) = @_;
111 join '.', map $self->_format_as_maybe_bareword($_), @$parts;
114 sub _format_as_list {
115 my ($self, $members) = @_;
117 map $self->_format_indented($_), @$members
121 sub _format_as_pairs {
122 my ($self, $members) = @_;
124 map $self->_format_indented(
125 [ word_and_body => $_ ]
130 sub _format_as_block {
131 my ($self, $members) = @_;
133 join +($WS eq ' ' ? '; ' : $WS),
134 map $self->_format_indented($_), @$members
138 sub _format_as_enter_block {
140 $self->_set_ambient_indent_level($self->ambient_indent_level + 1);
144 sub _format_as_leave_block {
146 $self->_set_ambient_indent_level($self->ambient_indent_level - 1);