Commit | Line | Data |
1444edde |
1 | package DX::TraceFormatter; |
381e8dad |
2 | |
c25fbf05 |
3 | use Scalar::Util qw(blessed); |
5b6cab1b |
4 | use curry; |
1444edde |
5 | use List::Util qw(min); |
381e8dad |
6 | use DX::Class; |
7 | |
1444edde |
8 | has ambient_indent_level => ( |
9 | is => 'rwp', lazy => 1, clearer => 1, default => 0 |
10 | ); |
11 | |
381e8dad |
12 | sub indent_by { ' ' } |
13 | |
c25fbf05 |
14 | sub format { |
381e8dad |
15 | my ($self, $thing) = @_; |
1444edde |
16 | local our $Indent_Level = $self->ambient_indent_level; |
17 | my $unindented = $self->_format($thing); |
18 | my $indent_level = min($Indent_Level, $self->ambient_indent_level); |
19 | (my $indented = $unindented) |
20 | =~ s/^/${\($self->indent_by x $indent_level)}/mg; |
21 | return $indented; |
7f385fb2 |
22 | } |
23 | |
c25fbf05 |
24 | sub _format { |
25 | my ($self, $thing) = @_; |
26 | my ($as, $data) = @{blessed($thing) ? $thing->for_deparse : $thing}; |
27 | $self->${\"_format_as_${as}"}($data); |
381e8dad |
28 | } |
29 | |
c25fbf05 |
30 | sub _format_indented { |
31 | my ($self, $cb) = @_; |
32 | our $Indent_Level; |
33 | local $Indent_Level = $Indent_Level + 1; |
34 | my $unindented = $cb->(); |
35 | (my $indented = $unindented) =~ s/^/${\$self->indent_by}/mg; |
36 | return $indented; |
1e812b19 |
37 | } |
38 | |
c25fbf05 |
39 | sub _format_as_string { |
40 | my ($self, $val) = @_; |
1e812b19 |
41 | # TODO: multiline handling |
381e8dad |
42 | if ($val =~ /^\w+$/) { |
43 | qq{'${val}'} |
44 | } else { |
45 | qq{{'${val}'}} |
46 | } |
47 | } |
48 | |
c25fbf05 |
49 | sub _format_as_symbol { $_[1] } |
1e812b19 |
50 | |
c25fbf05 |
51 | sub _format_as_maybe_bareword { |
52 | my ($self, $maybe_bareword) = @_; |
53 | # should stringify if required |
54 | return $maybe_bareword; |
39351e10 |
55 | } |
56 | |
c25fbf05 |
57 | sub _format_as_number { $_[1] } |
1e812b19 |
58 | |
c25fbf05 |
59 | sub _format_as_boolean { $_[1] ? 'true' : 'false' } |
1e812b19 |
60 | |
c25fbf05 |
61 | sub _format_as_unset { 'unset' } |
e442aff8 |
62 | |
c25fbf05 |
63 | sub _format_as_array { |
64 | my ($self, $members) = @_; |
65 | join ' ', '{[', (map $self->_format($_), @$members), ']}'; |
1e812b19 |
66 | } |
67 | |
c25fbf05 |
68 | sub _format_as_dict { |
69 | my ($self, $members) = @_; |
70 | join ' ', '{{', ( |
71 | map +( |
72 | $self->_format_as_maybe_bareword($_), |
73 | $self->_format($members->{$_}), |
74 | ), sort keys %$members |
75 | ), '}}'; |
693f2d6d |
76 | } |
77 | |
c25fbf05 |
78 | sub _format_as_statement { |
79 | my ($self, $parts) = @_; |
80 | join ' ', map $self->_format($_), @$parts; |
061f9d55 |
81 | } |
82 | |
c25fbf05 |
83 | sub _format_as_value_path { |
84 | my ($self, $parts) = @_; |
85 | join '.', map $self->_format_as_maybe_bareword($_), @$parts; |
693f2d6d |
86 | } |
1e812b19 |
87 | |
c25fbf05 |
88 | sub _format_as_list { |
89 | my ($self, $members) = @_; |
90 | join "\n", '{', ( |
91 | map $self->_format_indented($self->curry::_format($_)), @$members |
92 | ), '}'; |
1e812b19 |
93 | } |
94 | |
c25fbf05 |
95 | sub _format_as_pairs { |
96 | my ($self, $members) = @_; |
97 | join "\n", '{', ( |
98 | map $self->_format_indented(sub { |
99 | $self->_format_as_maybe_bareword($_->[0]) |
100 | .' '.$self->_format($_->[1]) |
101 | }), @$members |
102 | ), '}'; |
1e812b19 |
103 | } |
381e8dad |
104 | |
c25fbf05 |
105 | sub _format_as_block { |
106 | my ($self, $members) = @_; |
107 | join "\n", '{', ( |
108 | map $self->_format_indented($self->curry::_format($_)), @$members |
109 | ), '}'; |
56f90161 |
110 | } |
111 | |
1444edde |
112 | sub _format_as_enter_block { |
113 | my ($self) = @_; |
114 | $self->_set_ambient_indent_level($self->ambient_indent_level + 1); |
115 | '{' |
116 | } |
117 | |
118 | sub _format_as_leave_block { |
119 | my ($self) = @_; |
120 | $self->_set_ambient_indent_level($self->ambient_indent_level - 1); |
121 | '}' |
122 | } |
123 | |
381e8dad |
124 | 1; |