cratestack_axum/envelope_layer/
service.rs1use 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
17pub(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#[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 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}