File Coverage

blib/lib/Path/Dispatcher/Rule/Under.pm
Criterion Covered Total %
statement 19 32 59.3
branch 3 8 37.5
condition 3 3 100.0
subroutine 4 5 80.0
pod 1 2 50.0
total 30 50 60.0


line stmt bran cond sub pod time code
1             package Path::Dispatcher::Rule::Under;
2 32     32   128 use Any::Moose;
  32         43  
  32         917  
3 32     32   12270 use Any::Moose '::Util::TypeConstraints';
  32         44  
  32         106  
4              
5             extends 'Path::Dispatcher::Rule';
6             with 'Path::Dispatcher::Role::Rules';
7              
8             subtype 'Path::Dispatcher::PrefixRule'
9             => as 'Path::Dispatcher::Rule'
10             => where { $_->prefix }
11             => message { "This rule ($_) does not match just prefixes!" };
12              
13             has predicate => (
14             is => 'ro',
15             isa => 'Path::Dispatcher::PrefixRule',
16             );
17              
18             sub match {
19 21     21 1 28 my $self = shift;
20 21         22 my $path = shift;
21              
22 21 100       87 my $prefix_match = $self->predicate->match($path)
23             or return;
24              
25 16         31 my $leftover = $prefix_match->leftover;
26 16 50       29 $leftover = '' if !defined($leftover);
27              
28 16         40 my $new_path = $path->clone_path($leftover);
29              
30             # Pop off @matches until we have a last rule that is not ::Chain
31             #
32             # A better technique than isa might be to use the concept of 'endpoint', 'midpoint', or 'anypoint' rules and
33             # add a method to ::Rule that lets evaluate whether any rule is of the right kind (i.e. ->is_endpoint)
34             #
35             # Because the checking for ::Chain endpointedness is here, this means that outside of an ::Under, ::Chain behaves like
36             # an ::Always (one that will always trigger next_rule if it's block is ran)
37             #
38 40         108 my @matches = map {
39 16         255 $_->match(
40             $new_path,
41             extra_constructor_args => {
42             parent => $prefix_match,
43             },
44             )
45             } $self->rules;
46 16   100     153 pop @matches while @matches && $matches[-1]->rule->isa('Path::Dispatcher::Rule::Chain');
47 16         131 return @matches;
48             }
49              
50             sub complete {
51 0     0 0   my $self = shift;
52 0           my $path = shift;
53              
54 0           my $predicate = $self->predicate;
55              
56 0 0         my $prefix_match = $predicate->match($path)
57             or return $predicate->complete($path);
58              
59 0           my $new_path = $path->clone_path($prefix_match->leftover);
60              
61 0           my $prefix = substr($path->path, 0, length($path->path) - length($new_path->path));
62              
63 0           my @completions = map { $_->complete($new_path) } $self->rules;
  0            
64              
65 0 0         if ($predicate->can('untokenize')) {
66 0           return map { $predicate->untokenize($prefix, $_) } @completions;
  0            
67             }
68             else {
69 0           return map { "$prefix$_" } @completions;
  0            
70             }
71             }
72              
73             __PACKAGE__->meta->make_immutable;
74 32     32   17710 no Any::Moose;
  32         48  
  32         123  
75              
76             1;
77              
78             __END__