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   352 use strict;
  24         52  
  24         615  
4 24     24   110 use warnings;
  24         44  
  24         897  
5              
6             our $VERSION = '0.83';
7              
8 24     24   118 use Params::Validate qw( validate ARRAYREF SCALARREF HASHREF CODEREF );
  24         45  
  24         1360  
9              
10 24     24   125 use parent 'DateTime::Format::Builder::Parser::generic';
  24         43  
  24         113  
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 78 my $self = shift;
43 41         69 my $date = shift;
44 41         335 my @matches = $date =~ $self->{regex};
45 41 100       151 return @matches ? \@matches : undef;
46             }
47              
48             sub post_match {
49 30     30 1 61 my $self = shift;
50 30         71 my ( $date, $matches, $p ) = @_;
51              
52             # Fill %p from match
53 30         53 @{$p}{ @{ $self->{params} } } = @$matches;
  30         126  
  30         63  
54 30         73 return;
55             }
56              
57             sub make {
58 30     30 1 54 my $self = shift;
59 30         68 my ( $date, $dt, $p ) = @_;
60 30         84 my @args = ( %$p, %{ $self->{extra} } );
  30         99  
61 30 100       88 if ( my $cons = $self->{constructor} ) {
62 5 100       20 if ( ref $cons eq 'ARRAY' ) {
    50          
63 3         7 my ( $class, $method ) = @$cons;
64 3         21 return $class->$method(@args);
65             }
66             elsif ( ref $cons eq 'CODE' ) {
67 2         7 return $self->$cons(@args);
68             }
69             }
70             else {
71 25         134 return DateTime->new(@args);
72             }
73             }
74              
75             sub create_parser {
76 34     34 0 111 my ( $self, %args ) = @_;
77 34   100     170 $args{extra} ||= {};
78 34 50       100 unless ( ref $self ) {
79 34         176 $self = $self->new(%args);
80             }
81              
82             # Create our parser
83             return $self->generic_parser(
84             (
85 136 100       414 map { exists $args{$_} ? ( $_ => $args{$_} ) : () }
86             qw(
87             on_match on_fail preprocess postprocess
88             )
89             ),
90             label => $args{label},
91 34         85 );
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.83
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 L<common keys|DateTime::Format::Builder/"SINGLE
122             SPECIFICATIONS">, C<Regex> supports:
123              
124             =over 4
125              
126             =item * regex
127              
128             B<regex> is a regular expression that should capture elements of the datetime
129             string. This is a required element. This is the key whose presence indicates
130             it's a specification that belongs to this class.
131              
132             =item * params
133              
134             B<params> is an arrayref of key names. The captures from the regex are mapped
135             to these (C<$1> to the first element, C<$2> to the second, and so on) and
136             handed to C<< DateTime->new >>. This is a required element.
137              
138             =item * extra
139              
140             B<extra> is a hashref of extra arguments you wish to give to C<< DateTime->new
141             >>. For example, you could set the C<year> or C<time_zone> to defaults:
142              
143             extra => { year => 2004, time_zone => "Australia/Sydney" },
144              
145             =item *
146              
147             B<constructor> is either an arrayref or a coderef. If an arrayref then the
148             first element is a class name or object, and the second element is a method
149             name (or coderef since Perl allows that sort of thing). The arguments to the
150             call are anything in C<$p> and anything given in the C<extra> option above.
151              
152             If only a coderef is supplied, then it is called with arguments of C<$self>,
153             C<$p> and C<extra>.
154              
155             In short:
156              
157             $self->$coderef( %{$p}, %{ $self->{extra} } );
158              
159             The method is expected to return a valid L<DateTime> object, or C<undef> in
160             event of failure, but can conceivably return anything it likes. So long as
161             it's 'true'.
162              
163             =back
164              
165             =head1 SEE ALSO
166              
167             C<datetime@perl.org> mailing list.
168              
169             http://datetime.perl.org/
170              
171             L<perl>, L<DateTime>,
172             L<DateTime::Format::Builder>
173              
174             =head1 SUPPORT
175              
176             Bugs may be submitted at L<https://github.com/houseabsolute/DateTime-Format-Builder/issues>.
177              
178             I am also usually active on IRC as 'autarch' on C<irc://irc.perl.org>.
179              
180             =head1 SOURCE
181              
182             The source code repository for DateTime-Format-Builder can be found at L<https://github.com/houseabsolute/DateTime-Format-Builder>.
183              
184             =head1 AUTHORS
185              
186             =over 4
187              
188             =item *
189              
190             Dave Rolsky <autarch@urth.org>
191              
192             =item *
193              
194             Iain Truskett <spoon@cpan.org>
195              
196             =back
197              
198             =head1 COPYRIGHT AND LICENSE
199              
200             This software is Copyright (c) 2020 by Dave Rolsky.
201              
202             This is free software, licensed under:
203              
204             The Artistic License 2.0 (GPL Compatible)
205              
206             The full text of the license can be found in the
207             F<LICENSE> file included with this distribution.
208              
209             =cut