#![warn(missing_debug_implementations, rust_2018_idioms)]
#![allow(clippy::mutex_atomic, clippy::module_inception)]
#![doc(test(attr(deny(rust_2018_idioms, warnings))))]
#![doc(test(attr(allow(unused_extern_crates, unused_variables))))]
use async_std::io::{self, prelude::*};
use async_std::task::{Context, Poll};
use futures::future::TryFuture;
use std::fmt;
use std::pin::Pin;
pin_project_lite::pin_project! {
pub struct Body {
#[pin]
reader: Pin<Box<dyn BufRead + Send + 'static>>,
}
}
impl Body {
pub fn empty() -> Self {
Self {
reader: Box::pin(io::empty()),
}
}
pub fn from_reader(reader: impl BufRead + Unpin + Send + 'static) -> Self {
Self {
reader: Box::pin(reader),
}
}
}
impl Read for Body {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
Pin::new(&mut self.reader).poll_read(cx, buf)
}
}
impl BufRead for Body {
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<&'_ [u8]>> {
let this = self.project();
this.reader.poll_fill_buf(cx)
}
fn consume(mut self: Pin<&mut Self>, amt: usize) {
Pin::new(&mut self.reader).consume(amt)
}
}
impl fmt::Debug for Body {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Body").field("reader", &"<hidden>").finish()
}
}
impl From<Vec<u8>> for Body {
fn from(vec: Vec<u8>) -> Body {
Self {
reader: Box::pin(io::Cursor::new(vec)),
}
}
}
impl<R: BufRead + Unpin + Send + 'static> From<Pin<Box<R>>> for Body {
fn from(reader: Pin<Box<R>>) -> Self {
Self { reader }
}
}
pub type Request = http::Request<Body>;
pub type Response = http::Response<Body>;
pub trait HttpService: Send + Sync + 'static {
type Connection: Send + 'static;
type ConnectionFuture: Send + 'static + TryFuture<Ok = Self::Connection>;
fn connect(&self) -> Self::ConnectionFuture;
type ResponseFuture: Send + 'static + TryFuture<Ok = Response>;
fn respond(&self, conn: &mut Self::Connection, req: Request) -> Self::ResponseFuture;
}