Skip to content

Commit

Permalink
merge into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ibraheemdev committed Sep 22, 2023
2 parents 88e6249 + 007c71b commit 55b37bf
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 108 deletions.
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "matchit"
version = "0.7.0"
license = "MIT"
version = "0.7.2"
license = "MIT AND BSD-3-Clause"
authors = ["Ibraheem Ahmed <[email protected]>"]
edition = "2021"
description = "A blazing fast URL router."
Expand All @@ -22,6 +22,11 @@ gonzales = "0.0.3-beta"
path-tree = "0.2.2"
routefinder = "0.5.2"

# examples
tower = { version = "0.4", features = ["make", "util"] }
tokio = { version = "1", features = ["full"] }
hyper = { version = "0.14", features = ["full"] }

[features]
default = []
__test_helpers = []
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# `matchit`

[![Documentation](https://img.shields.io/badge/docs-0.7.0-4d76ae?style=for-the-badge)](https://docs.rs/matchit)
[![Documentation](https://img.shields.io/badge/docs-0.7.2-4d76ae?style=for-the-badge)](https://docs.rs/matchit)
[![Version](https://img.shields.io/crates/v/matchit?style=for-the-badge)](https://crates.io/crates/matchit)
[![License](https://img.shields.io/crates/l/matchit?style=for-the-badge)](https://crates.io/crates/matchit)
[![Actions](https://img.shields.io/github/workflow/status/ibraheemdev/matchit/Rust/master?style=for-the-badge)](https://github.com/ibraheemdev/matchit/actions)

A blazing fast URL router.
A high performance, zero-copy URL router.

```rust
use matchit::Router;
Expand Down Expand Up @@ -48,9 +47,11 @@ Catch-all parameters start with `*` and match everything after the `/`. They mus
let mut m = Router::new();
m.insert("/*p", true)?;
assert_eq!(m.at("/")?.params.get("p"), Some(""));
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"));
// note that this would not match:
assert_eq!(m.at("/").is_err());
```

## Routing Priority
Expand Down
87 changes: 87 additions & 0 deletions examples/hyper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use std::collections::HashMap;
use std::convert::Infallible;
use std::sync::{Arc, Mutex};

use hyper::server::Server;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response};
use tower::util::BoxCloneService;
use tower::Service as _;

// GET /
async fn index(_req: Request<Body>) -> hyper::Result<Response<Body>> {
Ok(Response::new(Body::from("Hello, world!")))
}

// GET /blog
async fn blog(_req: Request<Body>) -> hyper::Result<Response<Body>> {
Ok(Response::new(Body::from("...")))
}

// 404 handler
async fn not_found(_req: Request<Body>) -> hyper::Result<Response<Body>> {
Ok(Response::builder().status(404).body(Body::empty()).unwrap())
}

// We can use `BoxCloneService` to erase the type of each handler service.
//
// We still need a `Mutex` around each service because `BoxCloneService` doesn't
// require the service to implement `Sync`.
type Service = Mutex<BoxCloneService<Request<Body>, Response<Body>, hyper::Error>>;

// We use a `HashMap` to hold a `Router` for each HTTP method. This allows us
// to register the same route for multiple methods.
type Router = HashMap<Method, matchit::Router<Service>>;

async fn route(router: Arc<Router>, req: Request<Body>) -> hyper::Result<Response<Body>> {
// find the subrouter for this request method
let router = match router.get(req.method()) {
Some(router) => router,
// if there are no routes for this method, respond with 405 Method Not Allowed
None => return Ok(Response::builder().status(405).body(Body::empty()).unwrap()),
};

// find the service for this request path
match router.at(req.uri().path()) {
Ok(found) => {
// lock the service for a very short time, just to clone the service
let mut service = found.value.lock().unwrap().clone();
service.call(req).await
}
// if we there is no matching service, call the 404 handler
Err(_) => not_found(req).await,
}
}

#[tokio::main]
async fn main() {
// Create a router and register our routes.
let mut router = Router::new();

// GET / => `index`
router
.entry(Method::GET)
.or_default()
.insert("/", BoxCloneService::new(service_fn(index)).into())
.unwrap();

// GET /blog => `blog`
router
.entry(Method::GET)
.or_default()
.insert("/blog", BoxCloneService::new(service_fn(blog)).into())
.unwrap();

// boilerplate for the hyper service
let router = Arc::new(router);
let make_service = make_service_fn(|_| {
let router = router.clone();
async { Ok::<_, Infallible>(service_fn(move |request| route(router.clone(), request))) }
});

// run the server
Server::bind(&([127, 0, 0, 1], 3000).into())
.serve(make_service)
.await
.unwrap()
}
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
//! # `matchit`
//!
//! [![Documentation](https://img.shields.io/badge/docs-0.7.0-4d76ae?style=for-the-badge)](https://docs.rs/matchit)
//! [![Documentation](https://img.shields.io/badge/docs-0.7.2-4d76ae?style=for-the-badge)](https://docs.rs/matchit)
//! [![Version](https://img.shields.io/crates/v/matchit?style=for-the-badge)](https://crates.io/crates/matchit)
//! [![License](https://img.shields.io/crates/l/matchit?style=for-the-badge)](https://crates.io/crates/matchit)
//! [![Actions](https://img.shields.io/github/workflow/status/ibraheemdev/matchit/Rust/master?style=for-the-badge)](https://github.com/ibraheemdev/matchit/actions)
//!
//! A blazing fast URL router.
//!
Expand Down Expand Up @@ -57,6 +56,9 @@
//! 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"));
//!
//! // note that this would not match
//! assert!(m.at("/").is_err());
//!
//! # Ok(())
//! # }
//! ```
Expand Down
Loading

0 comments on commit 55b37bf

Please sign in to comment.