use std::convert::TryInto; pub trait ReadExt { fn read_exact(&mut self, n: usize) -> Option<&[u8]>; fn read_le_i32(&mut self) -> Option { self.read_exact(4).map(|bytes| i32::from_le_bytes(bytes.try_into().unwrap())) } fn read_le_u32(&mut self) -> Option { self.read_exact(4).map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap())) } fn read_le_u64(&mut self) -> Option { self.read_exact(8).map(|bytes| u64::from_le_bytes(bytes.try_into().unwrap())) } fn read_pascal_blob(&mut self) -> Option<&[u8]> { let len = self.read_le_u64()?; self.read_exact(len as usize) } fn read_pascal_string(&mut self) -> Option> { self.read_pascal_blob().map(|b| String::from_utf8(b.to_vec())) } } impl ReadExt for &[u8] { fn read_exact(&mut self, n: usize) -> Option<&[u8]> { if self.len() >= n { let (res, newlist) = self.split_at(n); *self = newlist; Some(res) } else { None } } }