#[cfg(feature = "no_std")]
use alloc::boxed::Box;
#[cfg(feature = "no_std")]
use alloc::vec::Vec;
use core::future::Future;
use core::pin::Pin;
use crate::Emitter;
use crate::Event as EventTrait;
pub enum Effect<Event: EventTrait> {
None,
Just(Event),
Batch(Vec<Effect<Event>>),
Async(Box<dyn FnOnceBox<Event> + Send>),
}
impl<Event: EventTrait> Effect<Event> {
pub fn just(event: Event) -> Self {
Effect::Just(event)
}
pub fn none() -> Self {
Effect::None
}
pub fn batch(effects: Vec<Effect<Event>>) -> Self {
Effect::Batch(effects)
}
pub fn from_async<F, Fut>(f: F) -> Self
where
F: FnOnce(Emitter<Event>) -> Fut + Send + 'static,
Fut: Future<Output = ()> + Send + 'static,
{
Effect::Async(Box::new(move |emitter: &Emitter<Event>| {
let future = f(emitter.clone());
Box::pin(future) as Pin<Box<dyn Future<Output = ()> + Send>>
}))
}
}
pub trait FnOnceBox<Event: EventTrait> {
fn call_box(
self: Box<Self>,
emitter: &Emitter<Event>,
) -> Pin<Box<dyn Future<Output = ()> + Send>>;
}
impl<F, Event: EventTrait> FnOnceBox<Event> for F
where
F: for<'a> FnOnce(&'a Emitter<Event>) -> Pin<Box<dyn Future<Output = ()> + Send>>,
{
fn call_box(
self: Box<Self>,
emitter: &Emitter<Event>,
) -> Pin<Box<dyn Future<Output = ()> + Send>> {
(*self)(emitter)
}
}