File Coverage

blib/lib/DateTime/Format/Builder/Parser/generic.pm
Criterion Covered Total %
statement 42 42 100.0
branch 23 30 76.6
condition 2 3 66.6
subroutine 8 8 100.0
pod 2 2 100.0
total 77 85 90.5


line stmt bran cond sub pod time code
1             package DateTime::Format::Builder::Parser::generic;
2              
3 24     24   163 use strict;
  24         76  
  24         736  
4 24     24   133 use warnings;
  24         47  
  24         895  
5              
6             our $VERSION = '0.82';
7              
8 24     24   124 use Carp;
  24         46  
  24         1359  
9 24         10073 use Params::Validate qw(
10             validate SCALAR CODEREF UNDEF
11 24     24   151 );
  24         45  
12              
13             sub new {
14 63     63 1 143 my $class = shift;
15 63         245 bless {@_}, $class;
16             }
17              
18             sub generic_parser {
19 63     63 1 134 my $class = shift;
20             my %args = validate(
21             @_,
22             {
23             (
24 63         155 map { $_ => { type => CODEREF, optional => 1 } }
  252         1784  
25             qw(
26             on_match on_fail preprocess postprocess
27             )
28             ),
29             label => { type => SCALAR | UNDEF, optional => 1 },
30             }
31             );
32 63         384 my $label = $args{label};
33              
34             my $callback
35 63 100 66     312 = ( exists $args{on_match} or exists $args{on_fail} ) ? 1 : undef;
36              
37             return sub {
38 84     84   201 my ( $self, $date, $p, @args ) = @_;
39 84 50       192 return unless defined $date;
40 84         140 my %p;
41 84 50       239 %p = %$p if $p; # Look! A Copy!
42              
43 84 50       305 my %param = (
    100          
44             self => $self,
45             ( defined $label ? ( label => $label ) : () ),
46             ( @args ? ( args => \@args ) : () ),
47             );
48              
49             # Preprocess - can modify $date and fill %p
50 84 100       218 if ( $args{preprocess} ) {
51             $date = $args{preprocess}
52 8         33 ->( input => $date, parsed => \%p, %param );
53             }
54              
55 84 50       1166 my $rv = $class->do_match( $date, @args ) if $class->can('do_match');
56              
57             # Funky callback thing
58 84 100       215 if ($callback) {
59 6 100       14 my $type = defined $rv ? "on_match" : "on_fail";
60 6 50       35 $args{$type}->( input => $date, %param ) if $args{$type};
61             }
62 84 100       2454 return unless defined $rv;
63              
64 44         76 my $dt;
65 44 50       245 $dt = $class->post_match( $date, $rv, \%p )
66             if $class->can('post_match');
67              
68             # Allow post processing. Return undef if regarded as failure
69 44 100       141 if ( $args{postprocess} ) {
70 10         39 my $rv = $args{postprocess}->(
71             parsed => \%p,
72             input => $date,
73             post => $dt,
74             %param,
75             );
76 10 50       93 return unless $rv;
77             }
78              
79             # A successful match!
80 44 100       211 $dt = $class->make( $date, $dt, \%p ) if $class->can('make');
81 44         72655 return $dt;
82 63         657 };
83             }
84              
85             {
86 24     24   188 no strict 'refs';
  24         55  
  24         1675  
87             for (qw( valid_params params )) {
88             *$_ = *{"DateTime::Format::Builder::Parser::$_"};
89             }
90             }
91              
92             1;
93              
94             # ABSTRACT: Useful routines
95              
96             __END__
97              
98             =pod
99              
100             =encoding UTF-8
101              
102             =head1 NAME
103              
104             DateTime::Format::Builder::Parser::generic - Useful routines
105              
106             =head1 VERSION
107              
108             version 0.82
109              
110             =head1 METHODS
111              
112             =head2 Useful
113              
114             =head3 new
115              
116             Standard constructor. Returns a blessed hash; any arguments are placed
117             in the hash. This is useful for storing information between methods.
118              
119             =head3 generic_parser
120              
121             This is a method provided solely for the benefit of
122             C<Parser> implementations. It semi-neatly abstracts
123             a lot of the work involved.
124              
125             Basically, it takes parameters matching the assorted
126             callbacks from the parser declarations and makes a coderef
127             out of it all.
128              
129             Currently recognized callbacks are:
130              
131             =over 4
132              
133             =item *
134              
135             on_match
136              
137             =item *
138              
139             on_fail
140              
141             =item *
142              
143             preprocess
144              
145             =item *
146              
147             postprocess
148              
149             =back
150              
151             =head2 Methods for subclassing
152              
153             These are methods you should define when writing your own subclass.
154              
155             B<Note>: these methods do not exist in this class. There is no point
156             trying to call C<< $self->SUPER::do_match( ... ) >>.
157              
158             =head3 do_match
159              
160             C<do_match> is the first phase. Arguments are the date and @args.
161             C<self>, C<label>, C<args>. Return value must be defined if you match
162             successfully.
163              
164             =head3 post_match
165              
166             C<post_match> is called after the appropriate callback out of
167             C<on_match>/C<on_fail> is done. It's passed the date, the return
168             value from C<do_match> and the parsing hash.
169              
170             Its return value is used as the C<post> argument to the C<postprocess>
171             callback, and as the second argument to C<make>.
172              
173             =head3 make
174              
175             C<make> takes the original input, the return value from C<post_match>
176             and the parsing hash and should return a C<DateTime> object or
177             undefined.
178              
179             =head2 Delegations
180              
181             For use of C<Parser>, this module also delegates C<valid_params> and
182             C<params>. This is just convenience to save typing the following:
183              
184             DateTime::Format::Builder::Parser->valid_params( blah )
185              
186             Instead we get to type:
187              
188             $self->valid_params( blah );
189             __PACKAGE__->valid_params( blah );
190              
191             =head1 WRITING A SUBCLASS
192              
193             Rather than attempt to explain how it all works, I think it's best if
194             you take a look at F<Regex.pm> and F<Strptime.pm> as examples and
195             work from there.
196              
197             =head1 SEE ALSO
198              
199             C<datetime@perl.org> mailing list.
200              
201             http://datetime.perl.org/
202              
203             L<perl>, L<DateTime>, L<DateTime::Format::Builder>,
204             L<DateTime::Format::Builder::Parser>.
205              
206             =head1 SUPPORT
207              
208             Bugs may be submitted at L<http://rt.cpan.org/Public/Dist/Display.html?Name=DateTime-Format-Builder> or via email to L<bug-datetime-format-builder@rt.cpan.org|mailto:bug-datetime-format-builder@rt.cpan.org>.
209              
210             I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>.
211              
212             =head1 SOURCE
213              
214             The source code repository for DateTime-Format-Builder can be found at L<https://github.com/houseabsolute/DateTime-Format-Builder>.
215              
216             =head1 AUTHORS
217              
218             =over 4
219              
220             =item *
221              
222             Dave Rolsky <autarch@urth.org>
223              
224             =item *
225              
226             Iain Truskett
227              
228             =back
229              
230             =head1 COPYRIGHT AND LICENSE
231              
232             This software is Copyright (c) 2019 by Dave Rolsky.
233              
234             This is free software, licensed under:
235              
236             The Artistic License 2.0 (GPL Compatible)
237              
238             The full text of the license can be found in the
239             F<LICENSE> file included with this distribution.
240              
241             =cut