3 releases (breaking)

0.3.0 Jul 24, 2024
0.2.0 Jan 19, 2024
0.1.0 Dec 29, 2023

#1194 in Web programming

Download history 229/week @ 2024-07-21 99/week @ 2024-07-28 147/week @ 2024-08-04 98/week @ 2024-08-11 252/week @ 2024-08-18 502/week @ 2024-08-25 482/week @ 2024-09-01 491/week @ 2024-09-08 455/week @ 2024-09-15 384/week @ 2024-09-22 293/week @ 2024-09-29 116/week @ 2024-10-06 102/week @ 2024-10-13 98/week @ 2024-10-20 357/week @ 2024-10-27 163/week @ 2024-11-03

733 downloads per month
Used in 4 crates (2 directly)

MIT license

105KB
2.5K SLoC

A fork of matchit

Compare to matchit

  • Pros
    • clean public types with no lifetime pollution. (easier to pass params around)
    • 100% safe Rust. (unsafe code still used through dependencies)
  • Cons
    • immutable router value.
    • potentially slower in micro benchmark.

lib.rs:

A fork of matchit using small string type for params lifetime elision.

let mut router = xitca_router::Router::new();
router.insert("/home", "Welcome!")?;
router.insert("/users/:id", "A User")?;

let matched = router.at("/users/978")?;
assert_eq!(*matched.value, "A User");

// params is owned value that can be sent between threads.
let params = matched.params;
std::thread::spawn(move || {
    assert_eq!(params.get("id"), Some("978"));
})
.join()
.unwrap();

Parameters

Along with static routes, the router also supports dynamic route segments. These can either be named or catch-all parameters:

Named Parameters

Named parameters like /:id match anything until the next / or the end of the path:

let mut m = xitca_router::Router::new();
m.insert("/users/:id", true)?;

assert_eq!(m.at("/users/1")?.params.get("id"), Some("1"));
assert_eq!(m.at("/users/23")?.params.get("id"), Some("23"));
assert!(m.at("/users").is_err());

Catch-all Parameters

Catch-all parameters start with * and match everything after the /. They must always be at the end of the route:

let mut m = xitca_router::Router::new();
m.insert("/*p", true)?;

assert_eq!(m.at("/foo.js")?.params.get("p"), Some("foo.js"));
assert_eq!(m.at("/c/bar.css")?.params.get("p"), Some("c/bar.css"));

Relaxed Catch-all Parameters

Relaxed Catch-all parameters with a single * and match everything after the /(Including / itself). Since there is no identifier for Params key associated they are left empty. They must always be at the end of the route:

let mut m = xitca_router::Router::new();
m.insert("/*", true)?;

assert!(m.at("/")?.value);
assert!(m.at("/foo")?.value);

Routing Priority

Static and dynamic route segments are allowed to overlap. If they do, static segments will be given higher priority:

let mut m = xitca_router::Router::new();
m.insert("/", "Welcome!").unwrap()    ;  // priority: 1
m.insert("/about", "About Me").unwrap(); // priority: 1
m.insert("/*filepath", "...").unwrap();  // priority: 2

Dependencies