File Coverage

blib/lib/Routes/Tiny.pm
Criterion Covered Total %
statement 62 65 95.3
branch 13 16 81.2
condition 2 3 66.6
subroutine 10 10 100.0
pod 5 5 100.0
total 92 99 92.9


line stmt bran cond sub pod time code
1             package Routes::Tiny;
2              
3 17     17   359381 use strict;
  17         51  
  17         612  
4 17     17   116 use warnings;
  17         52  
  17         965  
5              
6             require Carp;
7             require Scalar::Util;
8 17     17   7214 use Routes::Tiny::Pattern;
  17         63  
  17         14320  
9              
10             our $VERSION = 0.20;
11              
12             sub new {
13 48     48 1 29242 my $class = shift;
14 48         168 my (%params) = @_;
15              
16 48         131 my $self = {};
17 48         121 bless $self, $class;
18              
19 48         201 $self->{strict_trailing_slash} = $params{strict_trailing_slash};
20 48         128 $self->{default_method} = $params{default_method};
21              
22 48         119 $self->{parent_pattern} = undef;
23 48         129 $self->{patterns} = [];
24 48         194 $self->{names} = {};
25             $self->{strict_trailing_slash} = 1
26 48 100       183 unless defined $self->{strict_trailing_slash};
27              
28 48         148 return $self;
29             }
30              
31             sub add_route {
32 67     67 1 386 my $self = shift;
33              
34 67         217 my $pattern = $self->_build_pattern(@_);
35              
36 66         118 push @{$self->{patterns}}, $pattern;
  66         161  
37              
38 66 100       286 $self->_register_pattern_name($pattern) if $pattern->{name};
39              
40 66         142 return $pattern;
41             }
42              
43             sub mount {
44 12     12 1 60 my $self = shift;
45 12         29 my ($pattern, $routes, @args) = @_;
46              
47 12         31 $pattern = $self->add_route($pattern, subroutes => $routes, @args);
48 12         26 $routes->{parent_pattern} = $pattern;
49 12         20 $self->_register_pattern_name($_) for values %{ $routes->{names} };
  12         43  
50 12         42 Scalar::Util::weaken($routes->{parent_pattern});
51 12         35 return $pattern;
52             }
53              
54             sub match {
55 102     102 1 8153 my $self = shift;
56 102         264 my ($path, @args) = @_;
57              
58 102         187 foreach my $pattern (@{$self->{patterns}}) {
  102         294  
59 159 100       502 if (my $m = $pattern->match($path, @args)) {
60 81         353 return $m;
61             }
62             }
63              
64 21         101 return;
65             }
66              
67             sub build_path {
68 35     35 1 3326 my $self = shift;
69 35         132 my ($name, @args) = @_;
70              
71 35         371 my $pattern = $self->{names}->{$name};
72              
73 35 50       230 return $pattern->build_path(@args) if $pattern;
74              
75 0         0 Carp::croak("Unknown name '$name' used to build a path");
76             }
77              
78             sub _register_pattern_name {
79 48     48   138 my $self = shift;
80 48         108 my ($pattern) = @_;
81              
82 48         153 my $name = $pattern->name;
83 48 50       142 if (exists $self->{names}->{ $name }) {
84 0         0 Carp::carp("pattern name '$name' already used");
85             }
86             else {
87 48         127 $self->{names}->{ $name } = $pattern;
88 48   66     134 my $parent_routes = $self->{parent_pattern} && $self->{parent_pattern}->{routes};
89 48 100       184 if ($parent_routes) {
90 1         6 $parent_routes->_register_pattern_name(@_);
91             }
92             }
93             }
94              
95             sub _build_pattern {
96 67     67   137 my $self = shift;
97              
98 67 100       216 if (@_ % 2) {
99 66         192 unshift(@_, 'pattern');
100             } else {
101 1         2 my $method = shift;
102 1         3 my $pattern = shift;
103              
104 1 50       8 if ($method =~ /^(GET|HEAD|POST|PUT|DELETE|TRACE|OPTIONS|CONNECT|PATCH)$/i) {
105 1         4 unshift(@_, pattern => $pattern);
106 1         3 unshift(@_, method => $method);
107             } else {
108 0         0 Carp::croak("Unknown pattern http method '$_[0]'");
109             }
110             }
111              
112             return Routes::Tiny::Pattern->new(
113             strict_trailing_slash => $self->{strict_trailing_slash},
114             default_method => $self->{default_method},
115 67         368 routes => $self,
116             @_
117             )
118             }
119              
120             1;
121             __END__