use std::ops::Deref;
use anylock::AnyLock;
use tracing::error;
use crate::{
handler::MessageHandler as _,
message::Message,
traits::{internal::SalishMessageInternal as _, Payload},
};
use super::{Endpoint, EndpointId, EndpointInner};
pub type EndpointCallback<'a, Ret> =
Box<dyn for<'b> Fn(&'b crate::message::Message) -> Option<Ret> + Send + Sync + 'a>;
pub struct EndpointHandle<'a, Ret>
where
Self: Send + Sync,
{
pub endpoint_id: EndpointId,
pub callback: EndpointCallback<'a, Ret>,
}
impl<'a, Ret> std::fmt::Debug for EndpointHandle<'a, Ret>
where
Self: Send + Sync,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EndpointHandle")
.field("endpoint_id", &self.endpoint_id)
.finish()
}
}
impl<'a, Ret> EndpointHandle<'a, Ret>
where
Self: Send + Sync,
{
pub fn new<M: Payload, Lock, Ref>(endpoint: &Endpoint<'a, M, Ret, Lock, Ref>) -> Self
where
Ref: Deref<Target: AnyLock<EndpointInner<'a, M, Ret>>>
+ From<Lock>
+ Clone
+ Send
+ Sync
+ 'a,
Lock: AnyLock<EndpointInner<'a, M, Ret>> + 'a,
{
let inner = endpoint.inner.clone();
let dispatch = move |msg: &Message| {
if let Some(payload) = msg.inner::<M>() {
Some(inner.write().on_message(payload))
} else {
error!("Failed to downcast message");
None
}
};
EndpointHandle {
endpoint_id: endpoint.id,
callback: Box::new(dispatch),
}
}
}