use std::{
ops::{Deref, DerefMut},
pin::Pin,
task::{Context, Poll},
};
use hyper::rt::{Executor, Sleep, Timer};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
#[derive(Debug, Default, Clone, Copy)]
pub struct VibeioExecutor;
impl<Fut> Executor<Fut> for VibeioExecutor
where
Fut: std::future::Future + 'static,
Fut::Output: 'static,
{
#[inline]
fn execute(&self, fut: Fut) {
vibeio::spawn(fut);
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct VibeioTimer;
impl Timer for VibeioTimer {
#[inline]
fn sleep(&self, duration: std::time::Duration) -> Pin<Box<dyn Sleep>> {
Box::pin(VibeioSleep {
inner: Box::pin(vibeio::time::sleep(duration)),
})
}
#[inline]
fn sleep_until(&self, deadline: std::time::Instant) -> Pin<Box<dyn Sleep>> {
Box::pin(VibeioSleep {
inner: Box::pin(vibeio::time::sleep_until(deadline)),
})
}
#[inline]
fn reset(&self, sleep: &mut Pin<Box<dyn Sleep>>, new_deadline: std::time::Instant) {
if let Some(mut sleep) = sleep.as_mut().downcast_mut_pin::<VibeioSleep>() {
sleep.reset(new_deadline);
}
}
}
struct VibeioSleep {
inner: Pin<Box<vibeio::time::Sleep>>,
}
impl std::future::Future for VibeioSleep {
type Output = ();
#[inline]
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.inner.as_mut().poll(cx)
}
}
impl Sleep for VibeioSleep {}
unsafe impl Send for VibeioSleep {}
unsafe impl Sync for VibeioSleep {}
impl VibeioSleep {
#[inline]
fn reset(&mut self, new_deadline: std::time::Instant) {
self.inner.reset(new_deadline);
}
}
#[derive(Debug)]
pub struct VibeioIo<T> {
inner: Pin<Box<T>>,
}
impl<T> VibeioIo<T> {
#[inline]
pub fn new(inner: T) -> Self {
Self {
inner: Box::pin(inner),
}
}
}
impl<T> Deref for VibeioIo<T> {
type Target = Pin<Box<T>>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> DerefMut for VibeioIo<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<T> hyper::rt::Read for VibeioIo<T>
where
T: AsyncRead,
{
#[inline]
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
mut buf: hyper::rt::ReadBufCursor<'_>,
) -> Poll<Result<(), std::io::Error>> {
let n = {
let mut tbuf = unsafe { ReadBuf::uninit(buf.as_mut()) };
match self.inner.as_mut().poll_read(cx, &mut tbuf) {
Poll::Ready(Ok(_)) => tbuf.filled().len(),
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Pending => return Poll::Pending,
}
};
unsafe { buf.advance(n) };
Poll::Ready(Ok(()))
}
}
impl<T> hyper::rt::Write for VibeioIo<T>
where
T: AsyncWrite,
{
#[inline]
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, std::io::Error>> {
self.inner.as_mut().poll_write(cx, buf)
}
#[inline]
fn poll_flush(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), std::io::Error>> {
self.inner.as_mut().poll_flush(cx)
}
#[inline]
fn poll_shutdown(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), std::io::Error>> {
self.inner.as_mut().poll_shutdown(cx)
}
#[inline]
fn is_write_vectored(&self) -> bool {
self.inner.is_write_vectored()
}
#[inline]
fn poll_write_vectored(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[std::io::IoSlice<'_>],
) -> Poll<Result<usize, std::io::Error>> {
self.inner.as_mut().poll_write_vectored(cx, bufs)
}
}
impl<T> AsyncRead for VibeioIo<T>
where
T: hyper::rt::Read,
{
#[inline]
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
tbuf: &mut ReadBuf<'_>,
) -> Poll<std::io::Result<()>> {
let filled = tbuf.filled().len();
let sub_filled = {
let mut buf = unsafe { hyper::rt::ReadBuf::uninit(tbuf.unfilled_mut()) };
match self.inner.as_mut().poll_read(cx, buf.unfilled()) {
Poll::Ready(Ok(_)) => buf.filled().len(),
Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
Poll::Pending => return Poll::Pending,
}
};
unsafe {
tbuf.assume_init(sub_filled);
tbuf.set_filled(filled + sub_filled);
};
Poll::Ready(Ok(()))
}
}
impl<T> AsyncWrite for VibeioIo<T>
where
T: hyper::rt::Write,
{
#[inline]
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, std::io::Error>> {
self.inner.as_mut().poll_write(cx, buf)
}
#[inline]
fn poll_flush(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), std::io::Error>> {
self.inner.as_mut().poll_flush(cx)
}
#[inline]
fn poll_shutdown(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<(), std::io::Error>> {
self.inner.as_mut().poll_shutdown(cx)
}
#[inline]
fn is_write_vectored(&self) -> bool {
self.inner.is_write_vectored()
}
#[inline]
fn poll_write_vectored(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[std::io::IoSlice<'_>],
) -> Poll<Result<usize, std::io::Error>> {
self.inner.as_mut().poll_write_vectored(cx, bufs)
}
}