zeptohttpc 0.1.2

minimal HTTP client using http and httparse crates
Documentation
use std::io::{BufRead, Error as IoError, ErrorKind::UnexpectedEof};

use httparse::Status::{self, Complete, Partial};

pub fn parse<R, P, T, E>(mut reader: R, parser: P) -> Result<T, E>
where
    R: BufRead,
    P: Fn(&[u8]) -> Result<Status<(usize, T)>, E>,
    E: From<IoError>,
{
    let buf = reader.fill_buf()?;
    if let Complete((parsed, val)) = parser(buf)? {
        reader.consume(parsed);
        return Ok(val);
    }

    parse_buffered(reader, parser)
}

#[cold]
fn parse_buffered<R, P, T, E>(mut reader: R, parser: P) -> Result<T, E>
where
    R: BufRead,
    P: Fn(&[u8]) -> Result<Status<(usize, T)>, E>,
    E: From<IoError>,
{
    let mut buf1 = Vec::new();
    loop {
        let buf = reader.fill_buf()?;
        if buf.is_empty() {
            return Err(IoError::from(UnexpectedEof).into());
        }
        buf1.extend_from_slice(buf);

        match parser(&buf1)? {
            Complete((parsed, val)) => {
                let amt = parsed - (buf1.len() - buf.len());
                reader.consume(amt);

                return Ok(val);
            }
            Partial => {
                let amt = buf.len();
                reader.consume(amt);
            }
        }
    }
}