Skip to content

Commit

Permalink
Expose path ID and chains in router display.
Browse files Browse the repository at this point in the history
  • Loading branch information
CathalMullan committed Dec 19, 2024
1 parent c2c829f commit 3e9d6b9
Show file tree
Hide file tree
Showing 20 changed files with 3,927 additions and 3,721 deletions.
50 changes: 33 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,28 +452,44 @@ fn main() -> Result<(), Box<dyn Error>> {
.build()?;
router.insert(&route, 14)?;

insta::assert_snapshot!(router.path, @r"
insta::assert_snapshot!(router, @r"
=== Path
/
├─ user [*]
├─ user [9]
│ ╰─ /
│ ├─ createWithList [*]
│ ├─ createWithList [10]
│ ├─ log
│ │ ├─ out [*]
│ │ ╰─ in [*]
│ ╰─ {username} [*]
├─ pet [*]
│ │ ├─ out [12]
│ │ ╰─ in [11]
│ ╰─ {username} [13]
├─ pet [1]
│ ╰─ /
│ ├─ findBy
│ │ ├─ Status [*]
│ │ ╰─ Tags [*]
│ ╰─ {petId} [*]
│ ╰─ /uploadImage [*]
│ │ ├─ Status [2]
│ │ ╰─ Tags [3]
│ ╰─ {petId} [4]
│ ╰─ /uploadImage [5]
├─ store/
│ ├─ inventory [*]
│ ╰─ order [*]
│ ├─ inventory [6]
│ ╰─ order [7]
│ ╰─ /
│ ╰─ {orderId} [*]
╰─ {*catch_all} [*]
│ ╰─ {orderId} [8]
╰─ {*catch_all} [14]
=== Chains
1
2
3
4
5
6
7
8
9
10
11
12
13
14
");

Ok(())
Expand Down Expand Up @@ -508,7 +524,7 @@ In a router of 130 routes, benchmark matching 4 paths.

| Library | Time | Alloc Count | Alloc Size | Dealloc Count | Dealloc Size |
|:-----------------|----------:|------------:|-----------:|--------------:|-------------:|
| wayfind | 401.83 ns | 5 | 329 B | 5 | 329 B |
| wayfind | 422.40 ns | 5 | 329 B | 5 | 329 B |
| matchit | 571.88 ns | 5 | 480 B | 5 | 512 B |
| path-tree | 584.19 ns | 5 | 480 B | 5 | 512 B |
| xitca-router | 652.85 ns | 8 | 864 B | 8 | 896 B |
Expand All @@ -523,7 +539,7 @@ In a router of 320 routes, benchmark matching 80 paths.

| Library | Time | Alloc Count | Alloc Size | Dealloc Count | Dealloc Size |
|:-----------------|----------:|------------:|-----------:|--------------:|-------------:|
| wayfind | 5.8701 µs | 60 | 3.847 KB | 60 | 3.847 KB |
| wayfind | 5.7526 µs | 60 | 3.847 KB | 60 | 3.847 KB |
| path-tree | 8.6580 µs | 60 | 8.727 KB | 60 | 8.75 KB |
| matchit | 9.9301 µs | 141 | 19.09 KB | 141 | 19.11 KB |
| xitca-router | 11.894 µs | 210 | 26.79 KB | 210 | 26.81 KB |
Expand Down
2 changes: 1 addition & 1 deletion benches/gitlab_criterion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fn display_benchmark(criterion: &mut Criterion) {

bencher.iter_batched(
|| router.clone(),
|router| router.path.to_string(),
|router| router.to_string(),
BatchSize::SmallInput,
);
});
Expand Down
2 changes: 1 addition & 1 deletion benches/gitlab_divan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ fn wayfind_display(bencher: divan::Bencher<'_, '_>) {

bencher
.with_inputs(|| router.clone())
.bench_refs(|router| router.path.to_string());
.bench_refs(|router| router.to_string());
}
9 changes: 8 additions & 1 deletion src/chain.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use crate::routers::path::id::PathId;
use std::fmt::Display;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct DataChain {
pub path: PathId,
}

impl Display for DataChain {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.path)
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![doc = include_str!("../README.md")]

pub(crate) mod chain;
pub use chain::DataChain;

pub(crate) mod decode;

Expand Down
19 changes: 15 additions & 4 deletions src/routers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
Request, Route,
};
use path::{PathParameters, PathRouter};
use std::collections::HashMap;
use std::collections::BTreeMap;

pub mod path;

Expand All @@ -24,15 +24,15 @@ pub struct PathMatch<'r, 'p> {
#[derive(Clone)]
pub struct Router<'r, T> {
pub path: PathRouter<'r>,
data: HashMap<DataChain, T>,
data: BTreeMap<DataChain, T>,
}

impl<'r, T> Router<'r, T> {
#[must_use]
pub fn new() -> Self {
Self {
path: PathRouter::new(),
data: HashMap::default(),
data: BTreeMap::default(),
}
}

Expand Down Expand Up @@ -85,10 +85,21 @@ impl<T> std::fmt::Display for Router<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "=== Path")?;
let path = self.path.to_string();
if !path.is_empty() {
if path.is_empty() {
write!(f, "\nEmpty")?;
} else {
write!(f, "\n{path}")?;
}

write!(f, "\n=== Chains")?;
if self.data.is_empty() {
write!(f, "\nEmpty")?;
} else {
for chain in self.data.keys() {
write!(f, "\n{chain}")?;
}
}

Ok(())
}
}
11 changes: 5 additions & 6 deletions src/routers/path/display.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::Node;
use crate::routers::path::state::State;
use crate::routers::path::{node::Node, state::State};
use std::fmt::{Display, Write};

