oneone-plz 0.0.5

HTTP/1 parser for the ParsePlz ecosystem
use body_plz::{reader::chunked_reader::ChunkReaderError, variants::Body};
use bytes::BytesMut;
use decompression_plz::{
    DecompressTrait, content_length::update_content_length,
};
use header_plz::{
    InfoLine, body_headers::parse::ParseBodyHeaders, error::HeaderReadError,
    message_head::MessageHead,
};
use protocol_traits_plz::Frame;
use thiserror::Error;

use crate::oneone::OneOne;

#[derive(Debug, Error)]
pub enum HttpStateError<T>
where
    T: InfoLine,
{
    #[error("header read| {0}")]
    InfoLine(#[from] HeaderReadError),
    #[error("chunkreader| {0}")]
    ChunkState(#[from] ChunkReaderError),
    // Partial
    #[error("partial| header")]
    Unparsed(BytesMut),
    #[error("partial| content length")]
    ContentLengthPartial(OneOne<T>, BytesMut),
    #[error("header not enough data")]
    ChunkReaderPartial(OneOne<T>, BytesMut),
}

impl<T> From<HttpStateError<T>> for BytesMut
where
    T: InfoLine,
    MessageHead<T>: ParseBodyHeaders,
{
    fn from(value: HttpStateError<T>) -> Self {
        match value {
            HttpStateError::Unparsed(buf) => buf,
            HttpStateError::ContentLengthPartial(oneone, buf)
            | HttpStateError::ChunkReaderPartial(oneone, buf) => {
                let mut data = oneone.into_bytes();
                data.unsplit(buf);
                data
            }
            _ => BytesMut::new(),
        }
    }
}

impl<T> TryFrom<HttpStateError<T>> for OneOne<T>
where
    T: InfoLine,
    MessageHead<T>: ParseBodyHeaders,
{
    type Error = HttpStateError<T>;

    fn try_from(value: HttpStateError<T>) -> Result<Self, Self::Error> {
        match value {
            HttpStateError::ContentLengthPartial(mut oneone, buf) => {
                let len = buf.len();
                oneone.set_body(Body::Raw(buf));
                update_content_length(&mut oneone, len);
                Ok(oneone)
            }
            _ => Err(value),
        }
    }
}

#[derive(Debug, Error)]
pub enum MessageFramingError {
    #[error("incorrect state| {0}")]
    IncorrectState(String),
}