intrepid_core/system/
stateless.rs

1use tower::Service;
2
3use crate::{ActionContext, Frame, FrameFuture, Handler};
4
5use super::System;
6
7/// A tag type for a system that has can be called without state. It's only possible to
8/// get to this status from an open status, and only if none of the actions in the system
9/// require state.
10#[derive(Clone, Copy, Default)]
11pub struct Stateless;
12
13/// A system which has been finalized without state. We can handle frames with this system.
14pub type StatelessSystem = System<Stateless, ()>;
15
16impl StatelessSystem {
17    /// Call the system with a frame.
18    pub fn handle_frame(self, frame: crate::Frame) -> FrameFuture {
19        match self {
20            Self::Batch(system) => system.handle_frame(frame),
21            Self::DispatchBatch(system) => system.handle_frame(frame),
22            Self::Routed(system) => system.handle_frame(frame),
23            Self::FirstMatch(system) => system.handle_frame(frame),
24        }
25    }
26}
27
28impl Handler<Frame, ()> for StatelessSystem {
29    type Future = FrameFuture;
30
31    fn invoke(&self, frame: impl Into<Frame>, _: ()) -> Self::Future {
32        let frame = frame.into();
33        let instance = self.clone();
34
35        match instance {
36            Self::Batch(system) => system.handle_frame(frame),
37            Self::DispatchBatch(system) => system.handle_frame(frame),
38            Self::Routed(system) => system.handle_frame(frame),
39            Self::FirstMatch(system) => system.handle_frame(frame),
40        }
41    }
42
43    fn context(&self) -> ActionContext<()> {
44        match self {
45            Self::Batch(system) => system.action_context(),
46            Self::DispatchBatch(system) => system.action_context(),
47            Self::Routed(system) => system.action_context(),
48            Self::FirstMatch(system) => system.action_context(),
49        }
50    }
51}
52
53impl<IntoFrame> Service<IntoFrame> for StatelessSystem
54where
55    IntoFrame: Into<Frame> + Clone + Send + 'static,
56{
57    type Response = Frame;
58    type Error = crate::Error;
59    type Future = FrameFuture;
60
61    fn poll_ready(
62        &mut self,
63        _: &mut std::task::Context<'_>,
64    ) -> std::task::Poll<Result<(), Self::Error>> {
65        std::task::Poll::Ready(Ok(()))
66    }
67
68    fn call(&mut self, frame: IntoFrame) -> Self::Future {
69        let frame: Frame = frame.into();
70        let instance = self.clone();
71
72        instance.invoke(frame, ())
73    }
74}