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   231 use strict;
  26         61  
  26         788  
4 26     26   156 use warnings;
  26         71  
  26         755  
5 26     26   142 use boolean qw(true false);
  26         68  
  26         149  
6              
7 26     26   13132 use Clone qw(clone);
  26         64052  
  26         1623  
8 26     26   10973 use DateTime::Format::Natural::Helpers qw(%flag);
  26         87  
  26         30058  
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   1086112 my $self = shift;
96 711741         1207920 my ($keyword) = @_;
97              
98 711741 100 66     2401601 return (exists $expand_prefix{$keyword} || exists $expand_suffix{$keyword}) ? true : false;
99             }
100              
101             sub _expand
102             {
103 20105     20105   143867 my $self = shift;
104 20105         45246 my ($keyword, $types_entry, $grammar) = @_;
105              
106 20105         61632 my %expand = (
107             prefix => \%expand_prefix,
108             suffix => \%expand_suffix,
109             );
110              
111 20105         37688 my (@expandable, @expansions);
112              
113 20105 50       61989 push @expandable, 'prefix' if exists $expand_prefix{$keyword};
114 20105 100       51201 push @expandable, 'suffix' if exists $expand_suffix{$keyword};
115              
116 20105         40298 foreach my $type (@expandable) {
117 36612         57036 my @elements = @{$expand{$type}->{$keyword}};
  36612         123735  
118              
119 36612         66975 foreach my $element (@elements) {
120 109836         196596 foreach my $entry (@$grammar) {
121 255516         1414393 my $types = clone($types_entry);
122              
123 255516         644136 $save->($type, $types, 'REGEXP');
124              
125 255516         6535740 my $new = clone($entry);
126              
127 255516 100       742311 if ($type eq 'prefix') {
128 138552         212984 my %definition;
129 138552         210636 while (my ($pos, $def) = each %{$new->[0]}) {
  497616         1344899  
130 359064         849961 $definition{$pos + 1} = $def;
131             }
132 138552         276740 %{$new->[0]} = %definition;
  138552         372577  
133              
134 138552         237501 my @indexes;
135 138552         196347 foreach my $aref (@{$new->[1]}) {
  138552         264613  
136 65019         190763 my @tmp = map $_ + 1, @$aref;
137 65019         173309 push @indexes, [ @tmp ];
138             }
139 138552         221150 @{$new->[1]} = @indexes;
  138552         257313  
140              
141 138552         209350 my @flags;
142 138552         204233 foreach my $aref (@{$new->[3]}) {
  138552         249614  
143 141381         201892 my @tmp;
144 141381         236766 foreach my $value (@$aref) {
145 249798 100       513436 if (ref $value eq 'HASH') {
146 184779         268932 my %hash;
147 184779         557905 while (my ($key, $val) = each %$value) {
148 184779 100       690673 $key++ if $key =~ /^\d+$/;
149 184779         581598 $hash{$key} = $val;
150             }
151 184779         585162 push @tmp, { %hash };
152             }
153             else {
154 65019         125740 push @tmp, $value + 1;
155             }
156             }
157 141381         338934 push @flags, [ @tmp ];
158             }
159 138552         211969 @{$new->[3]} = @flags;
  138552         421350  
160             }
161              
162             my %indexes = (
163             prefix => 0,
164 255516         402061 suffix => scalar keys %{$new->[0]},
  255516         687796  
165             );
166              
167 255516         476652 my $i = $indexes{$type};
168              
169 255516         1246205 $new->[0]->{$i} = $self->{data}->__RE($element);
170              
171 255516 100       713748 if (exists $data{$element}->{2}) {
172 170344         586881 $save->($type, $new->[1], [ $i ]);
173 170344         773773 $save->($type, $new->[2], $self->{data}->__extended_checks($data{$element}->{2}));
174             }
175              
176 255516 100       403651 push @{$new->[3]}, exists $data{$element}->{3} ? [ { $i => [ $data{$element}->{3} ] } ] : [ $i ];
  255516         981507  
177              
178 255516         433817 push @{$new->[4]}, $data{$element}->{4};
  255516         481631  
179 255516         372013 push @{$new->[5]}, $data{$element}->{5};
  255516         480325  
180              
181 255516         364253 foreach my $key (keys %{$data{$element}->{6}}) {
  255516         673102  
182 255516         377508 push @{$new->[6]->{$key}}, @{$data{$element}->{6}->{$key}};
  255516         448661  
  255516         583635  
183             }
184              
185 255516         793040 push @expansions, [ $types, $new ];
186             }
187             }
188             }
189              
190 20105         106673 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