File Coverage

blib/lib/Minima/Router.pm
Criterion Covered Total %
statement 14 14 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 19 19 100.0


line stmt bran cond sub pod time code
1 11     11   157956 use v5.40;
  11         48  
2 11     11   403 use experimental 'class';
  11         3025  
  11         54  
3              
4             class Minima::Router;
5              
6 11     11   1844 use Carp;
  11         14  
  11         664  
7 11     11   5263 use Path::Tiny;
  11         79713  
  11         594  
8 11     11   5159 use Router::Simple;
  11         54570  
  11         10050  
9              
10             field $router = Router::Simple->new;
11             field %special;
12             field $prefix = 'Controller';
13              
14             method match ($env)
15             {
16             my $match = $router->match($env);
17             return $match if defined $match;
18              
19             $self->not_found_route;
20             }
21              
22             method read_file ($file)
23             {
24             $file = path($file);
25             croak "Routes file `$file` does not exist.\n"
26             unless -e $file->absolute;
27              
28             # Parse routes
29             for ($file->lines_utf8) {
30             # Skip blank or comment lines
31             next if /^\s*#|^\s*$/;
32              
33             # Extract data
34             $_ = trim $_;
35             my ($method, $pattern, $controller, $action) = split;
36              
37             # Build destination and options
38             my %dest = $self->_build_destination($controller, $action);
39             my %opt = $self->_build_options($method);
40              
41             # Test the nature of the route
42             if ($method eq '@') {
43             # Special
44             $special{$pattern} = \%dest;
45             } else {
46             # Regular
47             $router->connect($pattern, \%dest, \%opt);
48             }
49             }
50             }
51              
52             method _build_command ($command, $action)
53             {
54             state %redirects = (
55             redirect => 302,
56             r => 302,
57             redirect_permanent => 301,
58             rp => 301,
59             );
60              
61             # Remove initial `@`
62             $command = substr($command, 1);
63              
64             croak "Unknown route command `$command`.\n"
65             unless exists $redirects{$command};
66              
67             (
68             redirect => $action,
69             redirect_status => $redirects{$command}
70             )
71             }
72              
73             method _build_destination ($controller, $action)
74             {
75             if (defined $controller) {
76             # Check if it is a command
77             return $self->_build_command($controller, $action)
78             if $controller =~ /^@/;
79              
80             # Fix controller prefix
81             $controller =~ s/^:+/${prefix}::/;
82             }
83              
84             ( controller => $controller, action => $action )
85             }
86              
87             method _build_options ($method)
88             {
89             return () if ($method eq '*'); # Don't add a constraint
90             return ( method => [ qw/ GET HEAD / ] ) if $method eq 'GET';
91             return ( method => 'GET' ) if $method eq '_GET';
92             return ( method => $method );
93             }
94              
95             method _connect
96             {
97             $router->connect(@_);
98             }
99              
100             method clear_routes
101             {
102             $router = Router::Simple->new;
103             %special = ( );
104             }
105              
106             method set_prefix ($new)
107             {
108             $prefix = $new;
109             }
110              
111             method not_found_route { $special{not_found} }
112             method error_route { $special{server_error} }
113              
114             __END__