File Coverage

blib/lib/Path/Dispatcher/Dispatch.pm
Criterion Covered Total %
statement 48 48 100.0
branch 6 6 100.0
condition 1 3 33.3
subroutine 16 16 100.0
pod 2 7 28.5
total 73 80 91.2


line stmt bran cond sub pod time code
1             package Path::Dispatcher::Dispatch;
2             # ABSTRACT: a list of matches
3              
4             our $VERSION = '1.08';
5              
6 31     31   222 use Moo;
  31         71  
  31         221  
7 31     31   12334 use MooX::TypeTiny;
  31         85  
  31         255  
8 31     31   35667 use Try::Tiny;
  31         35186  
  31         1812  
9 31     31   226 use Carp qw(confess);
  31         76  
  31         1303  
10 31     31   190 use Types::Standard qw(ArrayRef);
  31         85  
  31         274  
11              
12 31     31   19225 use Path::Dispatcher::Match;
  31         75  
  31         15675  
13              
14             has _matches => (
15             is => 'ro',
16             isa => ArrayRef,
17             default => sub { [] },
18             );
19              
20             sub add_match {
21 131     131 0 238 my $self = shift;
22              
23             $_->isa('Path::Dispatcher::Match')
24             or confess "$_ is not a Path::Dispatcher::Match"
25 131   33     588 for @_;
26              
27 131         215 push @{ $self->{_matches} }, @_;
  131         379  
28             }
29              
30 91     91 1 1186 sub matches { @{ shift->{_matches} } }
  91         224  
31 1     1 0 2 sub has_match { scalar @{ shift->{_matches} } }
  1         7  
32 1     1 0 4 sub first_match { shift->{_matches}[0] }
33              
34             # aliases
35 131     131 0 485 sub add_matches { goto \&add_match }
36 1     1 0 7 sub has_matches { goto \&has_match }
37              
38             sub run {
39 90     90 1 6286 my $self = shift;
40 90         191 my @args = @_;
41 90         209 my @matches = $self->matches;
42 90         149 my @results;
43              
44 90         256 while (my $match = shift @matches) {
45 67         109 my $exception;
46              
47             try {
48 67     67   3795 local $SIG{__DIE__} = 'DEFAULT';
49              
50 67         308 push @results, $match->run(@args);
51              
52             # we always stop after the first match UNLESS they explicitly
53             # ask to continue on to the next rule
54 58         652 die "Path::Dispatcher abort\n";
55             }
56             catch {
57 67     67   1153 $exception = $_;
58 67         567 };
59              
60 67 100       874 last if $exception =~ /^Path::Dispatcher abort\n/;
61 8 100       41 next if $exception =~ /^Path::Dispatcher next rule\n/;
62              
63 5         49 die $exception;
64             }
65              
66 85 100       285 return @results if wantarray;
67 78         461 return $results[0];
68             }
69              
70             __PACKAGE__->meta->make_immutable;
71              
72 31     31   255 no Moo;
  31         96  
  31         198  
73              
74             1;
75              
76             __END__
77              
78             =pod
79              
80             =encoding UTF-8
81              
82             =head1 NAME
83              
84             Path::Dispatcher::Dispatch - a list of matches
85              
86             =head1 VERSION
87              
88             version 1.08
89              
90             =head1 SYNOPSIS
91              
92             my $dispatcher = Path::Dispatcher->new(
93             rules => [
94             Path::Dispatcher::Rule::Tokens->new(
95             tokens => [ 'attack', qr/^\w+$/ ],
96             block => sub { attack(shift->pos(2)) },
97             ),
98             ],
99             );
100              
101             my $dispatch = $dispatcher->dispatch("attack goblin");
102              
103             $dispatch->matches; # list of matches (in this case, one)
104             $dispatch->has_matches; # whether there were any matches
105              
106             $dispatch->run; # attacks the goblin
107              
108             =head1 DESCRIPTION
109              
110             Dispatching creates a C<dispatch> which is little more than a (possibly empty!)
111             list of matches.
112              
113             =head1 ATTRIBUTES
114              
115             =head2 matches
116              
117             The list of L<Path::Dispatcher::Match> that correspond to the rules that were
118             matched.
119              
120             =head1 METHODS
121              
122             =head2 run
123              
124             Executes the first match.
125              
126             Each match's L<Path::Dispatcher::Match/run> method is evaluated in scalar
127             context. The return value of this method is a list of these scalars (or the
128             first if called in scalar context).
129              
130             =head1 SUPPORT
131              
132             Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Path-Dispatcher>
133             (or L<bug-Path-Dispatcher@rt.cpan.org|mailto:bug-Path-Dispatcher@rt.cpan.org>).
134              
135             =head1 AUTHOR
136              
137             Shawn M Moore, C<< <sartak at bestpractical.com> >>
138              
139             =head1 COPYRIGHT AND LICENSE
140              
141             This software is copyright (c) 2020 by Shawn M Moore.
142              
143             This is free software; you can redistribute it and/or modify it under
144             the same terms as the Perl 5 programming language system itself.
145              
146             =cut