under/endpoints/
scope.rs

1use std::pin::Pin;
2
3#[derive(Default, Debug)]
4/// A builder for a [`ScopeEndpoint`].
5///
6/// This takes in all of the middleware that should operate before the next
7/// endpoint, inserting it into an array.  It operates very similarly to the
8/// principle of [`crate::Router::with`].
9pub struct ScopeEndpointBuilder(Vec<Pin<Box<dyn crate::Middleware>>>);
10
11impl ScopeEndpointBuilder {
12    /// Appends middleware to the scope endpoint.  This operates very similarly
13    /// to [`crate::Router::with`].
14    pub fn with<M: crate::Middleware>(&mut self, middleware: M) -> &mut Self {
15        self.0.push(Box::pin(middleware));
16        self
17    }
18
19    /// Completes the builder, generating a [`ScopeEndpoint`].
20    ///
21    /// This does leave the builder in a usable state afterwards, resetting it
22    /// to the default state.
23    pub fn then<E: crate::Endpoint>(&mut self, endpoint: E) -> ScopeEndpoint {
24        let endpoint = Box::pin(endpoint);
25        let middleware = std::mem::take(&mut self.0);
26
27        ScopeEndpoint {
28            middleware,
29            endpoint,
30        }
31    }
32}
33
34#[derive(Debug)]
35/// The scope endpoint.
36///
37/// Created from [`ScopeEndpointBuilder`].  See [`super::scope()`] for more
38/// information.
39pub struct ScopeEndpoint {
40    middleware: Vec<Pin<Box<dyn crate::Middleware>>>,
41    endpoint: Pin<Box<dyn crate::Endpoint>>,
42}
43
44#[async_trait]
45impl crate::Endpoint for ScopeEndpoint {
46    async fn apply(
47        self: Pin<&Self>,
48        request: crate::Request,
49    ) -> Result<crate::Response, anyhow::Error> {
50        let next = crate::middleware::Next::new(&self.middleware[..], self.endpoint.as_ref());
51        next.apply(request).await
52    }
53}