miku_http_util/request/parser/integration/
utils.rs

1//! Integration with other crates, utils
2
3use anyhow::Result;
4use http::Request;
5
6use crate::request::parser::OwnedQuery;
7
8/// Type alias for [`Result<OwnedQuery, ParseQueryError>`].
9///
10/// You may just need [`get_query`] to extract parsed [`Query`](OwnedQuery) from
11/// [`Extensions`](http::Extensions) within given [`Request`].
12pub type ParseQueryResult = Result<OwnedQuery, ParseQueryError>;
13
14#[inline]
15/// Helper function to extract parsed [`Query`](OwnedQuery) from
16/// [`Extensions`](http::Extensions) within given [`Request`].
17pub fn get_query<ReqBody>(request: &Request<ReqBody>) -> Result<Option<&OwnedQuery>> {
18    match request.extensions().get::<ParseQueryResult>() {
19        Some(Ok(data)) => Ok(Some(data)),
20        Some(Err(e)) => Err((*e).into()),
21        None => Ok(None),
22    }
23}
24
25#[derive(Debug, Clone, Copy)]
26#[derive(thiserror::Error)]
27/// `ParseQueryError`
28pub enum ParseQueryError {
29    #[error("missing query key `{0}`")]
30    /// Missing required query key
31    MissingKey(&'static str),
32}
33
34#[inline]
35pub(super) fn parse_query<ReqBody>(req: &mut Request<ReqBody>, required: &'static [&'static str]) {
36    match req.uri().query().map(OwnedQuery::parse) {
37        Some(owned_query) => {
38            #[cfg(feature = "feat-tracing")]
39            tracing::trace!("Found query: {:?}", owned_query);
40
41            let owned_query = required
42                .iter()
43                .find_map(|&key| {
44                    if !owned_query.contains_key(key) {
45                        #[cfg(feature = "feat-tracing")]
46                        tracing::error!(key, "Missing query key.");
47
48                        Some(ParseQueryResult::Err(ParseQueryError::MissingKey(key)))
49                    } else {
50                        None
51                    }
52                })
53                .unwrap_or(ParseQueryResult::Ok(owned_query));
54
55            req.extensions_mut().insert::<ParseQueryResult>(owned_query);
56        }
57        None => {
58            if !required.is_empty() {
59                #[cfg(feature = "feat-tracing")]
60                tracing::error!("Missing query.");
61
62                req.extensions_mut()
63                    .insert::<ParseQueryResult>(ParseQueryResult::Err(
64                        ParseQueryError::MissingKey(required[0]),
65                    ));
66            }
67        }
68    }
69}