httpio 0.2.4

A transport-agnostic, async HTTP/1.1 client library for any runtime.
Documentation
use crate::enums::char_set::CharSet;
use crate::enums::http_error::HttpError;
use crate::structures::header::header_list::HttpHeaderList;
use crate::utils::parse_util;
use async_regex::CRLF;
use futures::AsyncBufRead;
use std::io::{self, Write};

#[derive(Clone)]
pub struct HttpBodyPart {
    pub headers: HttpHeaderList,
    pub content: Vec<u8>,
}

impl HttpBodyPart {
    pub fn write_to<W: Write>(&self, mut writer: W) -> io::Result<()> {
        let headers = self.headers.to_string();
        let headers_bytes = headers.as_bytes();
        writer.write_all(headers_bytes)?;
        if !headers_bytes.is_empty() {
            writer.write_all(CRLF)?;
        }
        writer.write_all(CRLF)?;
        writer.write_all(&self.content)?;
        Ok(())
    }

    pub fn as_bytes(&self) -> Vec<u8> {
        let mut result = Vec::with_capacity(self.content.len() + 64);
        self.write_to(&mut result).expect("Vec write cannot fail");
        result
    }

    pub async fn read(mut reader: impl AsyncBufRead + Unpin) -> Result<HttpBodyPart, HttpError> {
        let headers = HttpHeaderList::read(&mut reader).await?;
        let content = parse_util::read_content_with_length(reader, None).await?;

        Ok(HttpBodyPart { headers, content })
    }

    pub fn to_string(&self, charset: CharSet) -> Result<String, HttpError> {
        let charset = self.headers.get_charset(charset);
        let bytes = self.as_bytes();
        let str = parse_util::bytes_to_string(&bytes, charset)?;
        Ok(str.to_string())
    }
}