A high performance, zero-copy URL router.
https://github.com/ibraheemdev/matchit.git
matchitA high performance, zero-copy URL router.
use matchit::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(())
}
The router supports dynamic route segments. These can either be named or catch-all parameters.
Named parameters like /{id} match anything until the next static segment or the end of the path.
``rust,ignore
let mut router = Router::new();
router.insert("/users/{id}", 42)?;
let matched = router.at("/users/1")?;
assert_eq!(matched.params.get("id"), Some("1"));
let matched = router.at("/users/23")?;
assert_eq!(matched.params.get("id"), Some("23"));
assert!(router.at("/users").is_err());
%%CODEBLOCK1%%rust,ignore
let mut router = Router::new();
router.insert("/images/img-{id}.png", true)?;
let matched = router.at("/images/img-1.png")?;
assert_eq!(matched.params.get("id"), Some("1"));
assert!(router.at("/images/img-1.jpg").is_err());
%%CODEBLOCK2%%rust,ignore
let mut router = Router::new();
router.insert("/{*rest}", true)?;
let matched = router.at("/foo.html")?;
assert_eq!(matched.params.get("rest"), Some("foo.html"));
let matched = router.at("/static/bar.css")?;
assert_eq!(matched.params.get("rest"), Some("static/bar.css"));
// Note that this would lead to an empty parameter value.
assert!(router.at("/").is_err());
%%CODEBLOCK3%%rust,ignore
let mut router = Router::new();
router.insert("/{{hello}}", true)?;
router.insert("/{hello}", true)?;
// Match the static route.
let matched = router.at("/{hello}")?;
assert!(matched.params.is_empty());
// Match the dynamic route.
let matched = router.at("/hello")?;
assert_eq!(matched.params.get("hello"), Some("hello"));
%%CODEBLOCK4%%rust,ignore
let mut router = Router::new();
router.insert("/", "Welcome!").unwrap(); // Priority: 1
router.insert("/about", "About Me").unwrap(); // Priority: 1
router.insert("/{*filepath}", "...").unwrap(); // Priority: 2
%%CODEBLOCK5%%text
Priority Path Value
9 \ 1
3 ├s None
2 |├earch\ 2
1 |└upport\ 3
2 ├blog\ 4
1 | └{post} None
1 | └\ 5
2 ├about-us\ 6
1 | └team\ 7
1 └contact\ 8
%%CODEBLOCK6%%text
Compare Routers/matchit
time: [2.4451 µs 2.4456 µs 2.4462 µs]
Compare Routers/gonzales
time: [4.2618 µs 4.2632 µs 4.2646 µs]
Compare Routers/path-tree
time: [4.8666 µs 4.8696 µs 4.8728 µs]
Compare Routers/wayfind
time: [4.9440 µs 4.9539 µs 4.9668 µs]
Compare Routers/route-recognizer
time: [49.203 µs 49.214 µs 49.226 µs]
Compare Routers/routefinder
time: [70.598 µs 70.636 µs 70.670 µs]
Compare Routers/actix
time: [453.91 µs 454.01 µs 454.11 µs]
Compare Routers/regex
time: [421.76 µs 421.82 µs 421.89 µs]
`
## Credits
A lot of the code in this package was inspired by Julien Schmidt's [httprouter`](https://github.com/julienschmidt/httprouter).