Router-Pygmy

 view release on metacpan or  search on metacpan

lib/Router/Pygmy.pm  view on Meta::CPAN

        my %args = ref $_[0] && ref $_[0] eq 'HASH' ? %{ $_[0] } : @_;

        if ( my $routes = $args{routes} ) {
            for my $spec ( keys %$routes ) {
                $router->add_route( $spec, $routes->{$spec} );
            }
        }
    }

    return $router;
}

sub new_route {
    my $this = shift;
    return Router::Pygmy::Route->parse(@_);
}

sub add_route {
    my ( $this, $spec, $name ) = @_;

    if ( my $duplicit_route = $this->{route_for}{$name} ) {
        croak sprintf "Duplicit routes for '$name' ('%s', '%s')",
          $duplicit_route->spec, $spec;
    }

    my $route  = $this->new_route($spec);
    my $lookup = $this->{lookup};
    for my $part ( @{ $route->parts } ) {
        $lookup = (
            defined($part)
            ? $lookup->[$PATH_PART_IDX]{$part}
            : $lookup->[$ARG_IDX]
        ) ||= [];
    }

    if ( my $duplicit_name = $lookup->[$ROUTE_IDX] ) {
        my $duplicit_route = $this->{route_for}{$duplicit_name};
        croak sprintf "Identical routes '%s', '%s'",
          $duplicit_route->spec, $route->spec;
    }

    $lookup->[$ROUTE_IDX] = $name;
    $this->{route_for}{$name} = $route;
    return $route;
}

# uri for
sub path_for {
    my $this = shift;
    my $name = shift;

    my $route = $this->{route_for}{$name}
      or croak "No route '$name'";
    return $route->path_for(@_);
}

# return (name, \@args)
sub match {
    my ( $this, $path ) = @_;

    my @parts = grep { length($_) > 0  } split m{/}, $path;
    my @args;

    my $lookup = $this->{lookup};

    while (@parts) {
        my $part = shift @parts;

        if ( my $by_path_part = $lookup->[$PATH_PART_IDX]{$part} ) {
            $lookup = $by_path_part;
        }
        elsif ( my $by_arg = $lookup->[$ARG_IDX] ) {
            push @args, $part;
            $lookup = $by_arg;
        }
        else {
            return;
        }
    }

    my $name = $lookup && $lookup->[$ROUTE_IDX];
    return $name ? ( $name, \@args ) : ();
}

sub match_named {
    my $this = shift;

    my ($name, $args) = $this->match(@_) or return;
    my $route = $this->{route_for}{$name};
    my $names = $route->arg_names;
    my $i = 0;
    return ( $name, [ map { ($names->[$i++] => $_) } @$args ]);
}

1;
# vim: expandtab:shiftwidth=4:tabstop=4:softtabstop=0:textwidth=78: 

__END__

=pod

=encoding UTF-8

=head1 NAME

Router::Pygmy - ultrasimple path router matching paths to names and args

=head1 VERSION

version 0.05

=head1 SYNOPSIS

    use Router::Pygmy;

    my $router = Router::Pygmy->new;
    $router->add_route( 'tree/:species/branches',    'tree.branches' );
    $router->add_route( 'tree/:species/:branch',     'tree.branch' );
    $router->add_route( 'tree/:species/:branch/nut', 'tree.nut' );

    # mapping path to ($name, \@args) or  ($name, \%params)



( run in 0.612 second using v1.01-cache-2.11-cpan-71847e10f99 )