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   246 use strict;
  26         60  
  26         818  
4 26     26   167 use warnings;
  26         71  
  26         774  
5 26     26   154 use boolean qw(true false);
  26         60  
  26         166  
6              
7 26     26   13896 use Clone qw(clone);
  26         68545  
  26         1673  
8 26     26   11465 use DateTime::Format::Natural::Helpers qw(%flag);
  26         92  
  26         33061  
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   1114234 my $self = shift;
96 711741         1212920 my ($keyword) = @_;
97              
98 711741 100 66     2384842 return (exists $expand_prefix{$keyword} || exists $expand_suffix{$keyword}) ? true : false;
99             }
100              
101             sub _expand
102             {
103 20849     20849   154842 my $self = shift;
104 20849         46708 my ($keyword, $types_entry, $grammar) = @_;
105              
106 20849         63705 my %expand = (
107             prefix => \%expand_prefix,
108             suffix => \%expand_suffix,
109             );
110              
111 20849         39490 my (@expandable, @expansions);
112              
113 20849 50       64707 push @expandable, 'prefix' if exists $expand_prefix{$keyword};
114 20849 100       51022 push @expandable, 'suffix' if exists $expand_suffix{$keyword};
115              
116 20849         41265 foreach my $type (@expandable) {
117 39173         59925 my @elements = @{$expand{$type}->{$keyword}};
  39173         134694  
118              
119 39173         74688 foreach my $element (@elements) {
120 117519         211992 foreach my $entry (@$grammar) {
121 316692         1730665 my $types = clone($types_entry);
122              
123 316692         804302 $save->($type, $types, 'REGEXP');
124              
125 316692         7893032 my $new = clone($entry);
126              
127 316692 100       922839 if ($type eq 'prefix') {
128 165921         253579 my %definition;
129 165921         257844 while (my ($pos, $def) = each %{$new->[0]}) {
  583260         1606016  
130 417339         984245 $definition{$pos + 1} = $def;
131             }
132 165921         342123 %{$new->[0]} = %definition;
  165921         437295  
133              
134 165921         293881 my @indexes;
135 165921         245317 foreach my $aref (@{$new->[1]}) {
  165921         329525  
136 55206         164828 my @tmp = map $_ + 1, @$aref;
137 55206         145146 push @indexes, [ @tmp ];
138             }
139 165921         266775 @{$new->[1]} = @indexes;
  165921         293110  
140              
141 165921         248987 my @flags;
142 165921         248032 foreach my $aref (@{$new->[3]}) {
  165921         298432  
143 170586         242153 my @tmp;
144 170586         282269 foreach my $value (@$aref) {
145 284418 100       591330 if (ref $value eq 'HASH') {
146 229212         325644 my %hash;
147 229212         679411 while (my ($key, $val) = each %$value) {
148 229212 100       834864 $key++ if $key =~ /^\d+$/;
149 229212         713700 $hash{$key} = $val;
150             }
151 229212         718749 push @tmp, { %hash };
152             }
153             else {
154 55206         109110 push @tmp, $value + 1;
155             }
156             }
157 170586         415474 push @flags, [ @tmp ];
158             }
159 165921         263670 @{$new->[3]} = @flags;
  165921         503798  
160             }
161              
162             my %indexes = (
163             prefix => 0,
164 316692         498279 suffix => scalar keys %{$new->[0]},
  316692         845765  
165             );
166              
167 316692         600369 my $i = $indexes{$type};
168              
169 316692         1533457 $new->[0]->{$i} = $self->{data}->__RE($element);
170              
171 316692 100       863361 if (exists $data{$element}->{2}) {
172 211128         727266 $save->($type, $new->[1], [ $i ]);
173 211128         968740 $save->($type, $new->[2], $self->{data}->__extended_checks($data{$element}->{2}));
174             }
175              
176 316692 100       507716 push @{$new->[3]}, exists $data{$element}->{3} ? [ { $i => [ $data{$element}->{3} ] } ] : [ $i ];
  316692         1172054  
177              
178 316692         538250 push @{$new->[4]}, $data{$element}->{4};
  316692         581470  
179 316692         459475 push @{$new->[5]}, $data{$element}->{5};
  316692         599301  
180              
181 316692         460616 foreach my $key (keys %{$data{$element}->{6}}) {
  316692         851845  
182 316692         473813 push @{$new->[6]->{$key}}, @{$data{$element}->{6}->{$key}};
  316692         555030  
  316692         739511  
183             }
184              
185 316692         938002 push @expansions, [ $types, $new ];
186             }
187             }
188             }
189              
190 20849         119309 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