#url-router #matching #path-tree #router #url #tree #user-id #match

matchthem

A high performance, zero-copy URL router with support for multi-path, middleware-style matching, and rich param syntax

1 unstable release

0.0.1 May 6, 2025

#9 in #url-router

Download history 128/week @ 2025-05-06 26/week @ 2025-05-13 1/week @ 2025-05-20

155 downloads per month

MIT AND BSD-3-Clause

82KB
1.5K SLoC

matchthem

crates.io github docs.rs

A high performance, zero-copy URL router with multi-match support.

use matchthem::Router;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut router = Router::new();
    router.insert("/home", "Welcome!")?;
    router.insert("/users/{id}", "A User")?;

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

    Ok(())
}

About

matchthem is a fork of matchit, with all its performance and features — and one major addition: Multi-Match Traversal.

Instead of returning just the single most specific match, matchthem can return all matching routes for a given path.

While matchit returns the single most specific route that matches a path, matchthem adds two new methods:

🔍 Router::all_matches(&self, path: &str)

Returns all routes that match the given path. Each result includes both the matched value and any extracted parameters.

use matchthem::Router;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut router = Router::new();
    router.insert("/users/test", "Welcome!")?;
    router.insert("/users/{id}", "A User")?;

    let matches = router.all_matches("/users/test");
    for m in matches {
        println!("Matched value: {}", m.value);
    }

    Ok(())
}

![WARNING] Returned matches are not ordered by insertion. The order is determined by internal trie traversal.

Router exposes 2 more functions: all_matches, all_matches_mut.

✏️ Router::all_matches_mut(&mut self, path: &str)

Similar to all_matches, but provides mutable access to each matched value.

This is especially useful for collecting, modifying, or aggregating multiple matches in-place:

let mut router = Router::new();
router.insert("/{*baz}", vec!["a"]).unwrap();
router.insert("/foo/bar", vec!["b"]).unwrap();

for m in router.all_matches_mut("/foo/bar") {
    m.value.push("mutated");
}

Credits

See.

No runtime deps