File Coverage

blib/lib/Puncheur/Dispatcher/Lite.pm
Criterion Covered Total %
statement 46 62 74.1
branch 9 24 37.5
condition n/a
subroutine 9 10 90.0
pod n/a
total 64 96 66.6


line stmt bran cond sub pod time code
1             package Puncheur::Dispatcher::Lite;
2 1     1   3 use strict;
  1         1  
  1         30  
3 1     1   4 use warnings;
  1         1  
  1         25  
4 1     1   464 use Router::Boom::Method;
  1         3823  
  1         50  
5              
6             sub import {
7 1     1   1 my $class = shift;
8 1         2 my $caller = caller(0);
9              
10              
11 1         5 my $router = Router::Boom::Method->new;
12 1         5 my $base;
13              
14 1     1   5 no strict 'refs';
  1         1  
  1         66  
15 1     0   2 *{"${caller}::base"} = sub { $base = $_[0] };
  1         8  
  0         0  
16              
17             # copied from Amon2::Web::Dispatcher::RouterBoom
18             # functions
19             #
20             # get( '/path', 'Controller#action')
21             # post('/path', 'Controller#action')
22             # delete_('/path', 'Controller#action')
23             # any( '/path', 'Controller#action')
24             # get( '/path', sub { })
25             # post('/path', sub { })
26             # delete_('/path', sub { })
27             # any( '/path', sub { })
28 1         2 for my $method (qw(get post delete_ any)) {
29 4         12 *{"${caller}::${method}"} = sub {
30 1     1   4 use strict 'refs';
  1         1  
  1         338  
31 2     2   3 my ($path, $dest) = @_;
32              
33 2         2 my %dest;
34 2 50       5 if (ref $dest eq 'CODE') {
35 2         4 $dest{code} = $dest;
36             }
37             else {
38 0         0 my ($controller, $method) = split('#', $dest);
39 0 0       0 $dest{class} = $base ? "${base}::${controller}" : $controller;
40 0 0       0 $dest{method} = $method if defined $method;
41             }
42              
43 2         3 my $http_method;
44 2 50       9 if ($method eq 'get') {
    50          
    50          
45 0         0 $http_method = ['GET','HEAD'];
46             } elsif ($method eq 'post') {
47 0         0 $http_method = 'POST';
48             } elsif ($method eq 'delete_') {
49 0         0 $http_method = 'DELETE';
50             }
51              
52 2         9 $router->add($http_method, $path, \%dest);
53 4         12 };
54             }
55              
56             # class methods
57 1     2   2 *{"${caller}::router"} = sub { $router };
  1         3  
  2         12  
58              
59 1         152 *{"${caller}::dispatch"} = sub {
60 2     2   4 my ($class, $c) = @_;
61 2 50       7 $c = $class unless $c;
62              
63 2         9 my $env = $c->request->env;
64 2 50       15 if (my ($dest, $captured, $method_not_allowed) = $class->router->match($env->{REQUEST_METHOD}, $env->{PATH_INFO})) {
65 2 50       679 if ($method_not_allowed) {
66 0         0 return $c->res_405;
67             }
68              
69 2         3 my $res = eval {
70 2 50       100 if ($dest->{code}) {
71 2         10 return $dest->{code}->($c, $captured);
72             } else {
73 0         0 my $method = $dest->{method};
74 0         0 $c->{args} = $captured;
75 0         0 return $dest->{class}->$method($c, $captured);
76             }
77             };
78 2 50       8 if ($@) {
79 0 0       0 if ($class->can('handle_exception')) {
80 0         0 return $class->handle_exception($c, $@);
81             }
82             else {
83 0         0 print STDERR "$env->{REQUEST_METHOD} $env->{PATH_INFO} [$env->{HTTP_USER_AGENT}]: $@";
84 0         0 return $c->res_500;
85             }
86             }
87 2         9 return $res;
88             }
89             else {
90 0           return $c->res_404;
91             }
92 1         3 };
93             }
94              
95             1;