nidus_http/middleware/
request_scope.rs1use std::{
2 sync::Arc,
3 task::{Context, Poll},
4};
5
6use http::Request;
7use nidus_core::{Container, RequestScope, SharedRequestScope};
8use tower::{Layer, Service};
9
10pub fn request_scope_layer(container: Arc<Container>) -> RequestScopeLayer {
12 RequestScopeLayer::new(container)
13}
14
15#[derive(Clone)]
17pub struct RequestScopeLayer {
18 container: Arc<Container>,
19}
20
21impl RequestScopeLayer {
22 pub fn new(container: Arc<Container>) -> Self {
24 Self { container }
25 }
26}
27
28impl<S> Layer<S> for RequestScopeLayer {
29 type Service = RequestScopeService<S>;
30
31 fn layer(&self, inner: S) -> Self::Service {
32 RequestScopeService {
33 inner,
34 container: Arc::clone(&self.container),
35 }
36 }
37}
38
39#[derive(Clone)]
41pub struct RequestScopeService<S> {
42 inner: S,
43 container: Arc<Container>,
44}
45
46impl<S, RequestBody> Service<Request<RequestBody>> for RequestScopeService<S>
47where
48 S: Service<Request<RequestBody>> + Send + 'static,
49 S::Future: Send + 'static,
50 S::Error: Send + 'static,
51 RequestBody: Send + 'static,
52{
53 type Response = S::Response;
54 type Error = S::Error;
55 type Future = S::Future;
56
57 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
58 self.inner.poll_ready(cx)
59 }
60
61 fn call(&mut self, mut request: Request<RequestBody>) -> Self::Future {
62 let scope: SharedRequestScope = Arc::new(RequestScope::from_shared_container(Arc::clone(
63 &self.container,
64 )));
65 request.extensions_mut().insert(scope);
66 self.inner.call(request)
67 }
68}