[−][src]Crate match_request
Macros for creating request routers in hyper.
Request paths can be matched using a more convenient readable syntax, or using full regular expressions. Specific methods can be listed under each path.
The return value of a match can be anything, though you'll usually want to return a boxed function to use as a view.
Pattern syntax
Matching a request path:
use match_request::match_request; use hyper::Method; let path = "/user/home"; let (value, params) = match_request!(&Method::GET, path, { "/login" => { GET => "serve login form", }, "/user/home" => { GET => "serve home page", } }).unwrap(); assert_eq!(value, "serve home page");
Matching against multiple methods:
use match_request::match_request; use hyper::Method; let path = "/example"; let (value, params) = match_request!(&Method::DELETE, path, { "/login" => { GET => "serve login form", POST => "attempt login", }, "/example" => { GET => "serve example page", DELETE => "delete example page", } }).unwrap(); assert_eq!(value, "delete example page");
Named path parameters:
use match_request::match_request; use hyper::Method; let path = "/posts/2020/my-blog-post"; let (value, params) = match_request!(&Method::GET, path, { "/posts/:year/:slug" => { GET => "serve blog post", }, }).unwrap(); assert_eq!(params.get("year"), Some("2020")); assert_eq!(params.get("slug"), Some("my-blog-post"));
Capturing the path tail:
use match_request::match_request; use hyper::Method; let path = "/static/vendor/img/icon.png"; let (value, params) = match_request!(&Method::GET, path, { "/static/*" => { GET => "serve static assets", }, }).unwrap(); // NOTE: the leading `/` is included assert_eq!(params.tail(), Some("/vendor/img/icon.png"));
Example router
use match_request::{match_request, Error, Params}; use hyper::{Request, Response, Body}; use futures::future::{Future, BoxFuture}; // A boxed type definition for your async views. type BoxedView = Box< dyn Fn(Request<Body>, Params) -> BoxFuture<'static, Response<Body>> >; // Like a regular `match` expression, `match_request` requires all // arms to return the same type. As each `async fn` will have a different // type, you'll likely need to put them in a Box first. This example macro // is one way to do it. macro_rules! view { ($closure:expr) => {{ #[allow(unused_mut)] let mut closure = $closure; let b: BoxedView = Box::new(move |req, params| { Box::pin(closure(req, params)) }); b }}; } // An example request router. async fn router(req: Request<Body>) -> Result<Response<Body>, Error> { let method = req.method(); let path = req.uri().path(); // Attempt to match the request to a view. let (handler, params) = match_request!(method, path, { "/foo/bar" => { GET => view!(foo_bar), }, "/user/:name" => { GET => view!(user_profile), } })?; // Execute the view. Ok(handler(req, params).await) } // Example views... async fn foo_bar(_req: Request<Body>, _params: Params) -> Response<Body> { Response::new(Body::from("Foo bar")) } async fn user_profile(_req: Request<Body>, params: Params) -> Response<Body> { // Extracting a parameter from the path. let name = params.get("name").unwrap(); Response::new(Body::from(format!("Profile for {}", name))) }
Macros
match_request | Matches a request method and path against the provided patterns, returning the matched value (if any) and any captured parameters from the path. |
match_request_regex | Like |
Structs
Params | Parameters matched by a URL pattern. |
Enums
Error | Possible failures for the |
Functions
pattern | Converts a URL pattern to a String suitable for compilation as a regular expression. |