hyper/service/
make.rs
1use std::error::Error as StdError;
2use std::fmt;
3
4use tokio::io::{AsyncRead, AsyncWrite};
5
6use super::{HttpService, Service};
7use crate::body::HttpBody;
8use crate::common::{task, Future, Poll};
9
10pub trait MakeConnection<Target>: self::sealed::Sealed<(Target,)> {
13 type Connection: AsyncRead + AsyncWrite;
14 type Error;
15 type Future: Future<Output = Result<Self::Connection, Self::Error>>;
16
17 fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
18 fn make_connection(&mut self, target: Target) -> Self::Future;
19}
20
21impl<S, Target> self::sealed::Sealed<(Target,)> for S where S: Service<Target> {}
22
23impl<S, Target> MakeConnection<Target> for S
24where
25 S: Service<Target>,
26 S::Response: AsyncRead + AsyncWrite,
27{
28 type Connection = S::Response;
29 type Error = S::Error;
30 type Future = S::Future;
31
32 fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
33 Service::poll_ready(self, cx)
34 }
35
36 fn make_connection(&mut self, target: Target) -> Self::Future {
37 Service::call(self, target)
38 }
39}
40
41pub trait MakeServiceRef<Target, ReqBody>: self::sealed::Sealed<(Target, ReqBody)> {
44 type ResBody: HttpBody;
45 type Error: Into<Box<dyn StdError + Send + Sync>>;
46 type Service: HttpService<ReqBody, ResBody = Self::ResBody, Error = Self::Error>;
47 type MakeError: Into<Box<dyn StdError + Send + Sync>>;
48 type Future: Future<Output = Result<Self::Service, Self::MakeError>>;
49
50 type __DontNameMe: self::sealed::CantImpl;
60
61 fn poll_ready_ref(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>>;
62
63 fn make_service_ref(&mut self, target: &Target) -> Self::Future;
64}
65
66impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target, IB> for T
67where
68 T: for<'a> Service<&'a Target, Error = ME, Response = S, Future = F>,
69 E: Into<Box<dyn StdError + Send + Sync>>,
70 ME: Into<Box<dyn StdError + Send + Sync>>,
71 S: HttpService<IB, ResBody = OB, Error = E>,
72 F: Future<Output = Result<S, ME>>,
73 IB: HttpBody,
74 OB: HttpBody,
75{
76 type Error = E;
77 type Service = S;
78 type ResBody = OB;
79 type MakeError = ME;
80 type Future = F;
81
82 type __DontNameMe = self::sealed::CantName;
83
84 fn poll_ready_ref(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>> {
85 self.poll_ready(cx)
86 }
87
88 fn make_service_ref(&mut self, target: &Target) -> Self::Future {
89 self.call(target)
90 }
91}
92
93impl<T, Target, S, B1, B2> self::sealed::Sealed<(Target, B1)> for T
94where
95 T: for<'a> Service<&'a Target, Response = S>,
96 S: HttpService<B1, ResBody = B2>,
97 B1: HttpBody,
98 B2: HttpBody,
99{
100}
101
102pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F>
139where
140 F: FnMut(&Target) -> Ret,
141 Ret: Future,
142{
143 MakeServiceFn { f }
144}
145
146#[derive(Clone, Copy)]
148pub struct MakeServiceFn<F> {
149 f: F,
150}
151
152impl<'t, F, Ret, Target, Svc, MkErr> Service<&'t Target> for MakeServiceFn<F>
153where
154 F: FnMut(&Target) -> Ret,
155 Ret: Future<Output = Result<Svc, MkErr>>,
156 MkErr: Into<Box<dyn StdError + Send + Sync>>,
157{
158 type Error = MkErr;
159 type Response = Svc;
160 type Future = Ret;
161
162 fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
163 Poll::Ready(Ok(()))
164 }
165
166 fn call(&mut self, target: &'t Target) -> Self::Future {
167 (self.f)(target)
168 }
169}
170
171impl<F> fmt::Debug for MakeServiceFn<F> {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 f.debug_struct("MakeServiceFn").finish()
174 }
175}
176
177mod sealed {
178 pub trait Sealed<X> {}
179
180 #[allow(unreachable_pub)] pub trait CantImpl {}
182
183 #[allow(missing_debug_implementations)]
184 pub enum CantName {}
185
186 impl CantImpl for CantName {}
187}