intrepid_core/system/
stateful.rsuse tower::Service;
use crate::{ActionContext, Frame, FrameFuture, Handler};
use super::System;
#[derive(Clone, Copy, Default)]
pub struct Stateful<State>(pub State);
pub type StatefulSystem<State> = System<Stateful<State>, State>;
impl<State> StatefulSystem<State>
where
State: Clone + Send + Sync + 'static,
{
pub async fn handle_frame(self, frame: crate::Frame) -> crate::Result<Frame> {
match self {
Self::Direct(system) => system.handle_frame(frame).await,
Self::Dispatch(system) => system.handle_frame(frame).await,
Self::Routed(system) => system.handle_frame(frame).await,
}
}
}
impl<State> Handler<Frame, State> for StatefulSystem<State>
where
State: Clone + Send + Sync + 'static,
{
type Future = FrameFuture;
fn invoke(&self, frame: impl Into<Frame>, state: State) -> Self::Future {
let frame = frame.into();
let instance = self.clone();
match instance {
Self::Direct(system) => system.handle_frame_with_state(frame, state),
Self::Dispatch(system) => system.handle_frame_with_state(frame, state),
Self::Routed(system) => system.handle_frame_with_state(frame, state),
}
}
fn context(&self) -> ActionContext<State> {
match self {
Self::Direct(system) => system.action_context(),
Self::Dispatch(system) => system.action_context(),
Self::Routed(system) => system.action_context(),
}
}
}
impl<State, IntoFrame> Service<IntoFrame> for StatefulSystem<State>
where
State: Clone + Send + Sync + 'static,
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 state = match self {
Self::Direct(system) => system.state(),
Self::Dispatch(system) => system.state(),
Self::Routed(system) => system.state(),
};
let frame: Frame = frame.into();
let instance = self.clone();
instance.invoke(frame, state)
}
}