miku_http_util/request/parser/integration/
integrate_tower.rs1use 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.")]
16pub type QueriesLayer<ReqBody> = WithQueryLayer<ReqBody>;
18
19#[deprecated(since = "0.6.0", note = "Renamed, use `WithQueryService` instead.")]
20pub type QueriesServcie<S, ReqBody> = WithQueryService<S, ReqBody>;
22
23#[derive(Debug, Default, Copy)]
24#[repr(transparent)]
25pub struct WithQueryLayer<ReqBody> {
28 _req_body: PhantomData<ReqBody>,
29 required: &'static [&'static str],
30}
31
32impl<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)]
45unsafe impl<ReqBody> Sync for WithQueryLayer<ReqBody> {}
49
50impl<ReqBody> WithQueryLayer<ReqBody> {
51 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)]
80pub 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 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
103impl<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)]
120unsafe 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}