hyperdriver/service/
make.rs

1use std::error::Error as StdError;
2use std::fmt;
3use std::future::Future;
4use std::sync::Arc;
5use std::task::{Context, Poll};
6
7use super::http::HttpService;
8use http_body::Body as HttpBody;
9use tower::Service;
10
11use tower::{layer::layer_fn, Layer, ServiceExt};
12
13use crate::BoxError;
14
15pub trait Sealed<Conn> {}
16
17/// A trait for types that can be used to make HTTP services, by recieving references to connections.
18pub trait MakeServiceRef<Target, ReqBody>: Sealed<(Target, ReqBody)> {
19    /// The `HttpBody` body of the `http::Response`.
20    type ResBody: HttpBody;
21
22    /// The error type that can occur within this `Service`.
23    type Error: Into<BoxError>;
24
25    /// The Service type produced to handle requests.
26    type Service: HttpService<ReqBody, ResBody = Self::ResBody, Error = Self::Error>;
27
28    /// The error type that occurs if we can't create the service.
29    type MakeError: Into<BoxError>;
30
31    /// The `Future` returned by this `MakeService`.
32    type Future: Future<Output = Result<Self::Service, Self::MakeError>>;
33
34    /// Poll the readiness of the make_serivce.
35    fn poll_ready_ref(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>>;
36
37    /// Create a new service.
38    fn make_service_ref(&mut self, target: &Target) -> Self::Future;
39}
40
41impl<T, Target, ME, S, F, IB> Sealed<(Target, IB)> for T where
42    T: for<'a> Service<&'a Target, Error = ME, Response = S, Future = F>
43{
44}
45
46impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target, IB> for T
47where
48    T: for<'a> Service<&'a Target, Error = ME, Response = S, Future = F>,
49    E: Into<Box<dyn StdError + Send + Sync>>,
50    ME: Into<Box<dyn StdError + Send + Sync>>,
51    S: HttpService<IB, ResBody = OB, Error = E>,
52    F: Future<Output = Result<S, ME>>,
53    IB: HttpBody,
54    OB: HttpBody,
55{
56    type Error = E;
57    type Service = S;
58    type ResBody = OB;
59    type MakeError = ME;
60    type Future = F;
61
62    fn poll_ready_ref(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::MakeError>> {
63        self.poll_ready(cx)
64    }
65
66    fn make_service_ref(&mut self, target: &Target) -> Self::Future {
67        self.call(target)
68    }
69}
70
71/// Create a `MakeService` from a function.
72///
73/// # Example
74///
75/// ```
76/// # #[cfg(feature = "runtime")]
77/// # async fn run() {
78/// use std::convert::Infallible;
79/// use hyperdriver::body::{Body, Request, Response};
80/// use hyperdriver::server::Server;
81/// use hyperdriver::server::service::{make_service_fn, service_fn};
82///
83/// let addr = ([127, 0, 0, 1], 3000).into();
84///
85/// let make_svc = make_service_fn(|socket: &AddrStream| {
86///     let remote_addr = socket.remote_addr();
87///     async move {
88///         Ok::<_, Infallible>(service_fn(move |_: Request<Body>| async move {
89///             Ok::<_, Infallible>(
90///                 Response::new(Body::from(format!("Hello, {}!", remote_addr)))
91///             )
92///         }))
93///     }
94/// });
95///
96/// // Then bind and serve...
97/// let server = Server::bind(&addr)
98///     .serve(make_svc);
99///
100/// // Finally, spawn `server` onto an Executor...
101/// if let Err(e) = server.await {
102///     eprintln!("server error: {}", e);
103/// }
104/// # }
105/// # fn main() {}
106/// ```
107pub fn make_service_fn<F, Target, Ret>(f: F) -> MakeServiceFn<F>
108where
109    F: FnMut(&Target) -> Ret,
110    Ret: Future,
111{
112    MakeServiceFn { f }
113}
114
115/// `MakeService` returned from [`make_service_fn`]
116#[derive(Clone, Copy)]
117pub struct MakeServiceFn<F> {
118    f: F,
119}
120
121impl<'t, F, Ret, Target, Svc, MkErr> Service<&'t Target> for MakeServiceFn<F>
122where
123    F: FnMut(&Target) -> Ret,
124    Ret: Future<Output = Result<Svc, MkErr>>,
125    MkErr: Into<Box<dyn StdError + Send + Sync>>,
126{
127    type Error = MkErr;
128    type Response = Svc;
129    type Future = Ret;
130
131    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
132        Poll::Ready(Ok(()))
133    }
134
135    fn call(&mut self, target: &'t Target) -> Self::Future {
136        (self.f)(target)
137    }
138}
139
140impl<F> fmt::Debug for MakeServiceFn<F> {
141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142        f.debug_struct("MakeServiceFn").finish()
143    }
144}
145
146//TODO: Should this really be 'static?
147type BoxFuture<T, E> = crate::BoxFuture<'static, Result<T, E>>;
148type ServiceRef<T, S, E> =
149    dyn for<'a> tower::Service<&'a T, Response = S, Error = E, Future = BoxFuture<S, E>> + Send;
150
151/// A boxed `ServiceRef`.
152pub struct BoxMakeServiceRef<Target, Service, MakeServiceError> {
153    inner: Box<ServiceRef<Target, Service, MakeServiceError>>,
154}
155
156impl<T, S, E> fmt::Debug for BoxMakeServiceRef<T, S, E> {
157    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158        f.debug_struct("BoxMakeServiceRef").finish()
159    }
160}
161
162impl<T, S, E> BoxMakeServiceRef<T, S, E> {
163    /// Create a new `BoxMakeServiceRef`.
164    pub fn new<U, F>(inner: U) -> Self
165    where
166        U: for<'a> Service<&'a T, Response = S, Error = E, Future = F> + Send + 'static,
167        F: Future<Output = Result<S, E>> + Send + 'static,
168        T: 'static,
169    {
170        let inner = Box::new(inner.map_future(|f| Box::pin(f) as _));
171        Self { inner }
172    }
173}
174
175impl<T, S, E> Service<&T> for BoxMakeServiceRef<T, S, E> {
176    type Response = S;
177    type Error = E;
178    type Future = BoxFuture<S, E>;
179
180    fn poll_ready(
181        &mut self,
182        cx: &mut std::task::Context<'_>,
183    ) -> std::task::Poll<Result<(), Self::Error>> {
184        self.inner.poll_ready(cx)
185    }
186
187    fn call(&mut self, target: &T) -> Self::Future {
188        self.inner.call(target)
189    }
190}
191
192/// A [`Layer`] that wraps an inner [`MakeServiceRef`] and returns a boxed [`MakeServiceRef`].
193pub struct BoxMakeServiceLayer<InnerMakeService, Target, InnerService, MakeServiceError> {
194    boxed: Arc<
195        dyn Layer<
196                InnerMakeService,
197                Service = BoxMakeServiceRef<Target, InnerService, MakeServiceError>,
198            > + Send
199            + Sync
200            + 'static,
201    >,
202}
203
204impl<In, T, U, E> BoxMakeServiceLayer<In, T, U, E> {
205    /// Create a new [`BoxMakeServiceLayer`].
206    pub fn new<L, F>(inner_layer: L) -> Self
207    where
208        L: Layer<In> + Send + Sync + 'static,
209        L::Service: for<'a> Service<&'a T, Response = U, Error = E, Future = F> + Send + 'static,
210        F: Future<Output = Result<U, E>> + Send + 'static,
211        T: 'static,
212    {
213        let layer = layer_fn(move |inner: In| {
214            let out = inner_layer.layer(inner);
215            BoxMakeServiceRef::new(out)
216        });
217
218        Self {
219            boxed: Arc::new(layer),
220        }
221    }
222}
223
224impl<In, T, U, E> Layer<In> for BoxMakeServiceLayer<In, T, U, E> {
225    type Service = BoxMakeServiceRef<T, U, E>;
226
227    fn layer(&self, inner: In) -> Self::Service {
228        self.boxed.layer(inner)
229    }
230}
231
232impl<In, T, U, E> Clone for BoxMakeServiceLayer<In, T, U, E> {
233    fn clone(&self) -> Self {
234        Self {
235            boxed: Arc::clone(&self.boxed),
236        }
237    }
238}
239
240impl<In, T, U, E> fmt::Debug for BoxMakeServiceLayer<In, T, U, E> {
241    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
242        fmt.debug_struct("BoxMakeServiceLayer").finish()
243    }
244}
245
246#[cfg(test)]
247mod tests {
248
249    use super::*;
250
251    use static_assertions::assert_impl_all;
252
253    assert_impl_all!(BoxMakeServiceLayer<(), (), (), ()>: Clone, Send, Sync);
254    assert_impl_all!(BoxMakeServiceRef<(), (), ()>: Send);
255}