use std::{
fmt,
future::Future,
io,
pin::Pin,
task::{Context, Poll},
};
pub(crate) trait UdpPoller: Send + Sync + std::fmt::Debug + 'static {
fn poll_writable(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>>;
}
pin_project_lite::pin_project! {
pub(crate) struct UdpPollHelper<MakeFut, Fut>
{
make_fut: MakeFut,
#[pin]
fut: Option<Fut>,
}
}
impl<MakeFut, Fut> UdpPollHelper<MakeFut, Fut> {
pub(crate) fn new(make_fut: MakeFut) -> Self {
Self {
make_fut,
fut: None,
}
}
}
impl<MakeFut, Fut> UdpPoller for UdpPollHelper<MakeFut, Fut>
where
MakeFut: Fn() -> Fut + Send + Sync + 'static,
Fut: Future<Output = io::Result<()>> + Send + Sync + 'static,
{
fn poll_writable(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
let mut this = self.project();
if this.fut.is_none() {
this.fut.set(Some((this.make_fut)()));
}
let result = this.fut.as_mut().as_pin_mut().unwrap().poll(cx);
if result.is_ready() {
this.fut.set(None);
}
result
}
}
impl<MakeFut, Fut> fmt::Debug for UdpPollHelper<MakeFut, Fut> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("UdpPollHelper").finish_non_exhaustive()
}
}