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())
}
}