File Coverage

blib/lib/Catmandu/TabularExporter.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Catmandu::TabularExporter;
2              
3 7     7   4431 use Catmandu::Sane;
  7         34  
  7         59  
4              
5             our $VERSION = '1.2020';
6              
7 7     7   57 use Catmandu::Util qw(:is :check);
  7         21  
  7         3365  
8 7     7   60 use Moo::Role;
  7         17  
  7         53  
9              
10             sub _coerce_array {
11             my $fields = $_[0];
12             if (ref $fields eq 'ARRAY') {return $fields}
13             if (ref $fields eq 'HASH') {return [sort keys %$fields]}
14             [split ',', $fields];
15             }
16              
17 7     7   5183 use namespace::clean;
  7         20  
  7         45  
18              
19             with 'Catmandu::Exporter';
20              
21             has fields => (is => 'rwp', coerce => \&_coerce_array,);
22              
23             has columns => (is => 'rwp', coerce => \&_coerce_array,);
24              
25             has collect_fields => (is => 'ro',);
26              
27             has header => (is => 'ro', default => sub {1});
28              
29             around add => sub {
30             my ($orig, $self, $data) = @_;
31             $self->_set_fields($data) unless $self->fields;
32             $orig->($self, $data);
33             };
34              
35             around add_many => sub {
36             my ($orig, $self, $many) = @_;
37              
38             if ($self->collect_fields && !$self->fields) {
39             my $coll;
40              
41             if (is_array_ref($many)) {
42             $coll = $many;
43             }
44             elsif (is_hash_ref($many)) {
45             $coll = [$many];
46             }
47             else {
48             if (is_invocant($many)) {
49             $many = check_able($many, 'generator')->generator;
50             }
51             check_code_ref($many);
52             $coll = [];
53             while (defined(my $data = $many->())) {
54             push @$coll, $data;
55             }
56             }
57              
58             my $keys = {};
59             for my $data (@$coll) {
60             for my $key (keys %$data) {
61             $keys->{$key} ||= 1;
62             }
63             }
64             $self->_set_fields($keys);
65              
66             $many = $coll;
67             }
68              
69             $orig->($self, $many);
70             };
71              
72             1;
73              
74             __END__
75              
76             =pod
77              
78             =head1 NAME
79              
80             Catmandu::TabularExporter - base role for tabular exporters like CSV
81              
82             =head1 DESCRIPTION
83              
84             See L<Catmandu::Exporter> for the base functionality of this role. This role
85             adds some functionality tailored to tabular or columnar exporters.
86              
87             =head1 CONFIGURATION
88              
89             =over
90              
91             =item fields
92              
93             The fields to be mapped. Can be an arrayref, example hashref or comma
94             separated string. If missing, the fields of the first record encountered will
95             be used. If C<collect_fields> is true, all fields names in the record stream
96             will be collected first.
97              
98             =item columns
99              
100             Optional custom column labels. Can be an arrayref, example hashref or comma
101             separated string.
102              
103             =item collect_fields
104              
105             See C<fields> for a description. Note that this option will cause all records
106             in the stream to be buffered in memory.
107              
108             =item header
109              
110             Include a header with column names. Enabled by default.
111              
112             =back
113              
114             =cut
115