A speedy, flexible router for Rust.
wayfind
attempts to bridge the gap between existing Rust router options:
- fast routers, lacking in flexibility
- flexible routers, lacking in speed
Real-world projects often need fancy routing capabilities, such as projects ported from frameworks like Ruby on Rails, or those adhering to specifications like the Open Container Initiative (OCI) Distribution Specification.
The goal of wayfind
is to remain competitive with the fastest libraries, while offering advanced routing features when needed. Unused features shouldn't impact performance - you only pay for what you use.
[dependencies]
wayfind = "0.8"
use std::error::Error;
use wayfind::Router;
fn main() -> Result<(), Box<dyn Error>> {
let mut router = Router::new();
router.insert("/pet(/)", 1)?;
router.insert("/pet/findByStatus(/)", 2)?;
router.insert("/pet/findByTags(/)", 3)?;
router.insert("/pet/{pet}(/)", 4)?;
router.insert("/pet/{petId:u16}/uploadImage(/)", 5)?;
router.insert("/store/inventory(/)", 6)?;
router.insert("/store/order(/{orderId:u16})(/)", 7)?;
router.insert("/user(/)", 8)?;
router.insert("/user/createWithList(/)", 9)?;
router.insert("/user/login(/)", 10)?;
router.insert("/user/logout(/)", 11)?;
router.insert("/user/{username}(/)", 12)?;
router.insert("/{*catch_all}", 13)?;
let search = router.search("/pet").unwrap();
assert_eq!(*search.data, 1);
let search = router.search("/pet/").unwrap();
assert_eq!(*search.data, 1);
let search = router.search("/pet/123/uploadImage").unwrap();
assert_eq!(*search.data, 5);
assert_eq!(search.parameters[0], ("petId", "123"));
let search = router.search("/store/order").unwrap();
assert_eq!(*search.data, 7);
let search = router.search("/store/order/456").unwrap();
assert_eq!(*search.data, 7);
assert_eq!(search.parameters[0], ("orderId", "456"));
let search = router.search("/user/alice").unwrap();
assert_eq!(*search.data, 12);
assert_eq!(search.parameters[0], ("username", "alice"));
let search = router.search("/unknown/path").unwrap();
assert_eq!(*search.data, 13);
assert_eq!(search.parameters[0], ("catch_all", "unknown/path"));
println!("{router}");
Ok(())
}
/
├─ pet [*]
│ ╰─ / [*]
│ ├─ findBy
│ │ ├─ Status [*]
│ │ │ ╰─ / [*]
│ │ ╰─ Tags [*]
│ │ ╰─ / [*]
│ ├─ {petId:u16}
│ │ ╰─ /uploadImage [*]
│ │ ╰─ / [*]
│ ╰─ {pet} [*]
│ ╰─ / [*]
├─ store/
│ ├─ inventory [*]
│ │ ╰─ / [*]
│ ╰─ order [*]
│ ╰─ / [*]
│ ╰─ {orderId:u16} [*]
│ ╰─ / [*]
├─ user [*]
│ ╰─ / [*]
│ ├─ createWithList [*]
│ │ ╰─ / [*]
│ ├─ log
│ │ ├─ in [*]
│ │ │ ╰─ / [*]
│ │ ╰─ out [*]
│ │ ╰─ / [*]
│ ╰─ {username} [*]
│ ╰─ / [*]
╰─ {*catch_all} [*]
wayfind
is fast, and appears to be competitive against other top performers in all benchmarks we currently run.
See BENCHMARKING.md for the results.
wayfind
is licensed under the terms of both the MIT License and the Apache License (Version 2.0).
- poem: Initial experimentations started out as a Poem router fork
- matchit: Performance leader among pre-existing routers
- path-tree: Extensive testing and router display feature
- ASP.NET Core: Constraints-based approach to routing