miku_http_util/request/parser/integration/
integrate_tower.rs

1//! `tower` integration for [`OwnedQuery`](OwnedQuery).
2
3use std::{
4    marker::PhantomData,
5    task::{Context, Poll},
6};
7
8use anyhow::Result;
9use http::Request;
10use tower_layer::Layer;
11use tower_service::Service;
12
13use super::parse_query;
14
15#[deprecated(since = "0.6.0", note = "Renamed, use `WithQueryLayer` instead.")]
16/// Renamed, use [`WithQueryLayer`] instead.
17pub type QueriesLayer<ReqBody> = WithQueryLayer<ReqBody>;
18
19#[deprecated(since = "0.6.0", note = "Renamed, use `WithQueryService` instead.")]
20/// Renamed, use [`WithQueryLayer`] instead.
21pub type QueriesServcie<S, ReqBody> = WithQueryService<S, ReqBody>;
22
23#[derive(Debug, Default, Copy)]
24#[repr(transparent)]
25/// [`Layer`] for parsing [`OwnedQuery`] from a [`Request`] and insert into
26/// the [`Request`] extensions.
27pub struct WithQueryLayer<ReqBody> {
28    _req_body: PhantomData<ReqBody>,
29    required: &'static [&'static str],
30}
31
32// `ReqBody`, `ResBody` is just type markers, we actually don't care
33// about what actually it is, but the compiler will complain that *`Clone` is
34// needed* if we just `#[derive(Clone)]`
35impl<ReqBody> Clone for WithQueryLayer<ReqBody> {
36    fn clone(&self) -> Self {
37        Self {
38            _req_body: PhantomData,
39            required: self.required,
40        }
41    }
42}
43
44#[allow(unsafe_code)]
45// SAFETY: `ReqBody`, `ResBody` is just type markers, we actually don't care
46// about what actually it is, but compiler complains about `the type parameter
47// `B` is not constrained by ***`.
48unsafe impl<ReqBody> Sync for WithQueryLayer<ReqBody> {}
49
50impl<ReqBody> WithQueryLayer<ReqBody> {
51    /// Create a new [`WithQueryLayer`].
52    ///
53    /// # Params
54    ///
55    /// - `required`: required query keys
56    pub const fn new(required: &'static [&'static str]) -> Self {
57        Self {
58            _req_body: PhantomData,
59            required,
60        }
61    }
62}
63
64impl<S, ReqBody> Layer<S> for WithQueryLayer<ReqBody>
65where
66    S: Service<Request<ReqBody>> + Send + 'static,
67{
68    type Service = WithQueryService<S, ReqBody>;
69
70    fn layer(&self, inner: S) -> Self::Service {
71        WithQueryService {
72            inner,
73            required: self.required,
74            _req_body: PhantomData,
75        }
76    }
77}
78
79#[derive(Debug)]
80/// [`Service`] for parsing [`OwnedQuery`] from a [`Request`] and insert into
81/// the [`Request`] extensions.
82pub struct WithQueryService<S, ReqBody> {
83    inner: S,
84    required: &'static [&'static str],
85    _req_body: PhantomData<ReqBody>,
86}
87
88impl<S, ReqBody> WithQueryService<S, ReqBody> {
89    /// Create a new [`WithQueryService`].
90    ///
91    /// # Params
92    ///
93    /// - `required`: required query keys
94    pub const fn new(inner: S, required: &'static [&'static str]) -> Self {
95        Self {
96            inner,
97            required,
98            _req_body: PhantomData,
99        }
100    }
101}
102
103// `ReqBody`, `ResBody` is just type markers, we actually don't care
104// about what actually it is, but the compiler will complain that *`Clone` is
105// needed* if we just `#[derive(Clone)]`
106impl<S, ReqBody> Clone for WithQueryService<S, ReqBody>
107where
108    S: Clone,
109{
110    fn clone(&self) -> Self {
111        Self {
112            inner: self.inner.clone(),
113            required: self.required,
114            _req_body: PhantomData,
115        }
116    }
117}
118
119#[allow(unsafe_code)]
120// SAFETY: `ReqBody`, `ResBody` is just type markers, we actually don't care
121// about what actually it is, but compiler complains about `the type parameter
122// `B` is not constrained by ***`.
123unsafe impl<S, ReqBody> Sync for WithQueryService<S, ReqBody> where S: Sync {}
124
125impl<S, ReqBody> Service<Request<ReqBody>> for WithQueryService<S, ReqBody>
126where
127    S: Service<Request<ReqBody>> + Send + 'static,
128{
129    type Response = S::Response;
130    type Error = S::Error;
131    type Future = S::Future;
132
133    fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
134        self.inner.poll_ready(cx)
135    }
136
137    fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
138        parse_query(&mut req, self.required);
139
140        self.inner.call(req)
141    }
142}