add depends_on info to resolve trace
[scpubgit/DX.git] / lib / DX / Deparse.pm
1 package DX::Deparse;
2
3 use Scalar::Util qw(blessed);
4 use curry;
5 use DX::Class;
6
7 sub indent_by { '    ' }
8
9 sub format {
10   my ($self, $thing) = @_;
11   local our $Indent_Level = 0;
12   $self->_format($thing);
13 }
14
15 sub _format {
16   my ($self, $thing) = @_;
17   my ($as, $data) = @{blessed($thing) ? $thing->for_deparse : $thing};
18   $self->${\"_format_as_${as}"}($data);
19 }
20
21 sub _format_indented {
22   my ($self, $cb) = @_;
23   our $Indent_Level;
24   local $Indent_Level = $Indent_Level + 1;
25   my $unindented = $cb->();
26   (my $indented = $unindented) =~ s/^/${\$self->indent_by}/mg;
27   return $indented;
28 }
29
30 sub _format_as_string {
31   my ($self, $val) = @_;
32   # TODO: multiline handling
33   if ($val =~ /^\w+$/) {
34     qq{'${val}'}
35   } else {
36     qq{{'${val}'}}
37   }
38 }
39
40 sub _format_as_symbol { $_[1] }
41
42 sub _format_as_maybe_bareword {
43   my ($self, $maybe_bareword) = @_;
44   # should stringify if required
45   return $maybe_bareword;
46 }
47
48 sub _format_as_number { $_[1] }
49
50 sub _format_as_boolean { $_[1] ? 'true' : 'false' }
51
52 sub _format_as_unset { 'unset' }
53
54 sub _format_as_array {
55   my ($self, $members) = @_;
56   join ' ', '{[', (map $self->_format($_), @$members), ']}';
57 }
58
59 sub _format_as_dict {
60   my ($self, $members) = @_;
61   join ' ', '{{', (
62     map +(
63       $self->_format_as_maybe_bareword($_),
64       $self->_format($members->{$_}),
65     ), sort keys %$members
66   ), '}}';
67 }
68
69 sub _format_as_statement {
70   my ($self, $parts) = @_;
71   join ' ', map $self->_format($_), @$parts;
72 }
73
74 sub _format_as_value_path {
75   my ($self, $parts) = @_;
76   join '.', map $self->_format_as_maybe_bareword($_), @$parts;
77 }
78
79 sub _format_as_list {
80   my ($self, $members) = @_;
81   join "\n", '{', (
82     map $self->_format_indented($self->curry::_format($_)), @$members
83   ), '}';
84 }
85
86 sub _format_as_pairs {
87   my ($self, $members) = @_;
88   join "\n", '{', (
89     map $self->_format_indented(sub {
90           $self->_format_as_maybe_bareword($_->[0])
91             .' '.$self->_format($_->[1])
92         }), @$members
93   ), '}';
94 }
95
96 sub _format_as_block {
97   my ($self, $members) = @_;
98   join "\n", '{', (
99     map $self->_format_indented($self->curry::_format($_)), @$members
100   ), '}';
101 }
102
103 1;