Skip to content

Commit

Permalink
Merge pull request #1130 from PerlDancer/veryrusty-named-captures-pr-…
Browse files Browse the repository at this point in the history
…1086

Allow mixed named params and splats in route captures v2
  • Loading branch information
bigpresh committed Oct 26, 2015
2 parents 8c8859b + e5f0233 commit a12af19
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 22 deletions.
4 changes: 4 additions & 0 deletions Changes
Expand Up @@ -4,10 +4,14 @@ Revision history for Dancer
[ API CHANGES ]

[ BUG FIXES ]
- Fix temporary directory handling in serialiser tests (PR 1133, nanis)

[ DOCUMENTATION ]

[ ENHANCEMENTS ]
- More efficient handling of large requests - don't store the raw request
body, but fish it out of the HTTP::Body object's temp file if required
(PR 1134, David Precious (bigpresh))

[ NEW FEATURES ]

Expand Down
50 changes: 29 additions & 21 deletions lib/Dancer/Route.pm
Expand Up @@ -79,25 +79,14 @@ sub match {

my $method = lc($request->method);
my $path = $request->path_info;
my %params;

Dancer::Logger::core(
sprintf "Trying to match '%s %s' against /%s/ (generated from '%s')",
$request->method, $path, $self->{_compiled_regexp}, $self->pattern
);


my @values = $path =~ $self->{_compiled_regexp};

# the regex comments are how we know if we captured
# a splat or a megasplat
if( my @splat_or_megasplat
= $self->{_compiled_regexp} =~ /\(\?#((?:mega)?splat)\)/g ) {
for ( @values ) {
$_ = [ split '/' => $_ ] if ( shift @splat_or_megasplat ) =~ /megasplat/;
}
}

Dancer::Logger::core(" --> got ".
map { defined $_ ? $_ : 'undef' } @values)
if @values;
Expand All @@ -124,18 +113,37 @@ sub match {
# IT WILL MOVE VERY SOON
$request->{_route_pattern} = $self->pattern;

# named tokens
my @tokens = @{$self->{_params} || []};

Dancer::Logger::core(" --> named tokens are: @tokens") if @tokens;
if (@tokens) {
for (my $i = 0; $i < @tokens; $i++) {
$params{$tokens[$i]} = $values[$i];
# regex comments are how we know if we captured a token,
# splat or a megasplat
my @token_or_splat
= $self->{_compiled_regexp} =~ /\(\?#([token|(?:mega)?splat]+)\)/g;
if (@token_or_splat) {
# named tokens
my @tokens = @{$self->{_params} || []};
Dancer::Logger::core(" --> named tokens are: @tokens") if @tokens;

my %params;
my @splat;
for ( my $i = 0; $i < @values; $i++ ) {
# Is this value from a token?
if ( $token_or_splat[$i] eq 'token' ) {
$params{ shift @tokens } = $values[$i];
next;
}

# megasplat values are split on '/'
if ($token_or_splat[$i] eq 'megasplat') {
$values[$i] = [ split '/' => $values[$i] ];
}
push @splat, $values[$i];
}
return $self->save_match_data($request, \%params);
return $self->save_match_data( $request, {
%params,
( @splat ? ( splat => \@splat ) : () ),
});
}

elsif ($self->{_should_capture}) {
if ($self->{_should_capture}) {
return $self->save_match_data($request, {splat => \@values});
}

Expand Down Expand Up @@ -326,7 +334,7 @@ sub _build_regexp_from_string {
if ($pattern =~ /:/) {
@params = $pattern =~ /:([^\/\.\?]+)/g;
if (@params) {
$pattern =~ s/(:[^\/\.\?]+)/\(\[\^\/\]\+\)/g;
$pattern =~ s!(:[^\/\.\?]+)!(?#token)([^/]+)!g;
$capture = 1;
}
}
Expand Down
15 changes: 14 additions & 1 deletion t/03_route_handler/04_wildcards_megasplat.t
Expand Up @@ -3,7 +3,7 @@ use Test::More;

use Dancer::Test;

plan tests => 4;
plan tests => 6;

get '/foo/**' => sub { show_splat() };
response_content_is [ GET => '/foo/a/b/c' ] => '(a,b,c)';
Expand All @@ -15,6 +15,19 @@ get '/alpha/**/gamma' => sub { show_splat() };
response_content_is [ GET => '/alpha/beta/delta/gamma' ] => '(beta,delta)';
response_content_is [ GET => '/alpha/beta/gamma' ] => '(beta)';

# mixed tokens and splat
my $route_code = sub {
my $id = param 'id';
$id = 'undef' unless defined $id;
my $splt = show_splat();
return "$id:$splt"
};
get '/some/:id/**/*' => $route_code;
response_content_is [ GET => '/some/where/to/run/and/hide' ] => 'where:(to,run,and):hide';

get '/some/*/**/:id?' => $route_code;
response_content_is [ GET => '/some/one/to/say/boo/' ] => 'undef:one:(to,say,boo)';

sub show_splat {
return join ':', map { ref $_ ? "(" . join( ',', @$_ ) . ")": $_ } splat;
}

0 comments on commit a12af19

Please sign in to comment.