use std::any::Any;
use std::fmt::Debug;
use std::future::Future;
use std::sync::Arc;
use futures::future::BoxFuture;
use crate::actor::message::message::Message;
use crate::actor::message::message_handle::MessageHandle;
#[derive(Clone)]
pub(crate) struct Continuation {
pub(crate) message_handle: MessageHandle,
pub(crate) f: ContinuationCallback,
}
impl Continuation {
pub(crate) fn new<F, Fut>(message_handle: MessageHandle, f: F) -> Self
where
F: Fn() -> Fut + Send + Sync + 'static,
Fut: Future<Output = ()> + Send + 'static, {
Continuation {
message_handle,
f: ContinuationCallback::new(move || Box::pin(f()) as BoxFuture<'static, ()>),
}
}
}
static_assertions::assert_impl_all!(Continuation: Send, Sync);
impl Debug for Continuation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Continuation")
.field("message", &self.message_handle)
.finish()
}
}
impl Message for Continuation {
fn eq_message(&self, other: &dyn Message) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() {
self.message_handle == other.message_handle
} else {
false
}
}
fn as_any(&self) -> &(dyn Any + Send + Sync + 'static) {
self
}
}
#[derive(Clone)]
pub struct ContinuationCallback(Arc<dyn Fn() -> BoxFuture<'static, ()> + Send + Sync>);
impl ContinuationCallback {
pub fn new<F, Fut>(f: F) -> Self
where
F: Fn() -> Fut + Send + Sync + 'static,
Fut: Future<Output = ()> + Send + 'static, {
Self(Arc::new(move || Box::pin(f()) as BoxFuture<'static, ()>))
}
pub async fn run(&self) {
tracing::debug!("ContinuationCallback::run: start");
(self.0)().await;
tracing::debug!("ContinuationCallback::run: end");
}
}
impl Debug for ContinuationCallback {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "ContinuationHandler")
}
}