gaia_tmtc/
handler.rs

1use anyhow::Result;
2use async_trait::async_trait;
3use futures::future::BoxFuture;
4
5#[async_trait]
6pub trait Handle<Request> {
7    type Response;
8    async fn handle(&mut self, request: Request) -> Result<Self::Response>;
9}
10
11pub trait Layer<H> {
12    type Handle;
13    fn layer(self, handle: H) -> Self::Handle;
14}
15
16#[derive(Clone, Debug)]
17pub struct BeforeHookLayer<K> {
18    hook: K,
19}
20
21impl<K> BeforeHookLayer<K> {
22    pub fn new(hook: K) -> Self {
23        Self { hook }
24    }
25}
26
27impl<K, H> Layer<H> for BeforeHookLayer<K> {
28    type Handle = BeforeHook<H, K>;
29
30    fn layer(self, inner: H) -> Self::Handle {
31        BeforeHook {
32            hook: self.hook,
33            inner,
34        }
35    }
36}
37
38#[derive(Clone, Debug)]
39pub struct BeforeHook<H, K> {
40    hook: K,
41    inner: H,
42}
43
44#[async_trait]
45impl<Q, H, K> Handle<Q> for BeforeHook<H, K>
46where
47    Q: Send + 'static,
48    H: Handle<K::Output> + Send,
49    K: Hook<Q> + Send,
50    K::Output: Send,
51{
52    type Response = H::Response;
53
54    async fn handle(&mut self, request: Q) -> Result<Self::Response> {
55        let next_request = self.hook.hook(request).await?;
56        self.inner.handle(next_request).await
57    }
58}
59
60#[async_trait]
61pub trait Hook<Input> {
62    type Output;
63    async fn hook(&mut self, input: Input) -> Result<Self::Output>;
64}
65
66#[derive(Clone, Debug)]
67pub struct Choice<X, Y> {
68    first: X,
69    second: Y,
70}
71
72#[async_trait]
73impl<Q, S, X, Y> Handle<Q> for Choice<X, Y>
74where
75    Q: Clone + Send + Sync + 'static,
76    X: Handle<Q, Response = Option<S>> + Send,
77    Y: Handle<Q, Response = Option<S>> + Send,
78{
79    type Response = Option<S>;
80
81    async fn handle(&mut self, request: Q) -> Result<Self::Response> {
82        if let Some(ret) = self.first.handle(request.clone()).await? {
83            return Ok(Some(ret));
84        }
85        self.second.handle(request).await
86    }
87}
88
89pub trait HandleChoiceExt<Q>: Handle<Q> {
90    fn prepend<X>(self, first: X) -> Choice<X, Self>
91    where
92        Self: Sized,
93    {
94        Choice {
95            first,
96            second: self,
97        }
98    }
99
100    fn append<Y>(self, second: Y) -> Choice<Self, Y>
101    where
102        Self: Sized,
103    {
104        Choice {
105            first: self,
106            second,
107        }
108    }
109}
110
111impl<T: ?Sized, Q> HandleChoiceExt<Q> for T where T: Handle<Q> {}
112
113#[derive(Debug, Clone, Default)]
114pub struct Identity;
115
116impl<H> Layer<H> for Identity {
117    type Handle = H;
118
119    fn layer(self, inner: H) -> Self::Handle {
120        inner
121    }
122}
123
124#[derive(Clone, Debug)]
125pub enum Either<A, B> {
126    A(A),
127    B(B),
128}
129
130impl<A, B, H> Layer<H> for Either<A, B>
131where
132    A: Layer<H>,
133    B: Layer<H>,
134{
135    type Handle = Either<A::Handle, B::Handle>;
136
137    fn layer(self, inner: H) -> Self::Handle {
138        match self {
139            Either::A(a) => Either::A(a.layer(inner)),
140            Either::B(b) => Either::B(b.layer(inner)),
141        }
142    }
143}
144
145impl<A, B, Q> Handle<Q> for Either<A, B>
146where
147    A: Handle<Q>,
148    B: Handle<Q, Response = A::Response>,
149{
150    type Response = A::Response;
151
152    fn handle<'a: 's, 's>(&'a mut self, request: Q) -> BoxFuture<'s, Result<Self::Response>>
153    where
154        Self: 's,
155    {
156        match self {
157            Either::A(a) => a.handle(request),
158            Either::B(b) => b.handle(request),
159        }
160    }
161}
162
163#[derive(Clone, Debug)]
164pub struct Stack<I, O> {
165    inner: I,
166    outer: O,
167}
168
169impl<I, O> Stack<I, O> {
170    pub fn new(inner: I, outer: O) -> Stack<I, O> {
171        Self { inner, outer }
172    }
173}
174
175impl<I, O, H> Layer<H> for Stack<I, O>
176where
177    I: Layer<H>,
178    O: Layer<I::Handle>,
179{
180    type Handle = O::Handle;
181
182    fn layer(self, handle: H) -> Self::Handle {
183        self.outer.layer(self.inner.layer(handle))
184    }
185}
186
187#[derive(Clone, Debug)]
188pub struct Builder<L> {
189    layer: L,
190}
191
192impl Builder<Identity> {
193    pub fn new() -> Self {
194        Self { layer: Identity }
195    }
196}
197
198impl Default for Builder<Identity> {
199    fn default() -> Self {
200        Self::new()
201    }
202}
203
204impl<L> Builder<L> {
205    pub fn layer<I>(self, layer: I) -> Builder<Stack<I, L>> {
206        Builder {
207            layer: Stack::new(layer, self.layer),
208        }
209    }
210
211    pub fn option_layer<I>(self, layer: Option<I>) -> Builder<Stack<Either<I, Identity>, L>> {
212        let inner = match layer {
213            Some(layer) => Either::A(layer),
214            None => Either::B(Identity),
215        };
216        Builder {
217            layer: Stack::new(inner, self.layer),
218        }
219    }
220
221    pub fn before_hook<K>(self, hook: K) -> Builder<Stack<BeforeHookLayer<K>, L>> {
222        let before_hook = BeforeHookLayer::new(hook);
223        self.layer(before_hook)
224    }
225
226    pub fn build<H>(self, handle: H) -> L::Handle
227    where
228        L: Layer<H>,
229    {
230        self.layer.layer(handle)
231    }
232}