next unless @result and defined($result[0]);
if (ref($result[0]) eq 'ARRAY') {
return $result[0];
- } elsif (blessed($result[0]) && $result[0]->can('wrap')) {
- return $result[0]->wrap(sub {
- $self->_dispatch($_[0], @match)
- })->($env);
+ } elsif (blessed($result[0]) && $result[0]->isa('Plack::Middleware')) {
+ die "Multiple results but first one is a middleware ($result[0])"
+ if @result > 1;
+ my $mw = $result[0];
+ $mw->app(sub { $self->_dispatch($_[0], @match) });
+ return $mw->to_app->($env);
} elsif (blessed($result[0]) && !$result[0]->can('to_app')) {
return $result[0];
} else {
return do {
my $match = $self->_parse_spec_section($_);
return sub {
- return {} unless $match->(@_);
+ return {} unless my @discard = $match->(@_);
return;
};
};
sub _url_extension_match {
my ($self, $str, $extension) = @_;
- if ($extension eq '*') {
- sub {
- if ((my $tmp = shift->{PATH_INFO}) =~ s/\.(\w+)$//) {
- ({ PATH_INFO => $tmp }, $1);
- } else {
- ();
- }
- };
- } else {
- sub {
- if ((my $tmp = shift->{PATH_INFO}) =~ s/\.\Q${extension}\E$//) {
- ({ PATH_INFO => $tmp });
- } else {
- ();
- }
- };
- }
+ match_extension($extension);
}
sub _parse_param_handler {
use strictures 1;
use base qw(Exporter);
-our @EXPORT = qw(match_and match_or match_method match_path match_path_strip);
+our @EXPORT = qw(
+ match_and match_or match_method match_path match_path_strip
+ match_extension
+);
sub match_and {
my @match = @_;
}
}
+sub match_extension {
+ my ($extension) = @_;
+ my $wild = (!$extension or $extension eq '*');
+ my $re = $wild
+ ? qr/\.(\w+)$/
+ : qr/\.(\Q${extension}\E)$/;
+ sub {
+ if ($_[0]->{PATH_INFO} =~ $re) {
+ ($wild ? ({}, $1) : {});
+ } else {
+ ();
+ }
+ };
+}
+
1;
package Web::Dispatch::Wrapper;
use strictures 1;
+use Moo;
use Exporter 'import';
our @EXPORT = qw(dispatch_wrapper redispatch_to response_filter);
+extends 'Plack::Middleware';
+
+has 'wrapper' => (is => 'ro', required => 1);
+
sub dispatch_wrapper (&) {
my ($code) = @_;
__PACKAGE__->from_code($code);
sub from_code {
my ($class, $code) = @_;
- bless(\$code, $class);
+ $class->new(wrapper => $code);
}
sub redispatch_to {
});
}
-sub wrap {
- my $code = ${$_[0]};
+sub to_app {
+ my $code = $_[0]->wrapper;
my $app = $_[1];
sub { $code->($_[0], $app) }
}
);
}
-ok(
- !eval { $dp->parse('GET POST'); 1; },
- "Don't yet allow two methods"
-);
-
{
my $html = $dp->parse('.html');
is_deeply(
[ $html->({ PATH_INFO => '/foo/bar.html' }) ],
- [ { PATH_INFO => '/foo/bar' } ],
+ [ { } ],
'.html matches'
);
is_deeply(
[ $any_ext->({ PATH_INFO => '/foo/bar.html' }) ],
- [ { PATH_INFO => '/foo/bar' }, 'html' ],
+ [ { }, 'html' ],
'.html matches .* and extension returned'
);
[],
'/post/one/ does not match'
);
+
+ is_deeply(
+ [ $post->({ PATH_INFO => '/post/one.html' }) ],
+ [ {}, 'one' ],
+ '/post/one.html still parses out one'
+ );
}
{
is_deeply(
[ $not->({ PATH_INFO => '/foo.xml' }) ],
- [ { PATH_INFO => '/foo' }, 'xml' ],
+ [ {}, 'xml' ],
'!.html+.* matches /foo.xml'
);