miasht 0.0.5

Minimum asynchronous HTTP server/client library
Documentation
use std::io::{self, Write};
use futures::{Async, Future, Poll};

use {Error, Status, TransportStream};
use status::RawStatus;
use header::{Header, HeadersMut};
use super::Connection;

pub fn builder<T>(mut connection: Connection<T>, status: RawStatus) -> ResponseBuilder<T>
where
    T: TransportStream,
{
    connection.inner.buffer.enter_write_phase();
    let _ = write!(
        connection.inner.buffer,
        "{} {}\r\n",
        connection.version, status
    );
    ResponseBuilder(connection)
}

#[derive(Debug)]
pub struct ResponseBuilder<T>(Connection<T>);
impl<T: TransportStream> ResponseBuilder<T> {
    pub fn headers_mut(&mut self) -> HeadersMut {
        HeadersMut::new(&mut self.0.inner.buffer)
    }
    pub fn add_raw_header(&mut self, name: &str, value: &[u8]) -> &mut Self {
        self.headers_mut().add_raw_header(name, value);
        self
    }
    pub fn add_header<'a, H: Header<'a>>(&mut self, header: &H) -> &mut Self {
        self.headers_mut().add_header(header);
        self
    }
    pub fn finish(mut self) -> Response<T> {
        let _ = write!(self.0.inner.buffer, "\r\n");
        Response(Some(self.0))
    }
}

#[derive(Debug)]
pub struct Response<T>(Option<Connection<T>>);
impl<T: TransportStream> Write for Response<T> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        if let Some(ref mut c) = self.0 {
            c.inner.flush_buffer()?;
            c.inner.stream.write(buf)
        } else {
            Err(io::Error::new(
                io::ErrorKind::WriteZero,
                "Cannot write into finished response",
            ))
        }
    }
    fn flush(&mut self) -> io::Result<()> {
        if let Some(ref mut c) = self.0 {
            c.inner.flush_buffer()?;
            c.inner.stream.flush()?;
        }
        Ok(())
    }
}
impl<T: TransportStream> Future for Response<T> {
    type Item = Connection<T>;
    type Error = Error;
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match self.flush() {
            Err(e) => {
                track_assert_eq!(
                    e.kind(),
                    io::ErrorKind::WouldBlock,
                    Status::InternalServerError
                );
                Ok(Async::NotReady)
            }
            Ok(()) => {
                let connection = self.0.take().expect("Cannot poll Response twice");
                Ok(Async::Ready(connection))
            }
        }
    }
}