use std::future::Future;
use std::io;
use std::pin::Pin;
use std::task::Context;
use std::task::Poll;
use std::time::Instant;
use hyper::rt::Executor;
use hyper::rt::Timer;
use pin_project_lite::pin_project;
use crate::private;
use crate::rt::GrpcEndpoint;
use crate::rt::GrpcRuntime;
#[derive(Clone)]
pub(crate) struct HyperCompatExec {
pub(crate) inner: GrpcRuntime,
}
impl<F> Executor<F> for HyperCompatExec
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
fn execute(&self, fut: F) {
self.inner.spawn(Box::pin(async {
let _ = fut.await;
}));
}
}
struct HyperCompatSleep {
inner: Pin<Box<dyn super::Sleep>>,
}
impl Future for HyperCompatSleep {
type Output = ();
fn poll(
mut self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
self.inner.as_mut().poll(cx)
}
}
impl hyper::rt::Sleep for HyperCompatSleep {}
pub(crate) struct HyperCompatTimer {
pub(crate) inner: GrpcRuntime,
}
impl Timer for HyperCompatTimer {
fn sleep(&self, duration: std::time::Duration) -> Pin<Box<dyn hyper::rt::Sleep>> {
let sleep = self.inner.sleep(duration);
Box::pin(HyperCompatSleep { inner: sleep })
}
fn sleep_until(&self, deadline: Instant) -> Pin<Box<dyn hyper::rt::Sleep>> {
let now = Instant::now();
let duration = deadline.saturating_duration_since(now);
self.sleep(duration)
}
}
pin_project! {
pub(crate) struct HyperStream {
#[pin]
inner: Box<dyn GrpcEndpoint>,
}
}
impl HyperStream {
pub fn new(stream: Box<dyn GrpcEndpoint>) -> Self {
Self { inner: stream }
}
}
impl hyper::rt::Read for HyperStream {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
mut buf: hyper::rt::ReadBufCursor<'_>,
) -> Poll<Result<(), io::Error>> {
let n = unsafe {
let mut tbuf = tokio::io::ReadBuf::uninit(buf.as_mut());
match self
.project()
.inner
.poll_read_private(cx, &mut tbuf, private::Internal)
{
Poll::Ready(Ok(())) => tbuf.filled().len(),
other => return other,
}
};
unsafe {
buf.advance(n);
}
Poll::Ready(Ok(()))
}
}
impl hyper::rt::Write for HyperStream {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
self.project()
.inner
.poll_write_private(cx, buf, private::Internal)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
self.project()
.inner
.poll_flush_private(cx, private::Internal)
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
self.project()
.inner
.poll_shutdown_private(cx, private::Internal)
}
fn is_write_vectored(&self) -> bool {
self.inner.is_write_vectored_private(private::Internal)
}
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[io::IoSlice<'_>],
) -> Poll<Result<usize, io::Error>> {
self.project()
.inner
.poll_write_vectored_private(cx, bufs, private::Internal)
}
}