intrepid_core/system/
open.rsuse tower::Service;
use crate::{ActionContext, Frame, FrameFuture, Handler};
use super::{
direct::Direct, dispatch::Dispatch, routed::Routed, Stateful, StatelessSystem, System,
};
#[derive(Clone, Copy, Default)]
pub struct Open;
pub type OpenSystem<State> = System<Open, State>;
impl<State> OpenSystem<State>
where
State: Clone + Send + Sync + 'static,
{
pub fn direct() -> Self {
Self::Direct(Direct::init())
}
pub fn dispatch() -> Self {
Self::Dispatch(Dispatch::init())
}
pub fn routed() -> Self {
Self::Routed(Routed::init())
}
pub fn with_state(&self, state: State) -> System<Stateful<State>, State> {
match self {
Self::Direct(system) => System::Direct(system.with_state(state)),
Self::Dispatch(system) => System::Dispatch(system.with_state(state)),
Self::Routed(system) => System::Routed(system.with_state(state)),
}
}
fn handle_frame_with_state(&self, frame: Frame, state: State) -> FrameFuture {
match self {
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),
}
}
}
impl OpenSystem<()> {
pub fn without_state(self) -> StatelessSystem {
match self {
Self::Direct(system) => System::Direct(system.without_state()),
Self::Dispatch(system) => System::Dispatch(system.without_state()),
Self::Routed(system) => System::Routed(system.without_state()),
}
}
pub fn handle_frame(self, frame: Frame) -> FrameFuture {
self.handle_frame_with_state(frame, ())
}
}
impl<State> Handler<Frame, State> for OpenSystem<State>
where
State: Clone + Send + Sync + 'static,
{
type Future = FrameFuture;
fn invoke(&self, frame: impl Into<Frame>, state: State) -> Self::Future {
self.handle_frame_with_state(frame.into(), 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<IntoFrame> Service<IntoFrame> for System<Open, ()>
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.handle_frame(frame)
}
}