use std::io::Write;
use rand::{rngs::OsRng, Rng};
use crate::{mime::grovel, support::un64};
#[derive(Debug, Clone, Default)]
pub struct ZstdTrainFetcher(Vec<u8>);
impl grovel::Visitor for ZstdTrainFetcher {
type Output = Vec<u8>;
fn header(
&mut self,
raw: &[u8],
name: &str,
_value: &[u8],
) -> Result<(), Self::Output> {
if name.eq_ignore_ascii_case("Content-Type")
|| name.eq_ignore_ascii_case("Content-Transfer-Encoding")
|| name.eq_ignore_ascii_case("Date")
|| name.eq_ignore_ascii_case("Precedence")
|| name.eq_ignore_ascii_case("MIME-Version")
{
self.0.extend_from_slice(raw);
} else {
let rand: [u8; 3] = OsRng.gen();
self.0.extend_from_slice(name.as_bytes());
self.0.extend_from_slice(b": ");
self.0.extend_from_slice(base64::encode(&rand).as_bytes());
self.0.extend_from_slice(b"\r\n");
}
Ok(())
}
fn start_content(&mut self) -> Result<(), Self::Output> {
Err(self.end())
}
fn end(&mut self) -> Self::Output {
let mut compressed = Vec::<u8>::with_capacity(self.0.len());
{
let mut writer = un64::Writer::new(&mut compressed);
writer
.write_all(&self.0)
.expect("writing to vec never fails");
writer.flush().expect("writing to vec never fails");
}
self.0.clear();
compressed
}
fn visit_default(&mut self) -> Result<(), Self::Output> {
Ok(())
}
}