use alloc::{boxed::Box, vec::Vec};
pub trait Accumulator {
fn write_byte(&mut self, value: u8);
fn write_bytes(&mut self, value: &[u8]);
}
pub(super) struct LengthMeasurement {
len: usize,
}
impl From<LengthMeasurement> for usize {
fn from(len: LengthMeasurement) -> usize {
len.len
}
}
impl LengthMeasurement {
pub fn zero() -> Self {
Self { len: 0 }
}
}
impl Accumulator for LengthMeasurement {
fn write_byte(&mut self, _value: u8) {
self.len += 1;
}
fn write_bytes(&mut self, value: &[u8]) {
self.len += value.len();
}
}
pub(super) struct Writer {
bytes: Vec<u8>,
requested_capacity: usize,
}
impl Writer {
pub(super) fn with_capacity(capacity: LengthMeasurement) -> Self {
Self {
bytes: Vec::with_capacity(capacity.len),
requested_capacity: capacity.len,
}
}
}
impl From<Writer> for Box<[u8]> {
fn from(writer: Writer) -> Self {
assert_eq!(writer.requested_capacity, writer.bytes.len());
writer.bytes.into_boxed_slice()
}
}
impl Accumulator for Writer {
fn write_byte(&mut self, value: u8) {
self.bytes.push(value);
}
fn write_bytes(&mut self, value: &[u8]) {
self.bytes.extend(value);
}
}
pub fn write_copy(accumulator: &mut dyn Accumulator, to_copy: untrusted::Input) {
accumulator.write_bytes(to_copy.as_slice_less_safe())
}