use crate::{Actor, Cx};
use static_assertions::assert_eq_size;
pub struct Ret<M: 'static>(Option<Box<dyn FnOnce(Option<M>)>>);
assert_eq_size!(Ret<()>, [usize; 2]);
impl<M> Ret<M> {
pub fn ret(mut self, msg: M) {
if let Some(f) = self.0.take() {
f(Some(msg));
}
}
#[inline]
pub fn new(f: impl FnOnce(Option<M>) + 'static) -> Self {
Self(Some(Box::new(f)))
}
#[allow(clippy::wrong_self_convention)]
#[inline]
pub fn to_actor<A: 'static>(
actor: Actor<A>,
f: impl FnOnce(&mut A, &mut Cx<'_, A>, Option<M>) + 'static,
) -> Self {
Self::new(move |m| {
let actor2 = actor.clone();
actor.defer(move |s| actor2.apply(s, move |a, cx| f(a, cx, m)));
})
}
#[allow(clippy::wrong_self_convention)]
#[inline]
pub fn to_actor_prep<A: 'static>(
actor: Actor<A>,
f: impl FnOnce(&mut Cx<'_, A>, Option<M>) -> Option<A> + 'static,
) -> Self {
Self::new(move |m| {
let actor2 = actor.clone();
actor.defer(move |s| actor2.apply_prep(s, move |cx| f(cx, m)));
})
}
#[inline]
pub fn some_to_actor<A: 'static>(
actor: Actor<A>,
f: impl FnOnce(&mut A, &mut Cx<'_, A>, M) + 'static,
) -> Self {
Self::new(move |m| {
if let Some(m) = m {
let actor2 = actor.clone();
actor.defer(move |s| actor2.apply(s, move |a, cx| f(a, cx, m)));
}
})
}
#[inline]
pub fn some_to_actor_prep<A: 'static>(
actor: Actor<A>,
f: impl FnOnce(&mut Cx<'_, A>, M) -> Option<A> + 'static,
) -> Self {
Self::new(move |m| {
if let Some(m) = m {
let actor2 = actor.clone();
actor.defer(move |s| actor2.apply_prep(s, move |cx| f(cx, m)));
}
})
}
#[inline]
pub fn panic(msg: impl Into<String>) -> Self {
let msg: String = msg.into();
Self::new(move |m| {
if m.is_some() {
panic!("{}", msg);
}
})
}
}
impl<M> Drop for Ret<M> {
fn drop(&mut self) {
if let Some(f) = self.0.take() {
f(None);
}
}
}