intrepid_core/system/
stateful.rs1use tower::Service;
2
3use crate::{ActionContext, Frame, FrameFuture, Handler};
4
5use super::System;
6
7#[derive(Clone, Copy, Default)]
12pub struct Stateful<State>(pub State);
13
14pub type StatefulSystem<State> = System<Stateful<State>, State>;
19
20impl<State> StatefulSystem<State>
21where
22 State: Clone + Send + Sync + 'static,
23{
24 pub async fn handle_frame(self, frame: crate::Frame) -> crate::Result<Frame> {
26 match self {
27 Self::Batch(system) => system.handle_frame(frame).await,
28 Self::DispatchBatch(system) => system.handle_frame(frame).await,
29 Self::Routed(system) => system.handle_frame(frame).await,
30 Self::FirstMatch(system) => system.handle_frame(frame).await,
31 }
32 }
33}
34
35impl<State> Handler<Frame, State> for StatefulSystem<State>
36where
37 State: Clone + Send + Sync + 'static,
38{
39 type Future = FrameFuture;
40
41 fn invoke(&self, frame: impl Into<Frame>, state: State) -> Self::Future {
42 let frame = frame.into();
43 let instance = self.clone();
44
45 match instance {
46 Self::Batch(system) => system.handle_frame_with_state(frame, state),
47 Self::DispatchBatch(system) => system.handle_frame_with_state(frame, state),
48 Self::Routed(system) => system.handle_frame_with_state(frame, state),
49 Self::FirstMatch(system) => system.handle_frame_with_state(frame, state),
50 }
51 }
52
53 fn context(&self) -> ActionContext<State> {
54 match self {
55 Self::Batch(system) => system.action_context(),
56 Self::DispatchBatch(system) => system.action_context(),
57 Self::Routed(system) => system.action_context(),
58 Self::FirstMatch(system) => system.action_context(),
59 }
60 }
61}
62
63impl<State, IntoFrame> Service<IntoFrame> for StatefulSystem<State>
64where
65 State: Clone + Send + Sync + 'static,
66 IntoFrame: Into<Frame> + Clone + Send + 'static,
67{
68 type Response = Frame;
69 type Error = crate::Error;
70 type Future = FrameFuture;
71
72 fn poll_ready(
73 &mut self,
74 _: &mut std::task::Context<'_>,
75 ) -> std::task::Poll<Result<(), Self::Error>> {
76 std::task::Poll::Ready(Ok(()))
77 }
78
79 fn call(&mut self, frame: IntoFrame) -> Self::Future {
80 let state = match self {
81 Self::Batch(system) => system.state(),
82 Self::DispatchBatch(system) => system.state(),
83 Self::Routed(system) => system.state(),
84 Self::FirstMatch(system) => system.state(),
85 };
86
87 let frame: Frame = frame.into();
88 let instance = self.clone();
89
90 instance.invoke(frame, state)
91 }
92}