Skip to main content

cratestack_axum/envelope_layer/
service.rs

1//! [`EnvelopeService`]: the tower service the layer produces. The
2//! per-request decisions are in `dispatch`.
3
4use std::convert::Infallible;
5use std::future::Future;
6use std::pin::Pin;
7use std::sync::Arc;
8use std::task::{Context, Poll};
9
10use axum::extract::Request;
11use axum::response::Response;
12use tower::{Service, ServiceExt};
13
14use super::dispatch::dispatch;
15use super::layer::Config;
16
17/// What the layer wraps: a route of the generated router.
18pub(super) trait Inner:
19    Service<Request, Response = Response, Error = Infallible, Future: Send> + Clone + Send + 'static
20{
21}
22
23impl<S> Inner for S where
24    S: Service<Request, Response = Response, Error = Infallible, Future: Send>
25        + Clone
26        + Send
27        + 'static
28{
29}
30
31/// The service [`super::EnvelopeLayer`] produces.
32#[derive(Clone)]
33pub struct EnvelopeService<S> {
34    pub(super) inner: S,
35    pub(super) config: Arc<Config>,
36}
37
38impl<S> Service<Request> for EnvelopeService<S>
39where
40    S: Service<Request, Response = Response, Error = Infallible, Future: Send>
41        + Clone
42        + Send
43        + 'static,
44{
45    type Response = Response;
46    type Error = Infallible;
47    type Future = Pin<Box<dyn Future<Output = Result<Response, Infallible>> + Send>>;
48
49    /// Always ready: each call drives a clone of the inner service through
50    /// `oneshot`, which waits for that clone's readiness itself.
51    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
52        Poll::Ready(Ok(()))
53    }
54
55    fn call(&mut self, req: Request) -> Self::Future {
56        let inner = self.inner.clone();
57        let config = self.config.clone();
58        Box::pin(async move { Ok(dispatch(config, inner, req).await) })
59    }
60}
61
62pub(super) async fn call<S: Inner>(inner: S, req: Request) -> Response {
63    match inner.oneshot(req).await {
64        Ok(response) => response,
65        Err(never) => match never {},
66    }
67}