File Coverage

blib/lib/DateTime/Format/Natural/Expand.pm
Criterion Covered Total %
statement 81 81 100.0
branch 15 16 93.7
condition 2 3 66.6
subroutine 7 7 100.0
pod n/a
total 105 107 98.1


line stmt bran cond sub pod time code
1             package DateTime::Format::Natural::Expand;
2              
3 26     26   251 use strict;
  26         60  
  26         829  
4 26     26   155 use warnings;
  26         61  
  26         868  
5 26     26   172 use boolean qw(true false);
  26         60  
  26         193  
6              
7 26     26   14290 use Clone qw(clone);
  26         69188  
  26         1682  
8 26     26   12098 use DateTime::Format::Natural::Helpers qw(%flag);
  26         84  
  26         32388  
9              
10             our $VERSION = '0.04';
11              
12             my %data = (
13             time => {
14             4 => {},
15             5 => '_time',
16             6 => { truncate_to => [q(hour_minute_second)] },
17             },
18             time_min => {
19             4 => {},
20             5 => '_time',
21             6 => { truncate_to => [q(minute_second)] },
22             },
23             time_am => {
24             2 => 'meridiem',
25             3 => $flag{time_am},
26             4 => {},
27             5 => '_at',
28             6 => { truncate_to => [q(hour_minute_second)] },
29             },
30             time_pm => {
31             2 => 'meridiem',
32             3 => $flag{time_pm},
33             4 => {},
34             5 => '_at',
35             6 => { truncate_to => [q(hour_minute_second)] },
36             },
37             );
38              
39             my %expand_prefix = (
40             date_literal_variant => [ qw( time_min time_am time_pm) ],
41             week_variant => [ qw( time_min time_am time_pm) ],
42             month_variant => [ qw( time_min time_am time_pm) ],
43             year_variant => [ qw( time_min time_am time_pm) ],
44             weekday_variant_week => [ qw(time time_am time_pm) ],
45             variant_week_weekday => [ qw(time time_am time_pm) ],
46             final_weekday_in_month => [ qw(time time_am time_pm) ],
47             month_day => [ qw( time_min time_am time_pm) ],
48             day_month_variant_year => [ qw( time_min time_am time_pm) ],
49             day_month_year_ago => [ qw( time_min time_am time_pm) ],
50             count_weekday => [ qw( time_min time_am time_pm) ],
51             count_yearday => [ qw( time_min time_am time_pm) ],
52             count_weekday_from_now => [ qw( time_min time_am time_pm) ],
53             count_day_variant_week => [ qw( time_min time_am time_pm) ],
54             count_day_variant_month => [ qw( time_min time_am time_pm) ],
55             count_month_variant_year => [ qw( time_min time_am time_pm) ],
56             count_weekday_variant_month => [ qw( time_min time_am time_pm) ],
57             count_weekday_in_month => [ qw( time_min time_am time_pm) ],
58             count_yearday_variant_year => [ qw( time_min time_am time_pm) ],
59             );
60             my %expand_suffix = (
61             date_literal_variant => [ qw( time_min time_am time_pm) ],
62             week_variant => [ qw( time_min time_am time_pm) ],
63             month_variant => [ qw( time_min time_am time_pm) ],
64             year_variant => [ qw( time_min time_am time_pm) ],
65             weekday_variant_week => [ qw(time time_am time_pm) ],
66             variant_week_weekday => [ qw(time time_am time_pm) ],
67             final_weekday_in_month => [ qw(time time_am time_pm) ],
68             day_month_variant_year => [ qw( time_min time_am time_pm) ],
69             day_month_year_ago => [ qw( time_min time_am time_pm) ],
70             count_weekday => [ qw( time_min time_am time_pm) ],
71             count_yearday => [ qw( time_min time_am time_pm) ],
72             count_weekday_from_now => [ qw( time_min time_am time_pm) ],
73             count_day_variant_week => [ qw( time_min time_am time_pm) ],
74             count_day_variant_month => [ qw( time_min time_am time_pm) ],
75             count_month_variant_year => [ qw( time_min time_am time_pm) ],
76             count_weekday_variant_month => [ qw( time_min time_am time_pm) ],
77             count_weekday_in_month => [ qw( time_min time_am time_pm) ],
78             count_yearday_variant_year => [ qw( time_min time_am time_pm) ],
79             );
80              
81             my $save = sub
82             {
83             my ($type, $target, @values) = @_;
84              
85             if ($type eq 'prefix') {
86             unshift @$target, @values;
87             }
88             elsif ($type eq 'suffix') {
89             push @$target, @values;
90             }
91             };
92              
93             sub _expand_for
94             {
95 711741     711741   1109925 my $self = shift;
96 711741         1206051 my ($keyword) = @_;
97              
98 711741 100 66     2393006 return (exists $expand_prefix{$keyword} || exists $expand_suffix{$keyword}) ? true : false;
99             }
100              
101             sub _expand
102             {
103 21801     21801   160770 my $self = shift;
104 21801         49394 my ($keyword, $types_entry, $grammar) = @_;
105              
106 21801         67112 my %expand = (
107             prefix => \%expand_prefix,
108             suffix => \%expand_suffix,
109             );
110              
111 21801         39774 my (@expandable, @expansions);
112              
113 21801 50       67765 push @expandable, 'prefix' if exists $expand_prefix{$keyword};
114 21801 100       56412 push @expandable, 'suffix' if exists $expand_suffix{$keyword};
115              
116 21801         43226 foreach my $type (@expandable) {
117 41658         64500 my @elements = @{$expand{$type}->{$keyword}};
  41658         142893  
118              
119 41658         77388 foreach my $element (@elements) {
120 124974         236490 foreach my $entry (@$grammar) {
121 338448         1851013 my $types = clone($types_entry);
122              
123 338448         867145 $save->($type, $types, 'REGEXP');
124              
125 338448         8508997 my $new = clone($entry);
126              
127 338448 100       994483 if ($type eq 'prefix') {
128 175056         268284 my %definition;
129 175056         269695 while (my ($pos, $def) = each %{$new->[0]}) {
  608046         1680962  
130 432990         1046060 $definition{$pos + 1} = $def;
131             }
132 175056         366687 %{$new->[0]} = %definition;
  175056         472642  
133              
134 175056         306311 my @indexes;
135 175056         260392 foreach my $aref (@{$new->[1]}) {
  175056         337032  
136 53343         161920 my @tmp = map $_ + 1, @$aref;
137 53343         140339 push @indexes, [ @tmp ];
138             }
139 175056         275566 @{$new->[1]} = @indexes;
  175056         316329  
140              
141 175056         280860 my @flags;
142 175056         254330 foreach my $aref (@{$new->[3]}) {
  175056         310578  
143 179721         253832 my @tmp;
144 179721         289864 foreach my $value (@$aref) {
145 291018 100       619713 if (ref $value eq 'HASH') {
146 237675         336186 my %hash;
147 237675         705730 while (my ($key, $val) = each %$value) {
148 237675 100       902777 $key++ if $key =~ /^\d+$/;
149 237675         753331 $hash{$key} = $val;
150             }
151 237675         732122 push @tmp, { %hash };
152             }
153             else {
154 53343         105618 push @tmp, $value + 1;
155             }
156             }
157 179721         434238 push @flags, [ @tmp ];
158             }
159 175056         272478 @{$new->[3]} = @flags;
  175056         532770  
160             }
161              
162             my %indexes = (
163             prefix => 0,
164 338448         552611 suffix => scalar keys %{$new->[0]},
  338448         925760  
165             );
166              
167 338448         655257 my $i = $indexes{$type};
168              
169 338448         1672460 $new->[0]->{$i} = $self->{data}->__RE($element);
170              
171 338448 100       925818 if (exists $data{$element}->{2}) {
172 225632         765836 $save->($type, $new->[1], [ $i ]);
173 225632         1033581 $save->($type, $new->[2], $self->{data}->__extended_checks($data{$element}->{2}));
174             }
175              
176 338448 100       531040 push @{$new->[3]}, exists $data{$element}->{3} ? [ { $i => [ $data{$element}->{3} ] } ] : [ $i ];
  338448         1272080  
177              
178 338448         571131 push @{$new->[4]}, $data{$element}->{4};
  338448         627476  
179 338448         495638 push @{$new->[5]}, $data{$element}->{5};
  338448         639525  
180              
181 338448         510678 foreach my $key (keys %{$data{$element}->{6}}) {
  338448         890954  
182 338448         492402 push @{$new->[6]->{$key}}, @{$data{$element}->{6}->{$key}};
  338448         613559  
  338448         792918  
183             }
184              
185 338448         1025311 push @expansions, [ $types, $new ];
186             }
187             }
188             }
189              
190 21801         126805 return @expansions;
191             }
192              
193             1;
194             __END__
195              
196             =head1 NAME
197              
198             DateTime::Format::Natural::Expand - Expand grammar at runtime
199              
200             =head1 SYNOPSIS
201              
202             Please see the DateTime::Format::Natural documentation.
203              
204             =head1 DESCRIPTION
205              
206             C<DateTime::Format::Natural::Expand> dynamically expands the grammar
207             at runtime in order to allow for additional time to be parsed.
208              
209             =head1 SEE ALSO
210              
211             L<DateTime::Format::Natural>
212              
213             =head1 AUTHOR
214              
215             Steven Schubiger <schubiger@cpan.org>
216              
217             =head1 LICENSE
218              
219             This program is free software; you may redistribute it and/or
220             modify it under the same terms as Perl itself.
221              
222             See L<http://dev.perl.org/licenses/>
223              
224             =cut