intrepid_core/system/
stateless.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use tower::Service;

use crate::{ActionContext, Frame, FrameFuture, Handler};

use super::System;

/// A tag type for a system that has can be called without state. It's only possible to
/// get to this status from an open status, and only if none of the actions in the system
/// require state.
#[derive(Clone, Copy, Default)]
pub struct Stateless;

/// A system which has been finalized without state. We can handle frames with this system.
pub type StatelessSystem = System<Stateless, ()>;

impl StatelessSystem {
    /// Call the system with a frame.
    pub fn handle_frame(self, frame: crate::Frame) -> FrameFuture {
        match self {
            Self::Direct(system) => system.handle_frame(frame),
            Self::Dispatch(system) => system.handle_frame(frame),
            Self::Routed(system) => system.handle_frame(frame),
        }
    }
}

impl Handler<Frame, ()> for StatelessSystem {
    type Future = FrameFuture;

    fn invoke(&self, frame: impl Into<Frame>, _: ()) -> Self::Future {
        let frame = frame.into();
        let instance = self.clone();

        match instance {
            Self::Direct(system) => system.handle_frame(frame),
            Self::Dispatch(system) => system.handle_frame(frame),
            Self::Routed(system) => system.handle_frame(frame),
        }
    }

    fn context(&self) -> ActionContext<()> {
        match self {
            Self::Direct(system) => system.action_context(),
            Self::Dispatch(system) => system.action_context(),
            Self::Routed(system) => system.action_context(),
        }
    }
}

impl<IntoFrame> Service<IntoFrame> for StatelessSystem
where
    IntoFrame: Into<Frame> + Clone + Send + 'static,
{
    type Response = Frame;
    type Error = crate::Error;
    type Future = FrameFuture;

    fn poll_ready(
        &mut self,
        _: &mut std::task::Context<'_>,
    ) -> std::task::Poll<Result<(), Self::Error>> {
        std::task::Poll::Ready(Ok(()))
    }

    fn call(&mut self, frame: IntoFrame) -> Self::Future {
        let frame: Frame = frame.into();
        let instance = self.clone();

        instance.invoke(frame, ())
    }
}