File Coverage

blib/lib/Data/Pipeline/Adapter.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Data::Pipeline::Adapter;
2              
3 1     1   1948 use Moose;
  0            
  0            
4              
5             use MooseX::Types::Moose qw(GlobRef CodeRef);
6              
7             use Data::Pipeline::Types qw( Iterator IteratorSource );
8              
9             use Data::Pipeline::Aggregator::Machine;
10             use Data::Pipeline::Iterator::Output;
11             use Data::Pipeline::Iterator::Source;
12              
13             has preamble => (
14             is => 'rw',
15             isa => 'Str|CodeRef',
16             predicate => 'has_preamble',
17             lazy => 1,
18             default => sub { '' }
19             );
20              
21             has postamble => (
22             is => 'rw',
23             isa => 'Str|CodeRef',
24             predicate => 'has_postamble',
25             lazy => 1,
26             default => sub { '' }
27             );
28              
29             has source => (
30             is => 'rw',
31             isa => IteratorSource,
32             lazy => 1,
33             coerce => 1,
34             default => sub {
35             Data::Pipeline::Iterator::Source -> new(
36             get_next => sub { },
37             has_next => sub { 0 }
38             );
39             }
40             );
41              
42             sub transform {
43             my($self, $iterator, $options) = @_;
44              
45             return Data::Pipeline::Iterator::Output -> new(
46             iterator => $iterator,
47             serializer => $self,
48             options => ($options||{})
49             );
50             }
51              
52             sub serialize {
53             my($self, $iterator, $target) = @_;
54              
55             my($pre, $post);
56              
57             $pre = (is_CodeRef($self -> preamble) ? $self -> preamble -> () : $self -> preamble);
58             $post = (is_CodeRef($self -> postamble) ? $self -> postamble -> () : $self -> postamble);
59             if( UNIVERSAL::isa($target, 'IO::Handle') || is_GlobRef($target) ) {
60             print $target $pre;
61             print $target $self -> inner until $iterator -> finished;
62             print $target $post;
63             }
64             elsif( is_CodeRef( $target ) ) {
65             $target -> ($pre);
66             $target -> ($self -> inner);
67             $target -> ($post);
68             }
69             elsif( ref( $target ) ) {
70             $$target = $pre;
71             $$target .= $self -> inner until $iterator -> finished;
72             $$target .= $post;
73             }
74             else {
75             # not a ref... what to do...?
76             }
77             }
78              
79             sub duplicate {
80             my($self, %options) = @_;
81            
82             # we want to build a new iterator source that should start over
83             # we avoid private attributes and {get|has}_next
84             # if those are required, we can't duplicate
85            
86            
87             my @attrs;
88            
89             @attrs = $self -> can_duplicate or
90             Carp::croak "Unable to duplicate adapter (".($self -> meta -> name).")";
91            
92             my %defaults;
93             my $meta = $self -> meta;
94             $defaults{$_} = $self -> $_
95             foreach grep { !/^_/ && $meta->get_attribute($_)->has_value($self) } (@attrs);
96              
97             delete $defaults{source};
98            
99             return $self -> new(%defaults, %options);
100             }
101              
102             sub can_duplicate {
103             my($self) = @_;
104            
105             my @attrs = $self -> meta -> get_attribute_list;
106              
107             # we return @attrs as an optimization
108             return @attrs;
109             return;
110             }
111              
112             no Moose;
113              
114             1;
115              
116             __END__
117              
118             =head1 NAME
119              
120             Data::Pipeline::Adapter - data format i/o adapter
121              
122             =head1 SYNOPSIS
123              
124             =head2 Creating an Adapter
125              
126             package My::Adapter;
127              
128             use Moose;
129             extends 'Data::Pipeline::Adapter';
130              
131             has '+source' => (
132             default => sub {
133             my($self) = @_;
134              
135             # build Data::Pipeline::Iterator::Source
136             }
137             );
138              
139             =head3 Serializing to the default handling of targets:
140              
141             augment serialize => sub {
142             my($self, $iterator, $target) = @_;
143              
144             # return serialized form of one item from iterator
145             };
146              
147             =head3 Overriding how targets are handled:
148              
149             override serialize => sub {
150             my($self, $iterator, $target) = @_;
151              
152             # serialize $iterator to $target
153             };
154              
155             =head2 Using an Adapter
156              
157             use My::Adapter;
158              
159             my $out = My::Adapter -> new( ... ) -> transform( $iterator );
160              
161             $out -> to( \$string ); # $string now contains serialization
162              
163             my $iterator = $pipeline -> transform( My::Adapter -> new( ... ) );
164              
165             =head1 DESCRIPTION
166              
167