File Coverage

blib/lib/Data/Record/Serialize/Role/Sink/Stream.pm
Criterion Covered Total %
statement 40 41 97.5
branch 14 18 77.7
condition 9 18 50.0
subroutine 9 9 100.0
pod 1 1 100.0
total 73 87 83.9


line stmt bran cond sub pod time code
1             package Data::Record::Serialize::Role::Sink::Stream;
2              
3             # ABSTRACT: output encoded data to a stream.
4              
5 10     10   160041 use v5.12;
  10         32  
6 10     10   45 use Scalar::Util;
  10         14  
  10         460  
7 10     10   471 use Moo::Role;
  10         12261  
  10         61  
8              
9 10     10   4833 use Data::Record::Serialize::Error { errors => [ '::create', '::parameter', '::internal' ] }, -all;
  10         20  
  10         143  
10 10     10   2581 use Types::Standard qw[ Bool ];
  10         184930  
  10         102  
11              
12             our $VERSION = '2.03';
13              
14 10     10   28359 use IO::File;
  10         64184  
  10         1465  
15              
16 10     10   526 use namespace::clean;
  10         13090  
  10         86  
17              
18             ## no critic( NamingConventions::ProhibitAmbiguousNames )
19             ## no critic( Subroutines::ProhibitBuiltinHomonyms )
20              
21              
22              
23              
24              
25              
26              
27              
28              
29              
30              
31              
32              
33              
34              
35              
36              
37              
38              
39              
40              
41              
42              
43              
44              
45              
46              
47              
48              
49              
50             has output => (
51             is => 'ro',
52             default => q{-},
53             isa => sub {
54             defined $_[0]
55             or error( '::parameter', q{'output' parameter must be defined} );
56             my $ref = ref $_[0];
57             return if $ref eq 'GLOB' or $ref eq 'SCALAR';
58              
59             if ( $ref eq q{} ) {
60             $ref = ref( \$_[0] ); # turn plain *STDOUT into \*STDOUT
61             return if $ref eq 'GLOB';
62             return if length $_[0];
63             error( '::parameter', q{string 'output' parameter must not be empty} );
64             }
65              
66             return
67             if Scalar::Util::blessed $_[0]
68             and $_[0]->isa( 'IO::Handle' ) || $_[0]->isa( 'FileHandle' );
69             error( '::parameter', q{illegal value for 'output' parameter} );
70             },
71             );
72              
73              
74              
75              
76              
77              
78              
79              
80              
81              
82              
83              
84              
85             has fh => (
86             is => 'lazy',
87             init_arg => undef,
88             clearer => 1,
89             predicate => 1,
90             handles => ['flush'],
91             );
92              
93              
94              
95              
96              
97              
98              
99             has _passed_fh => (
100             is => 'rwp',
101             init_arg => undef,
102             default => 1,
103             );
104              
105             sub _build_fh {
106 19     19   1254 my $self = shift;
107              
108 19         87 my $output = $self->output;
109 19         46 my $ref = ref $output;
110              
111             # filename
112 19 100       67 if ( $ref eq q{} ) {
113 4 100       27 return $output if ref( \$output ) eq 'GLOB';
114 3 50       14 return \*STDOUT if $output eq q{-};
115              
116 3         12 $self->_set__passed_fh( 0 );
117 3 100       11 if ( $self->create_output_dir ) {
118 1         1189 require Path::Tiny;
119 1         11535 my $dir = Path::Tiny::path( $output )->parent;
120 1 50       122 eval { $dir->mkdir; } or error( '::create', "unable to create output directory '$dir': $@" );
  1         3  
121             }
122             return (
123 3   33     478 IO::File->new( $output, 'w' )
124             or error( '::create', "unable to create output file: '$output'" ) );
125             }
126              
127 15 50 33     125 return $output
      66        
      66        
128             if $ref eq 'GLOB'
129             or Scalar::Util::blessed( $output )
130             && ( $output->isa( 'IO::Handle' ) || $output->isa( 'FileHandle' ) );
131              
132 12         63 $self->_set__passed_fh( 0 );
133             return (
134 12 50 33     131 IO::File->new( $output, 'w' )
135             or error( '::create', q{unable to open scalar for output} ) ) if $ref eq 'SCALAR';
136              
137 0         0 error( '::internal', q{can't get here} );
138             }
139              
140              
141              
142              
143              
144              
145              
146              
147             has create_output_dir => (
148             is => 'ro',
149             isa => Bool,
150             default => 0,
151             );
152              
153              
154              
155              
156              
157              
158              
159              
160              
161              
162              
163              
164              
165              
166              
167              
168              
169              
170              
171              
172              
173              
174              
175              
176              
177             sub close {
178 23     23 1 152 my ( $self, $in_global_destruction ) = @_;
179              
180             # don't bother closing the FH in global destruction (it'll be done
181             # on its own) or if we were passed a file handle in the output
182             # attribute.
183 23 100 66     184 return if $in_global_destruction or $self->_passed_fh;
184              
185             # fh is lazy, so the object may close without every using it, so
186             # don't inadvertently create it.
187 13 100       266 $self->fh->close if $self->has_fh;
188 13         715 $self->clear_fh;
189             }
190              
191             1;
192              
193             #
194             # This file is part of Data-Record-Serialize
195             #
196             # This software is Copyright (c) 2017 by Smithsonian Astrophysical Observatory.
197             #
198             # This is free software, licensed under:
199             #
200             # The GNU General Public License, Version 3, June 2007
201             #
202              
203             __END__