File Coverage

blib/lib/Dancer/Plugin/Dispatcher.pm
Criterion Covered Total %
statement 40 40 100.0
branch 10 14 71.4
condition 8 11 72.7
subroutine 5 5 100.0
pod n/a
total 63 70 90.0


line stmt bran cond sub pod time code
1             # ABSTRACT: Controller Class Dispatching System for Dancer
2             package Dancer::Plugin::Dispatcher;
3              
4 9     9   1843809 use Beam::Wire;
  9         1375354  
  9         339  
5 9     9   4263 use Dancer::Plugin;
  9         11183  
  9         675  
6              
7 9     9   54 use Dancer ':syntax';
  9         16  
  9         59  
8              
9             our $VERSION = '0.13'; # VERSION
10              
11             my %handlers;
12             my %services;
13              
14             register dispatch => sub {
15 11     11   2657 my $config = plugin_setting;
16 11         252 my ($self, @directions) = plugin_args(@_);
17              
18 11   50     91 my $caller = caller(0) // 'main';
19 11   100     208 my $container = Beam::Wire->new(config => $config->{services} // {});
20 11   100     29349 my $prefix = $config->{prefix} // '';
21 11   100     52 my $suffix = $config->{suffix} // '';
22 11         20 my $handlers = [];
23              
24 11         25 for my $direction (@directions) {
25 21 50       56 next if $handlers{$caller}{$direction};
26              
27 21         96 my ($service, $method) = split /#/, $direction;
28              
29 21         39 my $object = bless {}, $caller;
30 21 100 33     49 $object = $services{$service} //= $container->get($service) if $service;
31 21         760 $method = join '', $prefix, $method, $suffix;
32              
33 21         26 my $class = ref $object;
34 21 100       169 my $code = $object->can($method)
35             or die "Class ($class) doesn't have method ($method)";
36              
37 19         116 $handlers{$caller}{$direction} = {
38             class => $class,
39             service => $service,
40             object => $object,
41             method => $method,
42             code => $code,
43             };
44             }
45              
46             return sub {
47 8     8   12622 my $data; my @args = @_;
  8         18  
48 8         20 for my $direction (@directions) {
49 16         71 my $handler = $handlers{$caller}{$direction};
50 16         30 my $class = $handler->{class};
51 16         23 my $service = $handler->{service};
52 16         23 my $method = $handler->{method};
53 16         18 my $code = $handler->{code};
54              
55 16 50       121 debug "Dispatching to class ($class) and method ($method)"
56             . $service ? " using service ($service)" : "";
57              
58 16         708 $data = $code->(@args);
59              
60             # the dispatch chain will be broken and return immediately if a 3xx
61             # series redirect is issued or if execution is explicitly halted
62 15 50       6236 if (my $response = Dancer::SharedData->response) {
63 15 100       107 last if $response->status =~ /^3/; # redirect
64 14 50       127 last if $response->halted; # halted
65             }
66             }
67 7         70 return $data;
68             }
69 9         146 };
70              
71             register_plugin for_versions => [1, 2];
72              
73             __END__