use std::pin::Pin;
use std::task::{Context, Poll};
use pin_project::pin_project;
use tower::BoxError;
pub(super) mod drivers;
#[cfg(feature = "tls")]
pub mod tls;
pub trait Protocol<S, IO, Req> {
type Response: Send + 'static;
type Error: Into<BoxError>;
type Connection: Connection + Future<Output = Result<(), Self::Error>> + 'static;
fn serve_connection(&self, stream: IO, service: S) -> Self::Connection;
}
pub trait Connection {
fn graceful_shutdown(self: Pin<&mut Self>);
}
pub trait Accept {
type Connection: Unpin + 'static;
type Error: Into<BoxError>;
fn poll_accept(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Self::Connection, Self::Error>>;
}
pub trait AcceptExt: Accept {
fn accept(self) -> AcceptOne<Self>
where
Self: Sized,
{
AcceptOne::new(self)
}
}
impl<A> AcceptExt for A where A: Accept {}
#[derive(Debug)]
#[pin_project]
pub struct AcceptOne<A> {
#[pin]
inner: A,
}
impl<A> AcceptOne<A> {
fn new(inner: A) -> Self {
AcceptOne { inner }
}
}
impl<A> Future for AcceptOne<A>
where
A: Accept,
{
type Output = Result<A::Connection, A::Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
self.project().inner.poll_accept(cx)
}
}