Fix syntax error in example
[dbsrgits/SQL-Abstract.git] / lib / SQL / Abstract / Formatter.pm
CommitLineData
77ec9556 1package SQL::Abstract::Formatter;
2
3require SQL::Abstract::Parts; # it loads us too, don't cross the streams
4
5use Moo;
6
7has indent_by => (is => 'ro', default => ' ');
8has max_width => (is => 'ro', default => 78);
9
10sub _join {
11 shift;
b349d2fa 12 return SQL::Abstract::Parts::stringify(\@_);
77ec9556 13}
14
15sub format {
16 my ($self, $join, @parts) = @_;
b7516a3a 17 $self->_fold_sql('', '', @{$self->_simplify($join, @parts)});
18}
19
20sub _simplify {
21 my ($self, $join, @parts) = @_;
22 return '' unless @parts;
23 return $parts[0] if @parts == 1 and !ref($parts[0]);
24 return $self->_simplify(@{$parts[0]}) if @parts == 1;
25 return [ $join, map ref() ? $self->_simplify(@$_) : $_, @parts ];
26}
27
28sub _fold_sql {
b7516a3a 29 my ($self, $indent0, $indent, $join, @parts) = @_;
30 my @res;
31 my $w = $self->max_width;
32 my $join_len = 0;
26244e44 33 (s/, \z/,\n/ and $join_len = 1)
34 or s/\a /\n/
b7516a3a 35 or $_ = "\n"
36 for my $line_join = $join;
37 my ($nl_pre, $nl_post) = split "\n", $line_join;
1b20ff8d 38 my $line_orig = my $line = $indent0;
b7516a3a 39 my $next_indent = $indent.$self->indent_by;
1b20ff8d 40 my $line_proto = $indent.$nl_post;
b7516a3a 41 PART: foreach my $idx (0..$#parts) {
b7516a3a 42 my $p = $parts[$idx];
9b0bc0ac 43#::DwarnT STARTPART => $p, \@res, $line, $line_orig;
1b20ff8d 44 my $pre = ($line ne $line_orig ? $join : '');
b7516a3a 45 my $j_part = $pre.(my $j = ref($p) ? $self->_join(@$p) : $p);
46 if (length($j_part) + length($line) + $join_len <= $w) {
47 $line .= $j_part;
3203315e 48 next PART;
49 }
f17bb26d 50 my $innerdent = @res
51 ? $next_indent
52 : $indent0.$self->indent_by;
3203315e 53 if (ref($p) and $p->[1] eq '(' and $p->[-1] eq ')') {
54 my $already = !($line eq $indent0 or $line eq $line_orig);
55 push @res, $line.($already ? $join : '').'('."\n";
56 my (undef, undef, $inner) = @$p;
4be609c3 57 my $folded = $self->_fold_sql($innerdent, $innerdent, @$inner);
26244e44 58 $folded =~ s/\n\z//;
3203315e 59 push @res, $folded."\n";
60 $line_orig = $line
2d4a4d5f 61 = $indent0.')'.($idx == $#parts ? '' : $join);
3203315e 62 next PART;
63 }
e152bc5a 64 if ($line ne $line_orig) {
65 push @res, $line.($idx == $#parts ? '' : $nl_pre)."\n";
66 }
3203315e 67 if (length($line = $line_proto.$j) <= $w) {
3203315e 68 next PART;
b7516a3a 69 }
3203315e 70 my $folded = $self->_fold_sql($line_proto, $innerdent, @$p);
26244e44 71 $folded =~ s/\n\z//;
e152bc5a 72 push @res, $folded.($idx == $#parts ? '' : $nl_pre)."\n";
3203315e 73 $line_orig = $line = $idx == $#parts ? '' : $line_proto;
9b0bc0ac 74 } continue {
75#::DwarnT ENDPART => $parts[$idx], \@res, $line, $line_orig;
b7516a3a 76 }
b349d2fa 77 return join '', @res, $line;
77ec9556 78}
79
b775020d 801;