| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#!perl |
|
2
|
|
|
|
|
|
|
#PODNAME: Raisin::Routes |
|
3
|
|
|
|
|
|
|
#ABSTRACT: A routing class for Raisin. |
|
4
|
|
|
|
|
|
|
|
|
5
|
13
|
|
|
13
|
|
154223
|
use strict; |
|
|
13
|
|
|
|
|
34
|
|
|
|
13
|
|
|
|
|
441
|
|
|
6
|
13
|
|
|
13
|
|
74
|
use warnings; |
|
|
13
|
|
|
|
|
29
|
|
|
|
13
|
|
|
|
|
645
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
package Raisin::Routes; |
|
9
|
|
|
|
|
|
|
$Raisin::Routes::VERSION = '0.92'; |
|
10
|
13
|
|
|
13
|
|
92
|
use Carp; |
|
|
13
|
|
|
|
|
26
|
|
|
|
13
|
|
|
|
|
902
|
|
|
11
|
13
|
|
|
|
|
129
|
use Plack::Util::Accessor qw( |
|
12
|
|
|
|
|
|
|
cache |
|
13
|
|
|
|
|
|
|
list |
|
14
|
|
|
|
|
|
|
routes |
|
15
|
13
|
|
|
13
|
|
533
|
); |
|
|
13
|
|
|
|
|
273
|
|
|
16
|
|
|
|
|
|
|
|
|
17
|
13
|
|
|
13
|
|
6734
|
use Raisin::Param; |
|
|
13
|
|
|
|
|
34
|
|
|
|
13
|
|
|
|
|
414
|
|
|
18
|
13
|
|
|
13
|
|
5725
|
use Raisin::Routes::Endpoint; |
|
|
13
|
|
|
|
|
33
|
|
|
|
13
|
|
|
|
|
424
|
|
|
19
|
13
|
|
|
13
|
|
94
|
use Raisin::Util; |
|
|
13
|
|
|
|
|
30
|
|
|
|
13
|
|
|
|
|
7928
|
|
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub new { |
|
22
|
33
|
|
|
33
|
0
|
63208
|
my $class = shift; |
|
23
|
33
|
|
|
|
|
485
|
my $self = bless { id => rand() }, $class; |
|
24
|
|
|
|
|
|
|
|
|
25
|
33
|
|
|
|
|
161
|
$self->cache({}); |
|
26
|
33
|
|
|
|
|
285
|
$self->list({}); |
|
27
|
33
|
|
|
|
|
208
|
$self->routes([]); |
|
28
|
|
|
|
|
|
|
|
|
29
|
33
|
|
|
|
|
253
|
$self; |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub add { |
|
33
|
64
|
|
|
64
|
1
|
15011
|
my ($self, %params) = @_; |
|
34
|
|
|
|
|
|
|
|
|
35
|
64
|
|
|
|
|
170
|
my $method = uc $params{method}; |
|
36
|
64
|
|
|
|
|
115
|
my $path = $params{path}; |
|
37
|
|
|
|
|
|
|
|
|
38
|
64
|
50
|
33
|
|
|
298
|
if (!$method || !$path) { |
|
39
|
0
|
|
|
|
|
0
|
carp "Method and path are required"; |
|
40
|
0
|
|
|
|
|
0
|
return; |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
64
|
|
|
|
|
100
|
my $code = $params{code}; |
|
44
|
|
|
|
|
|
|
# Supports only CODE as route destination |
|
45
|
64
|
50
|
33
|
|
|
270
|
if (!$code || !(ref($code) eq 'CODE')) { |
|
46
|
0
|
|
|
|
|
0
|
carp "Invalid route params for $method $path"; |
|
47
|
0
|
|
|
|
|
0
|
return; |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
64
|
|
|
|
|
97
|
my @pp; |
|
51
|
64
|
|
|
|
|
123
|
for my $key (qw(params named)) { |
|
52
|
128
|
|
100
|
|
|
568
|
my $next_param = Raisin::Util::iterate_params($params{$key} || []); |
|
53
|
128
|
|
|
|
|
358
|
while (my ($type, $spec) = $next_param->()) { |
|
54
|
179
|
100
|
|
|
|
614
|
last unless $type; |
|
55
|
|
|
|
|
|
|
|
|
56
|
51
|
|
|
|
|
226
|
push @pp, Raisin::Param->new( |
|
57
|
|
|
|
|
|
|
named => $key eq 'named', |
|
58
|
|
|
|
|
|
|
type => $type, # -> requires/optional |
|
59
|
|
|
|
|
|
|
spec => $spec, # -> { name => ..., type => ... } |
|
60
|
|
|
|
|
|
|
); |
|
61
|
|
|
|
|
|
|
} |
|
62
|
|
|
|
|
|
|
} |
|
63
|
|
|
|
|
|
|
|
|
64
|
64
|
50
|
33
|
|
|
173
|
if (ref($path) && ref($path) ne 'Regexp') { |
|
65
|
0
|
|
|
|
|
0
|
print STDERR "Route `$path` should be SCALAR or Regexp\n"; |
|
66
|
0
|
|
|
|
|
0
|
return; |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# Cut off the last slash from a path |
|
70
|
64
|
50
|
|
|
|
195
|
$path =~ s#(.+)/$#$1# if !ref($path); |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
my $ep = Raisin::Routes::Endpoint->new( |
|
73
|
|
|
|
|
|
|
code => $code, |
|
74
|
|
|
|
|
|
|
method => $method, |
|
75
|
|
|
|
|
|
|
params => \@pp, |
|
76
|
|
|
|
|
|
|
path => $path, |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
desc => $params{desc}, |
|
79
|
|
|
|
|
|
|
entity => $params{entity}, |
|
80
|
|
|
|
|
|
|
summary => $params{summary}, |
|
81
|
|
|
|
|
|
|
tags => $params{tags}, |
|
82
|
|
|
|
|
|
|
produces => $params{produces}, |
|
83
|
64
|
|
|
|
|
420
|
); |
|
84
|
64
|
|
|
|
|
141
|
push @{ $self->{routes} }, $ep; |
|
|
64
|
|
|
|
|
181
|
|
|
85
|
|
|
|
|
|
|
|
|
86
|
64
|
100
|
|
|
|
155
|
if ($self->list->{$path}{$method}) { |
|
87
|
2
|
|
|
|
|
20
|
Raisin::log(warn => "route has been redefined: $method $path"); |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
|
|
90
|
64
|
|
|
|
|
1271
|
$self->list->{$path}{$method} = scalar @{ $self->{routes} }; |
|
|
64
|
|
|
|
|
199
|
|
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub find { |
|
94
|
65
|
|
|
65
|
1
|
5914
|
my ($self, $method, $path) = @_; |
|
95
|
|
|
|
|
|
|
|
|
96
|
65
|
|
|
|
|
186
|
my $cache_key = lc "$method:$path"; |
|
97
|
|
|
|
|
|
|
my $routes |
|
98
|
|
|
|
|
|
|
= exists $self->cache->{$cache_key} |
|
99
|
65
|
100
|
|
|
|
200
|
? $self->cache->{$cache_key} |
|
100
|
|
|
|
|
|
|
: $self->routes; |
|
101
|
|
|
|
|
|
|
|
|
102
|
65
|
100
|
|
|
|
592
|
my @found = grep { $_->match($method, $path) } @$routes or return; |
|
|
446
|
|
|
|
|
2417
|
|
|
103
|
|
|
|
|
|
|
|
|
104
|
64
|
50
|
|
|
|
353
|
if (scalar @found > 1) { |
|
105
|
0
|
|
|
|
|
0
|
Raisin::log(warn => "more then one route has been found: $method $path"); |
|
106
|
|
|
|
|
|
|
} |
|
107
|
|
|
|
|
|
|
|
|
108
|
64
|
|
|
|
|
179
|
$self->cache->{$cache_key} = \@found; |
|
109
|
64
|
|
|
|
|
371
|
$found[0]; |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
1; |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
__END__ |