boitalettres/src/server/accept/mod.rs

80 lines
1.8 KiB
Rust

use std::error::Error as StdError;
use std::pin::Pin;
use std::task;
use futures::io;
use futures::Stream;
pub mod addr;
pub trait Accept {
type Conn: io::AsyncRead + io::AsyncWrite;
type Error: StdError;
fn poll_accept(
self: Pin<&mut Self>,
cx: &mut task::Context,
) -> task::Poll<Option<Result<Self::Conn, Self::Error>>>;
}
pub fn poll_fn<F, IO, E>(f: F) -> impl Accept<Conn = IO, Error = E>
where
F: FnMut(&mut task::Context) -> task::Poll<Option<Result<IO, E>>>,
IO: io::AsyncRead + io::AsyncWrite,
E: StdError,
{
struct PollFn<F>(F);
impl<F> Unpin for PollFn<F> {}
impl<F, IO, E> Accept for PollFn<F>
where
F: FnMut(&mut task::Context) -> task::Poll<Option<Result<IO, E>>>,
IO: io::AsyncRead + io::AsyncWrite,
E: StdError,
{
type Conn = IO;
type Error = E;
fn poll_accept(
self: Pin<&mut Self>,
cx: &mut task::Context,
) -> task::Poll<Option<Result<Self::Conn, Self::Error>>> {
(self.get_mut().0)(cx)
}
}
PollFn(f)
}
pub fn from_stream<S, IO, E>(stream: S) -> impl Accept<Conn = IO, Error = E>
where
S: Stream<Item = Result<IO, E>>,
IO: io::AsyncRead + io::AsyncWrite,
E: StdError,
{
use pin_project::pin_project;
#[pin_project]
struct FromStream<S>(#[pin] S);
impl<S, IO, E> Accept for FromStream<S>
where
S: Stream<Item = Result<IO, E>>,
IO: io::AsyncRead + io::AsyncWrite,
E: StdError,
{
type Conn = IO;
type Error = E;
fn poll_accept(
self: Pin<&mut Self>,
cx: &mut task::Context,
) -> task::Poll<Option<Result<Self::Conn, Self::Error>>> {
self.project().0.poll_next(cx)
}
}
FromStream(stream)
}