File Coverage

blib/lib/CodeGen/Cpppp/Output.pm
Criterion Covered Total %
statement 79 108 73.1
branch 9 26 34.6
condition 6 19 31.5
subroutine 16 18 88.8
pod 9 10 90.0
total 119 181 65.7


line stmt bran cond sub pod time code
1             package CodeGen::Cpppp::Output;
2              
3             our $VERSION = '0.005'; # VERSION
4             # ABSTRACT: Collect text output into named sections
5              
6 17     17   230 use v5.20;
  17         78  
7 17     17   99 use warnings;
  17         26  
  17         983  
8 17     17   87 use experimental 'signatures', 'postderef';
  17         29  
  17         105  
9 17     17   3277 use Carp;
  17         31  
  17         1379  
10 17     17   183 use Scalar::Util 'looks_like_number';
  17         28  
  17         1192  
11 17     17   134 use List::Util 'max';
  17         30  
  17         6261  
12 17     17   5824 use overload '""' => sub { $_[0]->get };
  17     14   19539  
  17         185  
  14         902  
13              
14              
15             our %standard_sections= (
16             public => 100,
17             protected => 200,
18             private => 10000,
19             );
20 41     41 1 69 sub new($class, @args) {
  41         65  
  41         62  
  41         50  
21             bless {
22             section_priority => { %standard_sections },
23             out => {},
24 41 50 33     935 @args == 1 && ref $args[0]? %{$args[0]}
  0 50       0  
25             : !(@args & 1)? @args
26             : croak "Expected hashref or even-length list"
27             }, $class;
28             }
29              
30              
31 56     56 1 96 sub section_list($self) {
  56         84  
  56         79  
32 56         154 my $pri= $self->section_priority;
33 56         316 sort { $pri->{$a} <=> $pri->{$b} } keys %$pri;
  145         418  
34             }
35              
36 13     13 0 15 sub has_section($self, $name) {
  13         17  
  13         15  
  13         12  
37 13         21 defined $self->section_priority->{$name};
38             }
39              
40 77     77 1 122 sub section_priority($self) {
  77         131  
  77         95  
41             $self->{section_priority}
42 77         194 }
43              
44 0     0 1 0 sub declare_sections($self, @list) {
  0         0  
  0         0  
  0         0  
45 0         0 my $pri= $self->section_priority;
46 0         0 my $max_before_private= max grep $_ < $pri->{private}, values %$pri;
47 0         0 my $next= $max_before_private + 1;
48 0         0 while (@list) {
49 0         0 my $name= shift @list;
50 0 0       0 looks_like_number($name) and croak "Expected non-numeric name at '$name'";
51 0 0       0 if (looks_like_number($list[0])) {
    0          
52 0         0 $pri->{$name}= shift @list;
53             } elsif (!defined $pri->{$name}) {
54 0 0       0 $name =~ /\.\.|,/ and croak "Section names may not contain '..' or ','";
55 0         0 $pri->{$name}= $next++;
56             }
57             }
58 0         0 $self;
59             }
60              
61              
62 65     65 1 102 sub append($self, $section, @code) {
  65         76  
  65         91  
  65         114  
  65         74  
63 65 50       233 defined $self->{section_priority}{$section} or croak "Unknown section $section";
64 65         77 push @{$self->{out}{$section}}, @code;
  65         210  
65             }
66 0     0 1 0 sub prepend($self, $section, @code) {
  0         0  
  0         0  
  0         0  
  0         0  
67 0 0       0 defined $self->{section_priority}{$section} or croak "Unknown section $section";
68 0         0 unshift @{$self->{out}{$section}}, @code;
  0         0  
69             }
70              
71              
72 8     8 1 12 sub expand_section_selector($self, @list) {
  8         12  
  8         25  
  8         10  
73 8 50       56 @list= map +(ref $_ eq 'ARRAY'? @$_ : $_), @list;
74 8         28 @list= map split(',', $_), @list;
75 8         21 my $sec_pri= $self->section_priority;
76 8         14 my %seen;
77 8         17 for (@list) {
78 8 50       45 if (/([^.]+)\.\.([^.]+)/) {
79 0   0     0 my $low= $sec_pri->{$1} // croak "Unknown section $1";
80 0   0     0 my $high= $sec_pri->{$2} // croak "Unknown section $2";
81 0         0 for (keys %$sec_pri) {
82 0 0 0     0 $seen{$_}++ if $sec_pri->{$_} >= $low && $sec_pri->{$_} <= $high;
83             }
84             } else {
85 8   33     25 $sec_pri->{$_} // croak "Unknown section $_";
86 8         22 $seen{$_}++;
87             }
88             }
89 8         32 sort { $sec_pri->{$a} <=> $sec_pri->{$b} } keys %seen;
  0         0  
90             }
91              
92              
93 49     49 1 5735 sub get($self, @sections) {
  49         75  
  49         72  
  49         66  
94 49 100       219 my @sec= @sections? $self->expand_section_selector(@sections) : $self->section_list;
95 49   100     117 join '', map @{$self->{out}{$_} // []}, @sec;
  135         739  
96             }
97              
98 15     15 1 29 sub consume($self, @sections) {
  15         40  
  15         27  
  15         25  
99 15 100       68 my @sec= @sections? $self->expand_section_selector(@sections) : $self->section_list;
100 15   100     39 my $out= join '', map @{delete $self->{out}{$_} // []}, @sec;
  41         217  
101 15         48 @{$self->{out}{$_}}= () for @sec;
  41         109  
102 15         82 $out
103             }
104              
105             1;
106              
107             __END__