#![feature(trait_alias)]
mod web;
mod addr;
use tokio::{
io::{AsyncRead, AsyncWrite, ReadBuf, Result as IoResult},
};
pub use crate::addr::Addr;
pub use crate::web::addr::{LocalAddr, RemoteAddr};
use futures_util::{future::BoxFuture, Future, FutureExt, TryFutureExt};
use http::uri::Scheme;
use std::{
convert::Infallible,
io::Error,
pin::Pin,
task::{Context, Poll},
};
pub trait Conn = AsyncRead + AsyncWrite + Send + Unpin + 'static;
pub trait Acceptor: Send {
type Io: Conn;
fn local_addr(&self) -> Vec<LocalAddr>;
fn accept(
&mut self,
) -> impl Future<Output = IoResult<(Self::Io, LocalAddr, RemoteAddr, Scheme)>> + Send;
}
pub struct BoxIo {
reader: Box<dyn AsyncRead + Send + Unpin + 'static>,
writer: Box<dyn AsyncWrite + Send + Unpin + 'static>,
}
impl BoxIo {
pub fn new(io: impl Conn) -> Self {
let (reader, writer) = tokio::io::split(io);
Self {
reader: Box::new(reader),
writer: Box::new(writer),
}
}
}
impl AsyncRead for BoxIo {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<IoResult<()>> {
let this = &mut *self;
Pin::new(&mut this.reader).poll_read(cx, buf)
}
}
impl AsyncWrite for BoxIo {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, Error>> {
let this = &mut *self;
Pin::new(&mut this.writer).poll_write(cx, buf)
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
let this = &mut *self;
Pin::new(&mut this.writer).poll_flush(cx)
}
fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
let this = &mut *self;
Pin::new(&mut this.writer).poll_shutdown(cx)
}
}
impl Acceptor for Infallible {
type Io = BoxIo;
fn local_addr(&self) -> Vec<LocalAddr> {
vec![]
}
async fn accept(&mut self) -> IoResult<(Self::Io, LocalAddr, RemoteAddr, Scheme)> {
unreachable!()
}
}
impl<T: Acceptor + ?Sized> Acceptor for Box<T> {
type Io = T::Io;
fn local_addr(&self) -> Vec<LocalAddr> {
self.as_ref().local_addr()
}
async fn accept(&mut self) -> IoResult<(Self::Io, LocalAddr, RemoteAddr, Scheme)> {
self.as_mut().accept().await
}
}
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}