X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FWeb%2FDispatch%2FPredicates.pm;h=db2ad880ad1831ca4b9ced5764783c9601005c5e;hb=75ad66d6b498a62a8ced06c4b4c404aa9533cf91;hp=f47605b5b179eb6ebe27edc55ca0c9cc9e647f50;hpb=ce573717455fc7127db16207de0342c65cc00ad5;p=catagits%2FWeb-Simple.git diff --git a/lib/Web/Dispatch/Predicates.pm b/lib/Web/Dispatch/Predicates.pm index f47605b..db2ad88 100644 --- a/lib/Web/Dispatch/Predicates.pm +++ b/lib/Web/Dispatch/Predicates.pm @@ -5,7 +5,7 @@ use base qw(Exporter); our @EXPORT = qw( match_and match_or match_not match_method match_path match_path_strip - match_extension + match_extension match_query match_body match_uploads ); sub match_and { @@ -101,4 +101,57 @@ sub match_extension { }; } +sub match_query { + _param_matcher(query => $_[0]); +} + +sub match_body { + _param_matcher(body => $_[0]); +} + +sub match_uploads { + _param_matcher(uploads => $_[0]); +} + +sub _param_matcher { + my ($type, $spec) = @_; + require Web::Dispatch::ParamParser; + my $unpack = Web::Dispatch::ParamParser->can("get_unpacked_${type}_from"); + sub { + _extract_params($unpack->($_[0]), $spec) + }; +} + +sub _extract_params { + my ($raw, $spec) = @_; + foreach my $name (@{$spec->{required}||[]}) { + return unless exists $raw->{$name}; + } + my @ret = ( + {}, + map { + $_->{multi} ? $raw->{$_->{name}}||[] : $raw->{$_->{name}}->[-1] + } @{$spec->{positional}||[]} + ); + # separated since 'or' is short circuit + my ($named, $star) = ($spec->{named}, $spec->{star}); + if ($named or $star) { + my %kw; + if ($star) { + @kw{keys %$raw} = ( + $star->{multi} + ? values %$raw + : map $_->[-1], values %$raw + ); + } + foreach my $n (@{$named||[]}) { + next if !$n->{multi} and !exists $raw->{$n->{name}}; + $kw{$n->{name}} = + $n->{multi} ? $raw->{$n->{name}}||[] : $raw->{$n->{name}}->[-1]; + } + push @ret, \%kw; + } + @ret; +} + 1;