use async_trait::async_trait;
use ranvier_core::bus::Bus;
use ranvier_core::outcome::Outcome;
use ranvier_core::transition::{ResourceRequirement, Transition};
use std::fmt::Debug;
use std::marker::PhantomData;
pub struct ClosureTransition<F, Res = ()> {
label: String,
f: F,
_phantom: PhantomData<Res>,
}
impl<F, Res> ClosureTransition<F, Res> {
pub fn new(label: impl Into<String>, f: F) -> Self {
Self {
label: label.into(),
f,
_phantom: PhantomData,
}
}
}
impl<F: Clone, Res> Clone for ClosureTransition<F, Res> {
fn clone(&self) -> Self {
Self {
label: self.label.clone(),
f: self.f.clone(),
_phantom: PhantomData,
}
}
}
#[async_trait]
impl<F, From, To, E, Res> Transition<From, To> for ClosureTransition<F, Res>
where
F: Fn(From, &mut Bus) -> Outcome<To, E> + Send + Sync + 'static,
From: Send + 'static,
To: Send + 'static,
E: Send + Sync + Debug + 'static,
Res: ResourceRequirement,
{
type Error = E;
type Resources = Res;
fn label(&self) -> String {
self.label.clone()
}
async fn run(
&self,
state: From,
_resources: &Self::Resources,
bus: &mut Bus,
) -> Outcome<To, Self::Error> {
(self.f)(state, bus)
}
}