impl<S: State> Display for Node<'_, S> {
Expand All @@ -14,15 +13,15 @@ impl<S: State> Display for Node<'_, S> {
let key = node.state.key();

if is_top {
if node.data.is_some() {
writeln!(output, "{key} [*]")?;
if let Some(data) = node.data.as_ref() {
writeln!(output, "{key} [{}]", data.id)?;
} else {
writeln!(output, "{key}")?;
}
} else {
let branch = if is_last { "╰─" } else { "├─" };
if node.data.is_some() {
writeln!(output, "{padding}{branch} {key} [*]")?;
if let Some(data) = node.data.as_ref() {
writeln!(output, "{padding}{branch} {key} [{}]", data.id)?;
} else {
writeln!(output, "{padding}{branch} {key}")?;
}
Expand Down
10 changes: 9 additions & 1 deletion src/routers/path/id.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

#[derive(Clone, Default)]
pub struct PathIdGenerator {
id: usize,
Expand All @@ -10,5 +12,11 @@ impl PathIdGenerator {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct PathId(pub usize);

impl Display for PathId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
22 changes: 16 additions & 6 deletions tests/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ fn test_constraint_dynamic() -> Result<(), Box<dyn Error>> {
insta::assert_snapshot!(router, @r"
=== Path
/users/
╰─ {id:name} [*]
╰─ {id:name} [1]
=== Chains
1
");

let request = RequestBuilder::new().path("/users/john123").build()?;
Expand Down Expand Up @@ -60,7 +62,9 @@ fn test_constraint_wildcard() -> Result<(), Box<dyn Error>> {
insta::assert_snapshot!(router, @r"
=== Path
/users/
╰─ {*path:name} [*]
╰─ {*path:name} [1]
=== Chains
1
");

let request = RequestBuilder::new().path("/users/john/doe123").build()?;
Expand Down Expand Up @@ -148,8 +152,11 @@ fn test_constraint_builtin() -> Result<(), Box<dyn Error>> {
insta::assert_snapshot!(router, @r"
=== Path
/users/
├─ {id:u32} [*]
╰─ {id} [*]
├─ {id:u32} [2]
╰─ {id} [1]
=== Chains
1
2
");

let request = RequestBuilder::new().path("/users/abc").build()?;
Expand Down Expand Up @@ -197,8 +204,11 @@ fn test_constraint_unreachable() -> Result<(), Box<dyn Error>> {
insta::assert_snapshot!(router, @r"
=== Path
/users/
├─ {id:name} [*]
╰─ {id:u32} [*]
├─ {id:name} [2]
╰─ {id:u32} [1]
=== Chains
1
2
");

let request = RequestBuilder::new().path("/users/123").build()?;
Expand Down
52 changes: 39 additions & 13 deletions tests/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ fn test_delete() -> Result<(), Box<dyn Error>> {

insta::assert_snapshot!(router, @r"
=== Path
/test [*]
/test [1]
=== Chains
1
");

let route = RouteBuilder::new().route("/tests").build()?;
Expand All @@ -27,7 +29,9 @@ fn test_delete() -> Result<(), Box<dyn Error>> {

insta::assert_snapshot!(router, @r"
=== Path
/test [*]
/test [1]
=== Chains
1
");

let route = RouteBuilder::new().route("(/test)").build()?;
Expand All @@ -47,12 +51,19 @@ fn test_delete() -> Result<(), Box<dyn Error>> {

insta::assert_snapshot!(router, @r"
=== Path
/test [*]
/test [1]
=== Chains
1
");

let route = RouteBuilder::new().route("/test").build()?;
router.delete(&route)?;
insta::assert_snapshot!(router, @"=== Path");
insta::assert_snapshot!(router, @r"
=== Path
Empty
=== Chains
Empty
");

Ok(())
}
Expand All @@ -66,8 +77,10 @@ fn test_delete_mismatch() -> Result<(), Box<dyn Error>> {

insta::assert_snapshot!(router, @r"
=== Path
/ [*]
╰─ test [*]
/ [1]
╰─ test [1]
=== Chains
1
");

let route = RouteBuilder::new().route("/test").build()?;
Expand All @@ -82,8 +95,10 @@ fn test_delete_mismatch() -> Result<(), Box<dyn Error>> {

insta::assert_snapshot!(router, @r"
=== Path
/ [*]
╰─ test [*]
/ [1]
╰─ test [1]
=== Chains
1
");

let route = RouteBuilder::new().route("/").build()?;
Expand All @@ -98,13 +113,20 @@ fn test_delete_mismatch() -> Result<(), Box<dyn Error>> {

insta::assert_snapshot!(router, @r"
=== Path
/ [*]
╰─ test [*]
/ [1]
╰─ test [1]
=== Chains
1
");

let route = RouteBuilder::new().route("(/test)").build()?;
router.delete(&route)?;
insta::assert_snapshot!(router, @"=== Path");
insta::assert_snapshot!(router, @r"
=== Path
Empty
=== Chains
Empty
");

Ok(())
}
Expand All @@ -120,7 +142,9 @@ fn test_delete_empty() -> Result<(), Box<dyn Error>> {
=== Path
/
╰─ {id}
╰─ data [*]
╰─ data [1]
=== Chains
1
");

let route = RouteBuilder::new().route("/{id}").build()?;
Expand All @@ -136,7 +160,9 @@ fn test_delete_empty() -> Result<(), Box<dyn Error>> {
=== Path
/
╰─ {id}
╰─ data [*]
╰─ data [1]
=== Chains
1
");

Ok(())
Expand Down
Loading

0 comments on commit 3e9d6b9

Please sign in to comment.