File Coverage

blib/lib/Path/Dispatcher/Rule/Sequence.pm
Criterion Covered Total %
statement 44 44 100.0
branch 11 12 91.6
condition 6 6 100.0
subroutine 7 7 100.0
pod 0 3 0.0
total 68 72 94.4


line stmt bran cond sub pod time code
1             package Path::Dispatcher::Rule::Sequence;
2 32     32   126 use Any::Moose;
  32         38  
  32         152  
3              
4             extends 'Path::Dispatcher::Rule';
5             with 'Path::Dispatcher::Role::Rules';
6              
7             has delimiter => (
8             is => 'ro',
9             isa => 'Str',
10             default => ' ',
11             );
12              
13             sub _match_as_far_as_possible {
14 80     80   68 my $self = shift;
15 80         66 my $path = shift;
16              
17 80         179 my @tokens = $self->tokenize($path->path);
18 80         182 my @rules = $self->rules;
19 80         81 my @matched;
20              
21 80   100     289 while (@tokens && @rules) {
22 152         149 my $rule = $rules[0];
23 152         132 my $token = $tokens[0];
24              
25 152 100       283 last unless $rule->match($path->clone_path($token));
26              
27 112         517 push @matched, $token;
28 112         103 shift @rules;
29 112         333 shift @tokens;
30             }
31              
32 80         244 return (\@matched, \@tokens, \@rules);
33             }
34              
35             sub _match {
36 48     48   35 my $self = shift;
37 48         43 my $path = shift;
38              
39 48         68 my ($matched, $tokens, $rules) = $self->_match_as_far_as_possible($path);
40              
41 48 100       108 return if @$rules; # didn't provide everything necessary
42 26 100 100     78 return if @$tokens && !$self->prefix; # had tokens left over
43              
44 24         47 my $leftover = $self->untokenize(@$tokens);
45             return {
46 24         67 leftover => $leftover,
47             positional_captures => $matched,
48             };
49             }
50              
51             sub complete {
52 32     32 0 24 my $self = shift;
53 32         36 my $path = shift;
54              
55 32         42 my ($matched, $tokens, $rules) = $self->_match_as_far_as_possible($path);
56 32 50       54 return if @$tokens > 1; # had tokens leftover
57 32 100       63 return if !@$rules; # consumed all rules
58              
59 30         23 my $rule = shift @$rules;
60 30 100       47 my $token = @$tokens ? shift @$tokens : '';
61              
62 30         59 return map { $self->untokenize(@$matched, $_) }
  40         60  
63             $rule->complete($path->clone_path($token));
64             }
65              
66             sub tokenize {
67 80     80 0 63 my $self = shift;
68 80         81 my $path = shift;
69 80         370 return grep { length } split $self->delimiter, $path;
  196         355  
70             }
71              
72             sub untokenize {
73 64     64 0 57 my $self = shift;
74 64         68 my @tokens = @_;
75 88         223 return join $self->delimiter,
76 88         192 grep { length }
77 64         140 map { split $self->delimiter, $_ }
78             @tokens;
79             }
80              
81             __PACKAGE__->meta->make_immutable;
82 32     32   24453 no Any::Moose;
  32         49  
  32         126  
83              
84             1;
85              
86             __END__