use std::future::Future;
use std::pin::Pin;
use std::task::Poll;
pub trait Connection<Req> {
type Response: 'static;
type Error: std::error::Error + Send + Sync + 'static;
type Future: Future<Output = Result<Self::Response, Self::Error>> + Send + 'static;
fn send_request(&mut self, request: Req) -> Self::Future;
fn poll_ready(
&mut self,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Result<(), Self::Error>>;
}
pub trait ConnectionExt<R>: Connection<R> {
fn when_ready(&mut self) -> WhenReady<'_, Self, R> {
WhenReady::new(self)
}
}
impl<T, R> ConnectionExt<R> for T where T: Connection<R> {}
#[derive(Debug)]
pub struct WhenReady<'a, C, R>
where
C: Connection<R> + ?Sized,
{
conn: &'a mut C,
_private: std::marker::PhantomData<fn(R)>,
}
impl<'a, C, R> WhenReady<'a, C, R>
where
C: Connection<R> + ?Sized,
{
pub(crate) fn new(conn: &'a mut C) -> Self {
Self {
conn,
_private: std::marker::PhantomData,
}
}
}
impl<C, R> Future for WhenReady<'_, C, R>
where
C: Connection<R> + ?Sized,
{
type Output = Result<(), C::Error>;
fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
self.conn.poll_ready(cx)
}
}