sub _parse_spec {
my ($self, $spec, $nested) = @_;
+ return sub { {} } unless length($spec);
for ($_[1]) {
my @match;
PARSE: { do {
# %<param spec>
/\G\%/gc and
return $self->_parse_param_handler($_, 'body');
+
+ # *<param spec>
+ /\G\*/gc and
+ return $self->_parse_param_handler($_, 'uploads');
}
return; # () will trigger the blam in our caller
}
for ($_[1]) {
my @path;
my $end = '';
+ my $keep_dot;
PATH: while (/\G\//gc) {
/\G\.\.\./gc
and do {
};
push @path, $self->_url_path_segment_match($_)
or $self->_blam("Couldn't parse path match segment");
+ /\G\.\*/gc
+ and do {
+ $keep_dot = 1;
+ last PATH;
+ };
}
- if (@path && !$end) {
+ if (@path && !$end && !$keep_dot) {
length and $_ .= '(?:\.\w+)?' for $path[-1];
}
my $re = '^('.join('/','',@path).')'.$end.'$';
/\G(?:(?=[+|\)])|$)/gc and
return '';
# word chars only -> exact path part match
- /\G([\w\-]+)/gc and
+ /
+ \G(
+ (?: # start matching at a space followed by:
+ [\w\-] # word chars or dashes
+ | # OR
+ \. # a period
+ (?!\.) # not followed by another period
+ )
+ + # then grab as far as possible
+ )
+ /gcx and
return "\Q$1";
# ** -> capture unlimited path parts
/\G\*\*/gc and
sub _parse_param_handler {
my ($self, $spec, $type) = @_;
- require Web::Simple::ParamParser;
- my $unpacker = Web::Simple::ParamParser->can("get_unpacked_${type}_from");
-
for ($_[1]) {
my (@required, @single, %multi, $star, $multistar, %positional, $have_kw);
my %spec;
}
} while (/\G\&/gc) }
- return sub {
- my $raw = $unpacker->($_[0]);
- Web::Dispatch::Predicates::_extract_params($raw, \%spec);
- };
+ return Web::Dispatch::Predicates->can("match_${type}")->(\%spec);
}
}