File Coverage

blib/lib/DateTime/Format/Builder/Parser/Regex.pm
Criterion Covered Total %
statement 38 38 100.0
branch 10 12 83.3
condition 2 2 100.0
subroutine 8 8 100.0
pod 3 4 75.0
total 61 64 95.3


line stmt bran cond sub pod time code
1             package DateTime::Format::Builder::Parser::Regex;
2              
3 24     24   162 use strict;
  24         48  
  24         727  
4 24     24   124 use warnings;
  24         47  
  24         1011  
5              
6             our $VERSION = '0.82';
7              
8 24     24   142 use Params::Validate qw( validate ARRAYREF SCALARREF HASHREF CODEREF );
  24         47  
  24         1322  
9              
10 24     24   138 use parent 'DateTime::Format::Builder::Parser::generic';
  24         47  
  24         133  
11              
12             __PACKAGE__->valid_params(
13              
14             # How to match
15             params => {
16             type => ARRAYREF, # mapping $1,$2,... to new() args
17             },
18             regex => {
19             type => SCALARREF,
20             callbacks => {
21             'is a regex' => sub { ref(shift) eq 'Regexp' }
22             }
23             },
24              
25             # How to create
26             extra => {
27             type => HASHREF,
28             optional => 1,
29             },
30             constructor => {
31             type => CODEREF | ARRAYREF,
32             optional => 1,
33             callbacks => {
34             'array has 2 elements' => sub {
35             ref( $_[0] ) eq 'ARRAY' ? ( @{ $_[0] } == 2 ) : 1;
36             }
37             }
38             },
39             );
40              
41             sub do_match {
42 41     41 1 86 my $self = shift;
43 41         73 my $date = shift;
44 41         347 my @matches = $date =~ $self->{regex};
45 41 100       171 return @matches ? \@matches : undef;
46             }
47              
48             sub post_match {
49 30     30 1 74 my $self = shift;
50 30         71 my ( $date, $matches, $p ) = @_;
51              
52             # Fill %p from match
53 30         58 @{$p}{ @{ $self->{params} } } = @$matches;
  30         132  
  30         63  
54 30         81 return;
55             }
56              
57             sub make {
58 30     30 1 58 my $self = shift;
59 30         73 my ( $date, $dt, $p ) = @_;
60 30         84 my @args = ( %$p, %{ $self->{extra} } );
  30         105  
61 30 100       93 if ( my $cons = $self->{constructor} ) {
62 5 100       21 if ( ref $cons eq 'ARRAY' ) {
    50          
63 3         9 my ( $class, $method ) = @$cons;
64 3         53 return $class->$method(@args);
65             }
66             elsif ( ref $cons eq 'CODE' ) {
67 2         8 return $self->$cons(@args);
68             }
69             }
70             else {
71 25         132 return DateTime->new(@args);
72             }
73             }
74              
75             sub create_parser {
76 34     34 0 118 my ( $self, %args ) = @_;
77 34   100     193 $args{extra} ||= {};
78 34 50       90 unless ( ref $self ) {
79 34         207 $self = $self->new(%args);
80             }
81              
82             # Create our parser
83             return $self->generic_parser(
84             (
85 136 100       416 map { exists $args{$_} ? ( $_ => $args{$_} ) : () }
86             qw(
87             on_match on_fail preprocess postprocess
88             )
89             ),
90             label => $args{label},
91 34         104 );
92             }
93              
94             1;
95              
96             # ABSTRACT: Regex based date parsing
97              
98             __END__
99              
100             =pod
101              
102             =encoding UTF-8
103              
104             =head1 NAME
105              
106             DateTime::Format::Builder::Parser::Regex - Regex based date parsing
107              
108             =head1 VERSION
109              
110             version 0.82
111              
112             =head1 SYNOPSIS
113              
114             my $parser = DateTime::Format::Builder->create_parser(
115             regex => qr/^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)$/,
116             params => [ qw( year month day hour minute second ) ],
117             );
118              
119             =head1 SPECIFICATION
120              
121             In addition to the
122             L<common keys|DateTime::Format::Builder/"SINGLE SPECIFICATIONS">,
123             C<Regex> supports:
124              
125             =over 4
126              
127             =item *
128              
129             B<regex> is a regular expression that should capture
130             elements of the datetime string.
131             This is a required element. This is the key whose presence
132             indicates it's a specification that belongs to this class.
133              
134             =item *
135              
136             B<params> is an arrayref of key names. The captures from the
137             regex are mapped to these (C<$1> to the first element, C<$2>
138             to the second, and so on) and handed to
139             C<< DateTime->new() >>.
140             This is a required element.
141              
142             =item *
143              
144             B<extra> is a hashref of extra arguments you wish to give to
145             C<< DateTime->new() >>. For example, you could set the
146             C<year> or C<time_zone> to defaults:
147              
148             extra => { year => 2004, time_zone => "Australia/Sydney" },
149              
150             =item *
151              
152             B<constructor> is either an arrayref or a coderef. If an arrayref
153             then the first element is a class name or object, and the second
154             element is a method name (or coderef since Perl allows that sort of
155             thing). The arguments to the call are anything in C<$p> and
156             anything given in the C<extra> option above.
157              
158             If only a coderef is supplied, then it is called with arguments of
159             C<$self>, C<$p> and C<extra>.
160              
161             In short:
162              
163             $self->$coderef( %$p, %{ $self->{extra} } );
164              
165             The method is expected to return a valid L<DateTime> object,
166             or undef in event of failure, but can conceivably return anything
167             it likes. So long as it's 'true'.
168              
169             =back
170              
171             =head1 SEE ALSO
172              
173             C<datetime@perl.org> mailing list.
174              
175             http://datetime.perl.org/
176              
177             L<perl>, L<DateTime>,
178             L<DateTime::Format::Builder>
179              
180             =head1 SUPPORT
181              
182             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>.
183              
184             I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>.
185              
186             =head1 SOURCE
187              
188             The source code repository for DateTime-Format-Builder can be found at L<https://github.com/houseabsolute/DateTime-Format-Builder>.
189              
190             =head1 AUTHORS
191              
192             =over 4
193              
194             =item *
195              
196             Dave Rolsky <autarch@urth.org>
197              
198             =item *
199              
200             Iain Truskett
201              
202             =back
203              
204             =head1 COPYRIGHT AND LICENSE
205              
206             This software is Copyright (c) 2019 by Dave Rolsky.
207              
208             This is free software, licensed under:
209              
210             The Artistic License 2.0 (GPL Compatible)
211              
212             The full text of the license can be found in the
213             F<LICENSE> file included with this distribution.
214              
215             =cut