a3s_boot/pipeline/
interceptor.rs1use super::ExecutionContext;
2use crate::{BootResponse, BoxFuture, Result};
3use std::sync::Arc;
4
5pub trait Interceptor: Send + Sync + 'static {
7 fn before(&self, _context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
8 Box::pin(async { Ok(()) })
9 }
10
11 fn after(
12 &self,
13 _context: ExecutionContext,
14 response: BootResponse,
15 ) -> BoxFuture<'static, Result<BootResponse>> {
16 Box::pin(async move { Ok(response) })
17 }
18}
19
20impl<F, Fut> Interceptor for F
21where
22 F: Fn(ExecutionContext) -> Fut + Send + Sync + 'static,
23 Fut: std::future::Future<Output = Result<()>> + Send + 'static,
24{
25 fn before(&self, context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
26 Box::pin(self(context))
27 }
28}
29
30pub trait ExecutionInterceptor: Send + Sync + 'static {
32 fn before(&self, _context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
33 Box::pin(async { Ok(()) })
34 }
35
36 fn after(&self, _context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
37 Box::pin(async { Ok(()) })
38 }
39}
40
41impl<F, Fut> ExecutionInterceptor for F
42where
43 F: Fn(ExecutionContext) -> Fut + Send + Sync + 'static,
44 Fut: std::future::Future<Output = Result<()>> + Send + 'static,
45{
46 fn before(&self, context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
47 Box::pin(self(context))
48 }
49}
50
51impl ExecutionInterceptor for Arc<dyn ExecutionInterceptor> {
52 fn before(&self, context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
53 self.as_ref().before(context)
54 }
55
56 fn after(&self, context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
57 self.as_ref().after(context)
58 }
59}
60
61pub(crate) struct ExecutionInterceptorAdapter<I> {
62 inner: I,
63}
64
65impl<I> ExecutionInterceptorAdapter<I> {
66 pub(crate) fn new(inner: I) -> Self {
67 Self { inner }
68 }
69}
70
71impl<I> Interceptor for ExecutionInterceptorAdapter<I>
72where
73 I: ExecutionInterceptor,
74{
75 fn before(&self, context: ExecutionContext) -> BoxFuture<'static, Result<()>> {
76 self.inner.before(context)
77 }
78
79 fn after(
80 &self,
81 context: ExecutionContext,
82 response: BootResponse,
83 ) -> BoxFuture<'static, Result<BootResponse>> {
84 let future = self.inner.after(context);
85 Box::pin(async move {
86 future.await?;
87 Ok(response)
88 })
89 }
90}