use std::fmt::{self, Debug};
use std::future;
use std::pin::Pin;
use tracing::Instrument;
use super::{Message, MessageResponse};
use crate::actor::Actor;
use crate::channel::oneshot;
pub struct FutureMessageResult<M>
where
M: Message,
{
future: Pin<Box<dyn Future<Output = M::Result> + Send>>,
}
impl<M> Debug for FutureMessageResult<M>
where
M: Message,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{}", crate::utils::ShortName::of::<Self>()))
}
}
impl<M> FutureMessageResult<M>
where
M: Message,
{
pub fn new<F>(future: F) -> Self
where
F: Future<Output = M::Result> + Send + 'static,
{
Self {
future: Box::pin(future),
}
}
}
impl<A, M> MessageResponse<A, M> for FutureMessageResult<M>
where
A: Actor,
M: Message,
{
fn handle(
self,
_ctx: &mut A::Context,
tx: Option<oneshot::Sender<M::Result>>,
) -> impl Future<Output = ()> + Send {
tokio::spawn(
async move {
let result = self.future.await;
if let Some(tx) = tx {
let _ = tx.send(result);
}
}
.in_current_span(),
);
future::ready(())
}
}