use std::any::Any;
use std::fmt::Debug;
use std::future::Future;
use std::sync::Arc;
use async_trait::async_trait;
use futures::future::BoxFuture;
use crate::actor::context::context_handle::ContextHandle;
use crate::actor::message::message::Message;
use crate::actor::message::response::ResponseHandle;
#[derive(Clone)]
pub struct AutoRespond(Arc<dyn Fn(ContextHandle) -> BoxFuture<'static, ResponseHandle> + Send + Sync + 'static>);
impl AutoRespond {
pub fn new<F, Fut>(f: F) -> Self
where
F: Fn(ContextHandle) -> Fut + Send + Sync + 'static,
Fut: Future<Output = ResponseHandle> + Send + 'static, {
Self(Arc::new(move |mh| Box::pin(f(mh))))
}
}
impl Debug for AutoRespond {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "AutoRespond")
}
}
impl Message for AutoRespond {
fn eq_message(&self, other: &dyn Message) -> bool {
other.eq_message(self)
}
fn as_any(&self) -> &(dyn Any + Send + Sync + 'static) {
self
}
}
#[async_trait]
pub trait AutoResponsive: Debug + Send + Sync + 'static {
async fn get_auto_response(&self, context: ContextHandle) -> ResponseHandle;
}
#[async_trait]
impl AutoResponsive for AutoRespond {
async fn get_auto_response(&self, ctx: ContextHandle) -> ResponseHandle {
(self.0)(ctx).await
}
}
#[derive(Debug, Clone)]
pub struct AutoRespondHandle(Arc<dyn AutoResponsive>);
impl AutoRespondHandle {
pub fn new(auto_respond: Arc<dyn AutoResponsive>) -> Self {
Self(auto_respond)
}
}
#[async_trait]
impl AutoResponsive for AutoRespondHandle {
async fn get_auto_response(&self, context: ContextHandle) -> ResponseHandle {
self.0.get_auto_response(context).await
}
}
impl PartialEq for AutoRespondHandle {
fn eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}
impl Eq for AutoRespondHandle {}
impl std::hash::Hash for AutoRespondHandle {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
Arc::as_ptr(&self.0).hash(state)
}
}