use bytesbuf::mem::{HasMemory, Memory, MemoryShared};
use bytesbuf::{BytesBuf, BytesView};
const PAYLOAD_LEN: usize = 12345;
fn main() {
let connection = Connection::accept();
let mut zero_counter = ConnectionZeroCounter::new(connection);
let payload = create_payload(&zero_counter.memory());
zero_counter.write(payload);
println!("Sent {PAYLOAD_LEN} bytes, of which {} were 0x00 bytes.", zero_counter.zero_count());
}
fn create_payload(memory: &impl Memory) -> BytesView {
let mut buf = memory.reserve(PAYLOAD_LEN);
for i in 0..PAYLOAD_LEN {
#[expect(clippy::cast_possible_truncation, reason = "intentional")]
buf.put_byte(i as u8);
}
buf.consume_all()
}
#[derive(Debug)]
struct ConnectionZeroCounter {
connection: Connection,
zero_count: u64,
}
impl ConnectionZeroCounter {
pub const fn new(connection: Connection) -> Self {
Self { connection, zero_count: 0 }
}
pub fn write(&mut self, message: BytesView) {
self.count_zeros(message.clone());
self.connection.write(message);
}
fn count_zeros(&mut self, mut message: BytesView) {
while !message.is_empty() {
if message.get_byte() == 0 {
self.zero_count = self.zero_count.wrapping_add(1);
}
}
}
pub const fn zero_count(&self) -> u64 {
self.zero_count
}
}
impl HasMemory for ConnectionZeroCounter {
fn memory(&self) -> impl MemoryShared {
self.connection.memory()
}
}
impl Memory for ConnectionZeroCounter {
fn reserve(&self, min_bytes: usize) -> BytesBuf {
self.connection.reserve(min_bytes)
}
}
#[derive(Debug)]
struct Connection;
impl Connection {
const fn accept() -> Self {
Self {}
}
#[expect(clippy::needless_pass_by_ref_mut, clippy::unused_self, reason = "for example realism")]
fn write(&mut self, mut _message: BytesView) {}
}
impl HasMemory for Connection {
fn memory(&self) -> impl MemoryShared {
bytesbuf::mem::testing::TransparentMemory::new()
}
}
impl Memory for Connection {
fn reserve(&self, min_bytes: usize) -> BytesBuf {
bytesbuf::mem::testing::TransparentMemory::new().reserve(min_bytes)
}
}