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}