use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use serde::{Deserialize, Serialize};
use zruntime::{Event, EventListener};
use crate::{Signature, Type};
#[derive(Debug)]
pub struct ResponseDispatchNotifier<R> {
response: R,
event: Option<Event>,
}
impl<R> ResponseDispatchNotifier<R> {
pub fn new(response: R) -> (Self, ResponseDispatchListener) {
let event = Event::new();
let listener = ResponseDispatchListener(event.listen());
(
Self {
response,
event: Some(event),
},
listener,
)
}
pub fn response(&self) -> &R {
&self.response
}
}
impl<R> Serialize for ResponseDispatchNotifier<R>
where
R: Serialize,
{
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.response.serialize(serializer)
}
}
impl<'de, R> Deserialize<'de> for ResponseDispatchNotifier<R>
where
R: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(Self {
response: R::deserialize(deserializer)?,
event: None,
})
}
}
impl<R> Type for ResponseDispatchNotifier<R>
where
R: Type,
{
const SIGNATURE: &'static Signature = R::SIGNATURE;
}
impl<T> Drop for ResponseDispatchNotifier<T> {
fn drop(&mut self) {
if let Some(event) = self.event.take() {
event.notify(usize::MAX);
}
}
}
#[derive(Debug)]
#[must_use = "listeners do nothing unless polled"]
pub struct ResponseDispatchListener(EventListener);
impl Future for ResponseDispatchListener {
type Output = ();
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.0).poll(cx)
}
}