rename Deparse to TraceFormatter and add ambient indent level
[scpubgit/DX.git] / lib / DX / TraceFormatter.pm
CommitLineData
1444edde 1package DX::TraceFormatter;
381e8dad 2
c25fbf05 3use Scalar::Util qw(blessed);
5b6cab1b 4use curry;
1444edde 5use List::Util qw(min);
381e8dad 6use DX::Class;
7
1444edde 8has ambient_indent_level => (
9 is => 'rwp', lazy => 1, clearer => 1, default => 0
10);
11
381e8dad 12sub indent_by { ' ' }
13
c25fbf05 14sub 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 24sub _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 30sub _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 39sub _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 49sub _format_as_symbol { $_[1] }
1e812b19 50
c25fbf05 51sub _format_as_maybe_bareword {
52 my ($self, $maybe_bareword) = @_;
53 # should stringify if required
54 return $maybe_bareword;
39351e10 55}
56
c25fbf05 57sub _format_as_number { $_[1] }
1e812b19 58
c25fbf05 59sub _format_as_boolean { $_[1] ? 'true' : 'false' }
1e812b19 60
c25fbf05 61sub _format_as_unset { 'unset' }
e442aff8 62
c25fbf05 63sub _format_as_array {
64 my ($self, $members) = @_;
65 join ' ', '{[', (map $self->_format($_), @$members), ']}';
1e812b19 66}
67
c25fbf05 68sub _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 78sub _format_as_statement {
79 my ($self, $parts) = @_;
80 join ' ', map $self->_format($_), @$parts;
061f9d55 81}
82
c25fbf05 83sub _format_as_value_path {
84 my ($self, $parts) = @_;
85 join '.', map $self->_format_as_maybe_bareword($_), @$parts;
693f2d6d 86}
1e812b19 87
c25fbf05 88sub _format_as_list {
89 my ($self, $members) = @_;
90 join "\n", '{', (
91 map $self->_format_indented($self->curry::_format($_)), @$members
92 ), '}';
1e812b19 93}
94
c25fbf05 95sub _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 105sub _format_as_block {
106 my ($self, $members) = @_;
107 join "\n", '{', (
108 map $self->_format_indented($self->curry::_format($_)), @$members
109 ), '}';
56f90161 110}
111
1444edde 112sub _format_as_enter_block {
113 my ($self) = @_;
114 $self->_set_ambient_indent_level($self->ambient_indent_level + 1);
115 '{'
116}
117
118sub _format_as_leave_block {
119 my ($self) = @_;
120 $self->_set_ambient_indent_level($self->ambient_indent_level - 1);
121 '}'
122}
123
381e8dad 1241;