routerify_query/
ext.rs

1use crate::Query;
2use hyper::Request;
3use std::collections::HashMap;
4
5/// An extension trait which extends the [`hyper::Request`](https://docs.rs/hyper/0.13.5/hyper/struct.Request.html) type with some helpful methods to
6/// access query values from `req` object.
7pub trait RequestQueryExt {
8    /// It returns the parsed queries in a [HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html).
9    ///
10    /// # Examples
11    ///
12    /// ```
13    /// use hyper::{Body, Request, Response, Server};
14    /// use routerify::{Router, RouterService};
15    /// // Import the query_parser function and the RequestQueryExt trait.
16    /// use routerify_query::{query_parser, RequestQueryExt};
17    /// use std::{convert::Infallible, net::SocketAddr};
18    ///
19    /// // A handler for "/" page. Visit: "/?username=Alice&bookname=HarryPotter" to see query values.
20    /// async fn home_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
21    ///     // Access the query values.
22    ///     let queries = req.queries();
23    ///
24    ///     let user_name = queries.get("username").unwrap();
25    ///     let book_name = queries.get("bookname").unwrap();
26    ///
27    ///     Ok(Response::new(Body::from(format!(
28    ///         "User: {}, Book: {}",
29    ///         user_name, book_name
30    ///     ))))
31    /// }
32    ///
33    /// # fn run() -> Router<Body, Infallible> {
34    /// // Create a router.
35    /// Router::builder()
36    ///   // Attach the query_parser middleware.
37    ///   .middleware(query_parser())
38    ///   .get("/", home_handler)
39    ///   .build()
40    ///   .unwrap()
41    /// }
42    /// # run();
43    /// ```
44    fn queries(&self) -> &HashMap<String, String>;
45
46    /// It returns the query value by a query name.
47    ///
48    /// # Examples
49    ///
50    /// ```
51    /// use hyper::{Body, Request, Response, Server};
52    /// use routerify::{Router, RouterService};
53    /// // Import the query_parser function and the RequestQueryExt trait.
54    /// use routerify_query::{query_parser, RequestQueryExt};
55    /// use std::{convert::Infallible, net::SocketAddr};
56    ///
57    /// // A handler for "/" page. Visit: "/?username=Alice&bookname=HarryPotter" to see query values.
58    /// async fn home_handler(req: Request<Body>) -> Result<Response<Body>, Infallible> {
59    ///     // Access the query values.
60    ///     let user_name = req.query("username").unwrap();
61    ///     let book_name = req.query("bookname").unwrap();
62    ///
63    ///     Ok(Response::new(Body::from(format!(
64    ///         "User: {}, Book: {}",
65    ///         user_name, book_name
66    ///     ))))
67    /// }
68    ///
69    /// # fn run() -> Router<Body, Infallible> {
70    /// // Create a router.
71    /// Router::builder()
72    ///   // Attach the query_parser middleware.
73    ///   .middleware(query_parser())
74    ///   .get("/", home_handler)
75    ///   .build()
76    ///   .unwrap()
77    /// }
78    /// # run();
79    /// ```
80    fn query<P: Into<String>>(&self, query_name: P) -> Option<&String>;
81}
82
83impl RequestQueryExt for Request<hyper::Body> {
84    fn queries(&self) -> &HashMap<String, String> {
85        self.extensions()
86            .get::<Query>()
87            .map(|q| &q.0)
88            .expect("Routerify-Query: No parsed queries added to the request object while processing request. Make sure the `query_parser` middleware is attached properly.")
89    }
90
91    fn query<P: Into<String>>(&self, query_name: P) -> Option<&String> {
92        self.queries().get(&query_name.into())
93    }
94}