mas_http/layers/
form_urlencoded_request.rs1use std::{future::Ready, marker::PhantomData, task::Poll};
16
17use bytes::Bytes;
18use futures_util::{
19 future::{Either, MapErr},
20 FutureExt, TryFutureExt,
21};
22use headers::{ContentType, HeaderMapExt};
23use http::Request;
24use serde::Serialize;
25use thiserror::Error;
26use tower::{Layer, Service};
27
28#[derive(Debug, Error)]
29pub enum Error<Service> {
30 #[error(transparent)]
31 Service { inner: Service },
32
33 #[error("could not serialize form payload")]
34 Serialize {
35 #[source]
36 inner: serde_urlencoded::ser::Error,
37 },
38}
39
40impl<S> Error<S> {
41 fn service(source: S) -> Self {
42 Self::Service { inner: source }
43 }
44
45 fn serialize(source: serde_urlencoded::ser::Error) -> Self {
46 Self::Serialize { inner: source }
47 }
48}
49
50#[derive(Clone)]
51pub struct FormUrlencodedRequest<S, T> {
52 inner: S,
53 _t: PhantomData<T>,
54}
55
56impl<S, T> FormUrlencodedRequest<S, T> {
57 pub const fn new(inner: S) -> Self {
58 Self {
59 inner,
60 _t: PhantomData,
61 }
62 }
63}
64
65impl<S, T> Service<Request<T>> for FormUrlencodedRequest<S, T>
66where
67 S: Service<Request<Bytes>>,
68 S::Future: Send + 'static,
69 S::Error: 'static,
70 T: Serialize,
71{
72 type Error = Error<S::Error>;
73 type Response = S::Response;
74 type Future = Either<
75 Ready<Result<Self::Response, Self::Error>>,
76 MapErr<S::Future, fn(S::Error) -> Self::Error>,
77 >;
78
79 fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
80 self.inner.poll_ready(cx).map_err(Error::service)
81 }
82
83 fn call(&mut self, request: Request<T>) -> Self::Future {
84 let (mut parts, body) = request.into_parts();
85
86 parts.headers.typed_insert(ContentType::form_url_encoded());
87
88 let body = match serde_urlencoded::to_string(&body) {
89 Ok(body) => Bytes::from(body),
90 Err(err) => return std::future::ready(Err(Error::serialize(err))).left_future(),
91 };
92
93 let request = Request::from_parts(parts, body);
94
95 self.inner
96 .call(request)
97 .map_err(Error::service as fn(S::Error) -> Self::Error)
98 .right_future()
99 }
100}
101
102#[derive(Clone, Copy)]
103pub struct FormUrlencodedRequestLayer<T> {
104 _t: PhantomData<T>,
105}
106
107impl<T> Default for FormUrlencodedRequestLayer<T> {
108 fn default() -> Self {
109 Self { _t: PhantomData }
110 }
111}
112
113impl<S, T> Layer<S> for FormUrlencodedRequestLayer<T> {
114 type Service = FormUrlencodedRequest<S, T>;
115
116 fn layer(&self, inner: S) -> Self::Service {
117 FormUrlencodedRequest::new(inner)
118 }
119}