use std::io::{Read, Write, IoSlice, IoSliceMut};
use std::ops::{Shl};
#[derive(Debug, Eq, PartialEq)]
pub struct Chunk(pub [u8; 4], pub Box<[u8]>);
pub struct Decoder(Box<dyn Read>);
impl Decoder
{ pub fn new(r: Box<dyn Read>) -> Self { Self(r) } }
pub struct Encoder(Box<dyn Write>);
impl Encoder
{ pub fn new(w: Box<dyn Write>) -> Self { Self(w) } }
impl Iterator for Decoder {
type Item = Chunk;
fn next(&mut self) -> Option<Self::Item> {
let mut id = [0u8; 4];
let mut size = [0u8; 4];
if let Err(_) = self.0.read_vectored(&mut [
IoSliceMut::new(&mut id),
IoSliceMut::new(&mut size)
]) { return None };
let size = u32::from_le_bytes(size) as usize;
let mut data = vec![0u8; size];
match self.0.read(&mut data) {
Ok(s) => if size != s || s == 0
{ return None },
Err(_) => { return None }
};
Some(Chunk(id, data.into_boxed_slice()))
}
}
impl Shl<Chunk> for Encoder {
type Output = Option<Self>;
fn shl(self, chunk: Chunk) -> Option<Self> {
let mut sel = self;
match sel.0.write_vectored(&[
IoSlice::new(&chunk.0),
IoSlice::new(&(chunk.1.len() as u32)
.to_le_bytes()[..]),
IoSlice::new(&chunk.1)
]) { Ok(_) => Some(Self(sel.0)),
Err(_) => None }
}
}