File Coverage

lib/Spreadsheet/Reader/ExcelXML/Types.pm
Criterion Covered Total %
statement 19 19 100.0
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 26 100.0


line stmt bran cond sub pod time code
1             package Spreadsheet::Reader::ExcelXML::Types;
2             our $AUTHORITY = 'cpan:JANDREW';
3 45     45   106761 use version; our $VERSION = version->declare('v0.16.8');
  45         1428  
  45         345  
4             ###LogSD warn "You uncovered internal logging statements for Spreadsheet::Reader::ExcelXML::Types-$VERSION";
5              
6 45     45   3715 use strict;
  45         56  
  45         796  
7 45     45   144 use warnings;
  45         46  
  45         1325  
8 45     45   15858 use Type::Utils -all;
  45         137883  
  45         386  
9             use Type::Library 1.000
10 45         264 -base,
11             -declare => qw(
12             XMLFile XLSXFile CellID
13             IOFileType ErrorString SubString
14             SpecialZeroScientific SpecialOneScientific SpecialTwoScientific
15             SpecialThreeScientific SpecialFourScientific SpecialFiveScientific
16             SpecialDecimal
17 45     45   85539 );
  45         888  
18 45     45   52502 use IO::File;
  45         105185  
  45         5076  
19 45     45   176 BEGIN{ extends "Types::Standard" };
20             my $try_xs =
21             exists($ENV{PERL_TYPE_TINY_XS}) ? !!$ENV{PERL_TYPE_TINY_XS} :
22             exists($ENV{PERL_ONLY}) ? !$ENV{PERL_ONLY} :
23             1;
24             if( $try_xs and exists $INC{'Type/Tiny/XS.pm'} ){
25             eval "use Type::Tiny::XS 0.010";
26             if( $@ ){
27             die "You have loaded Type::Tiny::XS but versions prior to 0.010 will cause this module to fail";
28             }
29             }
30              
31             #########1 Package Variables 3#########4#########5#########6#########7#########8#########9
32              
33              
34              
35             #########1 Type Library 3#########4#########5#########6#########7#########8#########9
36              
37             declare XMLFile,
38             as Str,
39             where{ $_ =~ /\.(xml|rels)$/i and -r $_},
40             message{
41             ( $_ !~ /\.(xml|rels)$/i ) ?
42             "The string -$_- does not have an xml file extension" :
43             ( !-r $_ ) ?
44             "Could not find / read the file: $_" :
45             'No value passed to the XMLFile test';
46             };
47              
48             declare XLSXFile,
49             as Str,
50             where{ $_ =~ /\.x(ls(x|m)|ml)$/i and -r $_ },
51             message{
52             my $test = $_;
53             my $return =
54             ( !defined $test ) ?
55             "Empty filename" :
56             ( ref $test ) ?
57             "'" . $test . "' is not a string value" :
58             ( $test !~ /\.x(ls(x|m)|ml)$/i ) ?
59             "The string -$test- does not have an xlsx|xlsm|xml file extension" :
60             ( -r $test) ?
61             "Could not find / read the file: $test" :
62             "Unmanageable value '" . ($test ? $test : '' ) . "' passed" ;
63             return $return;
64             };
65              
66             declare IOFileType,
67             as InstanceOf[ 'IO::File' ];#, 'File::Temp'
68              
69             coerce IOFileType,
70             from GlobRef,
71             via{ my $fh = bless( $_, 'IO::File' );
72             $fh->binmode();
73             return $fh; };
74              
75             coerce IOFileType,
76             from XMLFile,
77             via{ my $fh = IO::File->new( $_, 'r' );
78             $fh->binmode();
79             return $fh; };
80              
81             coerce IOFileType,
82             from XLSXFile,
83             via{ my $fh = IO::File->new( $_, 'r' );
84             $fh->binmode();
85             return $fh; };
86              
87             declare CellID,
88             as StrMatch[ qr/^[A-Z]{1,3}[1-9]\d*$/ ];
89              
90             declare SubString,
91             as Str;
92              
93             declare ErrorString,
94             as SubString,
95             where{ $_ !~ /\)\n;/ };
96              
97             coerce SubString,
98             from Object,
99             via{
100             my $object = $_;
101             if( $object->can( 'as_string' ) ){
102             return $object->as_string;
103             }elsif( $object->can( 'message' ) ){
104             return $object->message;
105             }
106             return $object;
107             };
108              
109             coerce ErrorString,
110             from SubString->coercibles,
111             via{
112             my $tmp = to_SubString($_);
113             $tmp =~ s/\)\n;/\);/g;
114             return $tmp;
115             };
116              
117             declare SpecialZeroScientific,
118             as Str,
119             where{ return $_ =~ /^\-?[0-9]+E-?\d{2,50}/i };#print "--$_\n";
120              
121             coerce SpecialZeroScientific,
122             from Str,
123             via{
124             my $string = $_;
125             $string =~ /([\-\d\.]+)[Ee](-)?(\d+)/i;#
126             #~ print "$1\n";
127             #~ print "$2\n";
128             #~ print "$3\n";
129             my $return = sprintf '%.0f', $1;
130             #~ print "$return\n";
131             $return .= 'E' . sprintf '%s%02d', $2, $3;
132             #~ print "$return\n";
133             return $return;
134             };
135              
136             declare SpecialOneScientific,
137             as Str,
138             where{ return $_ =~ /^\-?[0-9]+\.\dE-?\d{2,50}/i };#print "--$_\n";
139              
140             coerce SpecialOneScientific,
141             from Str,
142             via{
143             my $string = $_;
144             $string =~ /([\-\d\.]+)[Ee](-)?(\d+)/i;#
145             #~ print "$1\n";
146             #~ print "$2\n";
147             #~ print "$3\n";
148             my $return = sprintf '%.1f', $1;
149             #~ print "$return\n";
150             $return .= 'E' . sprintf '%s%02d', $2, $3;
151             #~ print "$return\n";
152             return $return;
153             };
154              
155             declare SpecialTwoScientific,
156             as Str,
157             where{ return $_ =~ /^\-?[0-9]+\.\d{2}E-?\d{2,50}/i };#print "--$_\n";
158              
159             coerce SpecialTwoScientific,
160             from Str,
161             via{
162             my $string = $_;
163             $string =~ /([\-\d\.]+)[Ee](-)?(\d+)/i;#
164             #~ print "$1\n";
165             #~ print "$2\n";
166             #~ print "$3\n";
167             my $return = sprintf '%.2f', $1;
168             #~ print "$return\n";
169             $return .= 'E' . sprintf '%s%02d', $2, $3;
170             #~ print "$return\n";
171             return $return;
172             };
173              
174             declare SpecialThreeScientific,
175             as Str,
176             where{ return $_ =~ /^\-?[0-9]+\.\d{3}E-?\d{2,50}/i };#print "--$_\n";
177              
178             coerce SpecialThreeScientific,
179             from Str,
180             via{
181             my $string = $_;
182             $string =~ /([\-\d\.]+)[Ee](-)?(\d+)/i;#
183             #~ print "$1\n";
184             #~ print "$2\n";
185             #~ print "$3\n";
186             my $return = sprintf '%.3f', $1;
187             #~ print "$return\n";
188             $return .= 'E' . sprintf '%s%02d', $2, $3;
189             #~ print "$return\n";
190             return $return;
191             };
192              
193             declare SpecialFourScientific,
194             as Str,
195             where{ return $_ =~ /^\-?[0-9]+\.\d{4}E-?\d{2,50}/i };#print "--$_\n";
196              
197             coerce SpecialFourScientific,
198             from Str,
199             via{
200             my $string = $_;
201             $string =~ /([\-\d\.]+)[Ee](-)?(\d+)/i;#
202             #~ print "$1\n";
203             #~ print "$2\n";
204             #~ print "$3\n";
205             my $return = sprintf '%.4f', $1;
206             #~ print "$return\n";
207             $return .= 'E' . sprintf '%s%02d', $2, $3;
208             #~ print "$return\n";
209             return $return;
210             };
211              
212             declare SpecialFiveScientific,
213             as Str,
214             where{ return $_ =~ /^\-?[0-9]+\.\d{5}E-?\d{2,50}/i };#print "--$_\n";
215              
216             coerce SpecialFiveScientific,
217             from Str,
218             via{
219             my $string = $_;
220             $string =~ /([\-\d\.]+)[Ee](-)?(\d+)/i;#
221             #~ print "$1\n";
222             #~ print "$2\n";
223             #~ print "$3\n";
224             my $return = sprintf '%.5f', $1;
225             #~ print "$return\n";
226             $return .= 'E' . sprintf '%s%02d', $2, $3;
227             #~ print "$return\n";
228             return $return;
229             };
230              
231             declare SpecialDecimal,
232             as Str,
233             where{ return $_ =~ /\.\d{1,9}$/i };#print "--$_\n";
234              
235             coerce SpecialDecimal,
236             from Str,
237             via{
238             my $string = $_;
239             my $return = sprintf '%.9f', $string;
240             #~ print "$return\n";
241             $return =~ /(.*[1-9])(0*)$/;
242             my $significant_decimal = $1;
243             #~ print "$significant_decimal\n";
244             return $significant_decimal;
245             };
246              
247             #~ declare PositiveNum,
248             #~ as Num,
249             #~ where{ $_ > 0 };
250              
251             #~ declare NegativeNum,
252             #~ as Num,
253             #~ where{ $_ < 0 };
254              
255             #~ declare ZeroOrUndef,
256             #~ as Maybe[Num],
257             #~ where{ !$_ };
258              
259             #~ declare NotNegativeNum,
260             #~ as Num,
261             #~ where{ $_ > -1 };
262              
263             #########1 Excel Defined Converions 4#########5#########6#########7#########8#########9
264              
265             #~ declare_coercion Excel_number_0,
266             #~ to_type Any, from Maybe[Any],
267             #~ via{ $_ };
268              
269             #########1 Public Attributes 3#########4#########5#########6#########7#########8#########9
270              
271              
272              
273             #########1 Private Methods 3#########4#########5#########6#########7#########8#########9
274              
275              
276             #########1 Phinish 3#########4#########5#########6#########7#########8#########9
277              
278             __PACKAGE__->meta->make_immutable;
279             1;
280              
281             #########1 Documentation 3#########4#########5#########6#########7#########8#########9
282             __END__
283              
284             =head1 NAME
285              
286             Spreadsheet::Reader::ExcelXML::Types - A type library for the ExcelXML reader
287              
288             =head1 DESCRIPTION
289              
290             This documentation is written to explain ways to use this module. To use the general
291             package for excel parsing out of the box please review the documentation for L<Workbooks
292             |Spreadsheet::Reader::ExcelXML::Workbook>, L<Worksheets
293             |Spreadsheet::Reader::ExcelXML::Worksheet>, and
294             L<Cells|Spreadsheet::Reader::ExcelXML::Cell>.
295              
296             This is a L<Type::Library|Type::Tiny::Manual::Libraries> for this package. There are no
297             real tricks here outside of the standard Type::Tiny stuf. For the cool number and date
298             formatting implementation see L<Spreadsheet::Reader::Format::ParseExcelFormatStrings>.
299              
300             =head1 TYPES
301              
302             =head2 XMLFile
303              
304             This type checks that the value is a readable file (full path - no file find magic
305             used) with an \.xml extention
306              
307             =head3 coercions
308              
309             none
310              
311             =head2 XLSXFile
312              
313             This type checks that the value is a readable file (full path - no file find magic
314             used) with an \.xlsx, \.xlsm, or \.xml extention
315              
316             =head3 coercions
317              
318             none
319              
320             =head2 IOFileType
321              
322             This is set as an L<instance of|Types::Standard/InstanceOf[`a]> 'IO::File'
323              
324             =head3 coercions
325              
326             =over
327              
328             B<GlobRef:> by blessing it into an IO::File instance 'via{ bless $_, 'IO::File' }'
329              
330             B<XLSXFile:> by opening it as an IO::File instance 'via{ IO::File->new( $_, 'r' ); }'
331              
332             B<XMLFile:> by opening it as an IO::File instance 'via{ IO::File->new( $_, 'r' ); }'
333              
334             =back
335              
336             =head2 ParserType
337              
338             For now this type checks that the parser type string == 'reader'. As future parser
339             types are added to the package I will update this type.
340              
341             =head3 coercions
342              
343             =over
344              
345             B<Str:> this will lower case any other version of the string 'reader' (Reader| READER)
346             to get it to pass
347              
348             =back
349              
350             =head2 PositiveNum
351              
352             This type checks that the value is a number and is greater than 0
353              
354             =head3 coercions
355              
356             none
357              
358             =head2 NegativeNum
359              
360             This type checks that the value is a number and is less than 0
361              
362             =head3 coercions
363              
364             none
365              
366             =head2 ZeroOrUndef
367              
368             This type allows the value to be the number 0 or undef
369              
370             =head3 coercions
371              
372             none
373              
374             =head2 NotNegativeNum
375              
376             This type checks that the value is a number and that the number is greater than
377             or equal to 0
378              
379             =head3 coercions
380              
381             none
382              
383             =head2 CellID
384              
385             this is a value that passes the following regular expression test; qr/^[A-Z]{1,3}[1-9]\d*$/
386              
387             =head3 coercions
388              
389             none
390              
391             =head2 SubString
392              
393             This is a precurser type to ErrorString. It is used to perform the first layer of coersions
394             so that error objects can be consumed as-is in this package when a subcomponent throws an
395             object rather than a string as an error.
396              
397             =head3 coercions
398              
399             =over
400              
401             B<Object:> it will test the object for two methods and if either one is present it will use
402             the results of that method as the string. The methods in order are; 'as_string' and 'message'
403              
404             =back
405              
406             =head2 ErrorString
407              
408             This is a string that can't match the following sequence /\)\n;/
409             #I don't even remember why that sequence is bad but it is
410              
411             =head3 coercions
412              
413             =over
414              
415             B<SubString:> by using the following substitution on the string; s/\)\n;/\);/g
416              
417             =back
418              
419             =head1 NAMED COERCIONS
420              
421             =head2 Excel_number_0
422              
423             This is essentially a pass through coercion used as a convenience rather than writing the
424             pass through each time a coercion is needed but no actual work should be performed on the
425             value
426              
427             =head1 SUPPORT
428              
429             =over
430              
431             L<github Spreadsheet::XLSX::Reader::LibXML/issues
432             |https://github.com/jandrew/p5-spreadsheet-reader-excelxml/issues>
433              
434             =back
435              
436             =head1 TODO
437              
438             =over
439              
440             B<1.> The ErrorString type tests still needs a 'fail' case
441              
442             =back
443              
444             =head1 AUTHOR
445              
446             =over
447              
448             =item Jed Lund
449              
450             =item jandrew@cpan.org
451              
452             =back
453              
454             =head1 COPYRIGHT
455              
456             This program is free software; you can redistribute
457             it and/or modify it under the same terms as Perl itself.
458              
459             The full text of the license can be found in the
460             LICENSE file included with this module.
461              
462             This software is copyrighted (c) 2016 by Jed Lund
463              
464             =head1 DEPENDENCIES
465              
466             =over
467              
468             L<Spreadsheet::Reader::ExcelXML> - the package
469              
470             =back
471              
472             =head1 SEE ALSO
473              
474             =over
475              
476             L<Spreadsheet::Read> - generic Spreadsheet reader
477              
478             L<Spreadsheet::ParseExcel> - Excel binary version 2003 and earlier (.xls files)
479              
480             L<Spreadsheet::XLSX> - Excel version 2007 and later
481              
482             L<Spreadsheet::ParseXLSX> - Excel version 2007 and later
483              
484             L<Log::Shiras|https://github.com/jandrew/Log-Shiras>
485              
486             =over
487              
488             All lines in this package that use Log::Shiras are commented out
489              
490             =back
491              
492             =back
493              
494             =cut
495              
496             #########1#########2 main pod documentation end 5#########6#########7#########8#########9