Commit | Line | Data |
1444edde |
1 | package DX::TraceFormatter; |
381e8dad |
2 | |
c25fbf05 |
3 | use Scalar::Util qw(blessed); |
1444edde |
4 | use List::Util qw(min); |
381e8dad |
5 | use DX::Class; |
6 | |
6162b001 |
7 | our $WS; |
8 | our $Extra = 0; |
9 | |
1444edde |
10 | has ambient_indent_level => ( |
2548ce61 |
11 | is => 'rwp', lazy => 1, clearer => 1, default => 0, isa => Int |
1444edde |
12 | ); |
13 | |
381e8dad |
14 | sub indent_by { ' ' } |
15 | |
6162b001 |
16 | sub max_width { 78 } |
17 | |
c25fbf05 |
18 | sub format { |
381e8dad |
19 | my ($self, $thing) = @_; |
1444edde |
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; |
25 | return $indented; |
7f385fb2 |
26 | } |
27 | |
c25fbf05 |
28 | sub _format { |
29 | my ($self, $thing) = @_; |
30 | my ($as, $data) = @{blessed($thing) ? $thing->for_deparse : $thing}; |
6162b001 |
31 | local $WS = ' '; |
32 | my $spaced = $self->${\"_format_as_${as}"}($data);# |
33 | if ($spaced =~ /\n/ |
34 | or (length($spaced) |
35 | > ($self->max_width - |
36 | ((length($self->indent_by) * our $Indent_Level) + $Extra))) |
37 | ) { |
38 | local $WS = "\n"; |
39 | local $Extra = 0; |
40 | return $self->${\"_format_as_${as}"}($data); |
41 | } |
42 | return $spaced; |
43 | } |
44 | |
45 | sub _format_as_word_and_body { |
46 | my ($self, $wb) = @_; |
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); |
381e8dad |
51 | } |
52 | |
c25fbf05 |
53 | sub _format_indented { |
f69aaaff |
54 | my ($self, $thing) = @_; |
55 | return $self->_format($thing) if $WS eq ' '; |
c25fbf05 |
56 | our $Indent_Level; |
57 | local $Indent_Level = $Indent_Level + 1; |
f69aaaff |
58 | my $unindented = $self->_format($thing); |
c25fbf05 |
59 | (my $indented = $unindented) =~ s/^/${\$self->indent_by}/mg; |
60 | return $indented; |
1e812b19 |
61 | } |
62 | |
c25fbf05 |
63 | sub _format_as_string { |
64 | my ($self, $val) = @_; |
1e812b19 |
65 | # TODO: multiline handling |
381e8dad |
66 | if ($val =~ /^\w+$/) { |
67 | qq{'${val}'} |
68 | } else { |
69 | qq{{'${val}'}} |
70 | } |
71 | } |
72 | |
c25fbf05 |
73 | sub _format_as_symbol { $_[1] } |
1e812b19 |
74 | |
c25fbf05 |
75 | sub _format_as_maybe_bareword { |
76 | my ($self, $maybe_bareword) = @_; |
77 | # should stringify if required |
78 | return $maybe_bareword; |
39351e10 |
79 | } |
80 | |
c25fbf05 |
81 | sub _format_as_number { $_[1] } |
1e812b19 |
82 | |
c25fbf05 |
83 | sub _format_as_boolean { $_[1] ? 'true' : 'false' } |
1e812b19 |
84 | |
c25fbf05 |
85 | sub _format_as_unset { 'unset' } |
e442aff8 |
86 | |
c25fbf05 |
87 | sub _format_as_array { |
88 | my ($self, $members) = @_; |
6162b001 |
89 | join $WS, |
90 | '{[', |
f69aaaff |
91 | (map $self->_format_indented($_), @$members) |
6162b001 |
92 | , ']}'; |
1e812b19 |
93 | } |
94 | |
c25fbf05 |
95 | sub _format_as_dict { |
96 | my ($self, $members) = @_; |
6162b001 |
97 | join $WS, '{{', ( |
f69aaaff |
98 | map $self->_format_indented( |
6162b001 |
99 | [ word_and_body => [ $_, $members->{$_} ] ], |
f69aaaff |
100 | ), sort keys %$members |
c25fbf05 |
101 | ), '}}'; |
693f2d6d |
102 | } |
103 | |
c25fbf05 |
104 | sub _format_as_statement { |
105 | my ($self, $parts) = @_; |
106 | join ' ', map $self->_format($_), @$parts; |
061f9d55 |
107 | } |
108 | |
c25fbf05 |
109 | sub _format_as_value_path { |
110 | my ($self, $parts) = @_; |
111 | join '.', map $self->_format_as_maybe_bareword($_), @$parts; |
693f2d6d |
112 | } |
1e812b19 |
113 | |
c25fbf05 |
114 | sub _format_as_list { |
115 | my ($self, $members) = @_; |
6162b001 |
116 | join $WS, '{', ( |
f69aaaff |
117 | map $self->_format_indented($_), @$members |
c25fbf05 |
118 | ), '}'; |
1e812b19 |
119 | } |
120 | |
c25fbf05 |
121 | sub _format_as_pairs { |
122 | my ($self, $members) = @_; |
6162b001 |
123 | join $WS, '{', ( |
f69aaaff |
124 | map $self->_format_indented( |
6162b001 |
125 | [ word_and_body => $_ ] |
f69aaaff |
126 | ), @$members |
c25fbf05 |
127 | ), '}'; |
1e812b19 |
128 | } |
381e8dad |
129 | |
c25fbf05 |
130 | sub _format_as_block { |
131 | my ($self, $members) = @_; |
6162b001 |
132 | join $WS, '{', ( |
133 | join +($WS eq ' ' ? '; ' : $WS), |
f69aaaff |
134 | map $self->_format_indented($_), @$members |
c25fbf05 |
135 | ), '}'; |
56f90161 |
136 | } |
137 | |
1444edde |
138 | sub _format_as_enter_block { |
139 | my ($self) = @_; |
140 | $self->_set_ambient_indent_level($self->ambient_indent_level + 1); |
141 | '{' |
142 | } |
143 | |
144 | sub _format_as_leave_block { |
145 | my ($self) = @_; |
146 | $self->_set_ambient_indent_level($self->ambient_indent_level - 1); |
147 | '}' |
148 | } |
149 | |
381e8dad |
150 | 1; |