Skip to content

Commit

Permalink
Seperate path routing logic from core router.
Browse files Browse the repository at this point in the history
  • Loading branch information
CathalMullan committed Nov 16, 2024
1 parent 2338095 commit 52477ce
Show file tree
Hide file tree
Showing 49 changed files with 1,529 additions and 1,458 deletions.
70 changes: 35 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ Dynamic parameters are greedy in nature, similar to a regex `.*`, and will attem

```rust
use std::error::Error;
use wayfind::{Router, RoutableBuilder, RequestBuilder};
use wayfind::{Router, RouteBuilder, RequestBuilder};

fn main() -> Result<(), Box<dyn Error>> {
let mut router = Router::new();

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/users/{id}")
.build()?;
router.insert(&route, 1)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/users/{id}/files/{filename}.{extension}")
.build()?;
router.insert(&route, 2)?;
Expand Down Expand Up @@ -95,17 +95,17 @@ Like dynamic parameters, wildcard parameters are also greedy in nature.

```rust
use std::error::Error;
use wayfind::{Router, RoutableBuilder, RequestBuilder};
use wayfind::{Router, RouteBuilder, RequestBuilder};

fn main() -> Result<(), Box<dyn Error>> {
let mut router = Router::new();

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/files/{*slug}/delete")
.build()?;
router.insert(&route, 1)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/{*catch_all}")
.build()?;
router.insert(&route, 2)?;
Expand Down Expand Up @@ -152,17 +152,17 @@ There is a small overhead to using optional groups, due to `Arc` usage internall

```rust
use std::error::Error;
use wayfind::{Router, RoutableBuilder, RequestBuilder};
use wayfind::{Router, RouteBuilder, RequestBuilder};

fn main() -> Result<(), Box<dyn Error>> {
let mut router = Router::new();

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/users(/{id})")
.build()?;
router.insert(&route, 1)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/files/{*slug}/{file}(.{extension})")
.build()?;
router.insert(&route, 2)?;
Expand Down Expand Up @@ -260,10 +260,10 @@ Curently, these can't be disabled.

```rust
use std::error::Error;
use wayfind::{Constraint, Router, RoutableBuilder, RequestBuilder};
use wayfind::{PathConstraint, Router, RouteBuilder, RequestBuilder};

struct NamespaceConstraint;
impl Constraint for NamespaceConstraint {
impl PathConstraint for NamespaceConstraint {
const NAME: &'static str = "namespace";

fn check(segment: &str) -> bool {
Expand All @@ -277,14 +277,14 @@ impl Constraint for NamespaceConstraint {

fn main() -> Result<(), Box<dyn Error>> {
let mut router = Router::new();
router.constraint::<NamespaceConstraint>()?;
router.path.constraint::<NamespaceConstraint>()?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/v2")
.build()?;
router.insert(&route, 1)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/v2/{*name:namespace}/blobs/{type}:{digest}")
.build()?;
router.insert(&route, 2)?;
Expand Down Expand Up @@ -323,7 +323,7 @@ Where possible, we try to provide user-friendly error messages.

```rust
use std::error::Error;
use wayfind::{Constraint, Router, errors::ConstraintError};
use wayfind::{PathConstraint, Router};

const ERROR_DISPLAY: &str = "
duplicate constraint name
Expand All @@ -340,7 +340,7 @@ try:
";

struct ConstraintA;
impl Constraint for ConstraintA {
impl PathConstraint for ConstraintA {
const NAME: &'static str = "my_constraint";

fn check(segment: &str) -> bool {
Expand All @@ -349,7 +349,7 @@ impl Constraint for ConstraintA {
}

struct ConstraintB;
impl Constraint for ConstraintB {
impl PathConstraint for ConstraintB {
const NAME: &'static str = "my_constraint";

fn check(segment: &str) -> bool {
Expand All @@ -359,9 +359,9 @@ impl Constraint for ConstraintB {

fn main() -> Result<(), Box<dyn Error>> {
let mut router: Router<usize> = Router::new();
router.constraint::<ConstraintA>()?;
router.path.constraint::<ConstraintA>()?;

let error = router.constraint::<ConstraintB>().unwrap_err();
let error = router.path.constraint::<ConstraintB>().unwrap_err();
assert_eq!(error.to_string(), ERROR_DISPLAY.trim());

Ok(())
Expand All @@ -380,7 +380,7 @@ Currenty, this doesn't handle split multi-byte characters well.

```rust
use std::error::Error;
use wayfind::{Router, RoutableBuilder};
use wayfind::{Router, RouteBuilder};

const ROUTER_DISPLAY: &str = "
/
Expand Down Expand Up @@ -409,77 +409,77 @@ const ROUTER_DISPLAY: &str = "
fn main() -> Result<(), Box<dyn Error>> {
let mut router = Router::new();

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/pet")
.build()?;
router.insert(&route, 1)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/pet/findByStatus")
.build()?;
router.insert(&route, 2)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/pet/findByTags")
.build()?;
router.insert(&route, 3)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/pet/{petId}")
.build()?;
router.insert(&route, 4)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/pet/{petId}/uploadImage")
.build()?;
router.insert(&route, 5)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/store/inventory")
.build()?;
router.insert(&route, 6)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/store/order")
.build()?;
router.insert(&route, 7)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/store/order/{orderId}")
.build()?;
router.insert(&route, 8)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/user")
.build()?;
router.insert(&route, 9)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/user/createWithList")
.build()?;
router.insert(&route, 10)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/user/login")
.build()?;
router.insert(&route, 11)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/user/logout")
.build()?;
router.insert(&route, 12)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/user/{username}")
.build()?;
router.insert(&route, 13)?;

let route = RoutableBuilder::new()
let route = RouteBuilder::new()
.route("/{*catch_all}")
.build()?;
router.insert(&route, 14)?;

assert_eq!(router.to_string(), ROUTER_DISPLAY.trim());
assert_eq!(router.path.to_string(), ROUTER_DISPLAY.trim());
Ok(())
}
```
Expand Down
16 changes: 5 additions & 11 deletions benches/gitlab_criterion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn insert_benchmark(criterion: &mut Criterion) {
|| router.clone(),
|mut router| {
for route in black_box(routes()) {
let route = wayfind::RoutableBuilder::new()
let route = wayfind::RouteBuilder::new()
.route(black_box(route))
.build()
.unwrap();
Expand All @@ -44,18 +44,15 @@ fn delete_benchmark(criterion: &mut Criterion) {
group.bench_function("gitlab delete benchmarks/wayfind", |bencher| {
let mut router = wayfind::Router::new();
for route in routes() {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, true).unwrap();
}

bencher.iter_batched(
|| router.clone(),
|mut router| {
for route in black_box(routes()) {
let route = wayfind::RoutableBuilder::new()
let route = wayfind::RouteBuilder::new()
.route(black_box(route))
.build()
.unwrap();
Expand All @@ -75,16 +72,13 @@ fn display_benchmark(criterion: &mut Criterion) {
group.bench_function("gitlab display benchmarks/wayfind", |bencher| {
let mut router = wayfind::Router::new();
for route in routes() {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, true).unwrap();
}

bencher.iter_batched(
|| router.clone(),
|router| router.to_string(),
|router| router.path.to_string(),
BatchSize::SmallInput,
);
});
Expand Down
19 changes: 5 additions & 14 deletions benches/gitlab_divan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn wayfind_insert(bencher: divan::Bencher<'_, '_>) {
let router = wayfind::Router::new();
bencher.with_inputs(|| router.clone()).bench_refs(|router| {
for route in black_box(routes()) {
let route = wayfind::RoutableBuilder::new()
let route = wayfind::RouteBuilder::new()
.route(black_box(route))
.build()
.unwrap();
Expand All @@ -29,19 +29,13 @@ fn wayfind_insert(bencher: divan::Bencher<'_, '_>) {
fn wayfind_delete(bencher: divan::Bencher<'_, '_>) {
let mut router = wayfind::Router::new();
for route in routes() {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, true).unwrap();
}

bencher.with_inputs(|| router.clone()).bench_refs(|router| {
for route in black_box(routes()) {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.delete(black_box(&route)).unwrap();
}
});
Expand All @@ -51,14 +45,11 @@ fn wayfind_delete(bencher: divan::Bencher<'_, '_>) {
fn wayfind_display(bencher: divan::Bencher<'_, '_>) {
let mut router = wayfind::Router::new();
for route in routes() {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, true).unwrap();
}

bencher
.with_inputs(|| router.clone())
.bench_refs(|router| router.to_string());
.bench_refs(|router| router.path.to_string());
}
5 changes: 1 addition & 4 deletions benches/matchit_criterion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ fn matchit_benchmark(criterion: &mut Criterion) {
group.bench_function("matchit benchmarks/wayfind", |bencher| {
let mut router = wayfind::Router::new();
for route in routes!(brackets) {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, true).unwrap();
}

Expand Down
5 changes: 1 addition & 4 deletions benches/matchit_divan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ fn main() {
fn wayfind(bencher: divan::Bencher<'_, '_>) {
let mut router = wayfind::Router::new();
for route in routes!(brackets) {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, true).unwrap();
}

Expand Down
5 changes: 1 addition & 4 deletions benches/path_tree_criterion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ fn path_tree_benchmark(criterion: &mut Criterion) {
group.bench_function("path-tree benchmarks/wayfind", |bencher| {
let mut router = wayfind::Router::new();
for (index, route) in routes!(brackets).iter().enumerate() {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, index).unwrap();
}

Expand Down
5 changes: 1 addition & 4 deletions benches/path_tree_divan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ fn main() {
fn wayfind(bencher: divan::Bencher<'_, '_>) {
let mut router = wayfind::Router::new();
for (index, route) in routes!(brackets).iter().enumerate() {
let route = wayfind::RoutableBuilder::new()
.route(route)
.build()
.unwrap();
let route = wayfind::RouteBuilder::new().route(route).build().unwrap();
router.insert(&route, index).unwrap();
}

Expand Down
4 changes: 2 additions & 2 deletions examples/oci/src/constraints/name.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use regex::Regex;
use std::sync::LazyLock;
use wayfind::Constraint;
use wayfind::PathConstraint;

/// Regex for validating path, lifted from Distribution Specification.
/// Note the addition of boundaries `^` and `$`, to ensure the entire segment matches.
Expand All @@ -12,7 +12,7 @@ static NAME_REGEX: LazyLock<Regex> = LazyLock::new(|| {
/// Constraint ensures that the `<name>` parameter in URLs adheres to the OCI Distribution Specification for repository names.
pub struct NameConstraint;

impl Constraint for NameConstraint {
impl PathConstraint for NameConstraint {
const NAME: &'static str = "name";

fn check(segment: &str) -> bool {
Expand Down
Loading

0 comments on commit 52477ce

Please sign in to comment.