Web-Dispatcher-Simple
view release on metacpan or search on metacpan
lib/Web/Dispatcher/Simple.pm view on Meta::CPAN
package Web::Dispatcher::Simple;
use strict;
use warnings;
our $VERSION = '0.11';
use Carp ();
use Router::Simple;
use Try::Tiny;
use Web::Dispatcher::Simple::Request;
use Web::Dispatcher::Simple::Response;
use Scalar::Util qw(blessed);
my $_ROUTER = Router::Simple->new;
sub import {
my $caller = caller;
no strict 'refs';
no warnings 'redefine';
*{"${caller}::router"} = \&router;
my @http_methods = qw/get post put del any/;
for my $http_method (@http_methods) {
*{"${caller}\::$http_method"} = sub { goto \&$http_method };
}
strict->import;
warnings->import;
}
sub _stub {
my $name = shift;
return sub { Carp::croak("Can't call $name() outside router block") };
}
{
my @declarations = qw(get post put del any);
for my $keyword (@declarations) {
no strict 'refs';
*$keyword = _stub $keyword;
}
}
sub router (&) { ## no critic
my $block = shift;
if ($block) {
no warnings 'redefine';
local *get = sub { do_get(@_) };
local *post = sub { do_post(@_) };
local *put = sub { do_put(@_) };
local *del = sub { do_del(@_) };
local *any = sub { do_any(@_) };
$block->();
return sub { dispatch(shift) }
}
}
# HTTP Methods
sub route {
my ( $pattern, $code, $methods ) = @_;
unless ( ref $code eq 'CODE' ) {
Carp::croak("The logic for $pattern must be CodeRef");
}
$_ROUTER->connect(
$pattern,
{ action => $code },
{ method => [ map { uc $_ } @$methods ] }
);
}
sub do_any {
if ( scalar @_ == 4 ) {
my ( $methods, $pattern, $code ) = @_;
route( $pattern, $code, $methods );
}
else {
my ( $pattern, $code ) = @_;
route( $pattern, $code, [ 'GET', 'POST', 'DELETE', 'PUT', 'HEAD' ] );
}
}
sub do_get {
my ( $pattern, $code ) = @_;
route( $pattern, $code, [ 'GET', 'HEAD' ] );
( run in 1.166 second using v1.01-cache-2.11-cpan-39bf76dae61 )