use std::fs; use std::fs::File; use std::io::prelude::*; use std::io::Result; use std::mem; use std::slice; pub trait DataBytes { fn data_bytes(&self) -> &[u8]; } pub trait DataBytesMut { fn data_bytes_mut(&mut self) -> &mut [u8]; } impl DataBytes for [T] { fn data_bytes(&self) -> &[u8] { let num_bytes = self.len() * mem::size_of::(); unsafe { slice::from_raw_parts(self.as_ptr() as *const u8, num_bytes) } } } impl DataBytesMut for [T] { fn data_bytes_mut(&mut self) -> &mut [u8] { let num_bytes = self.len() * mem::size_of::(); unsafe { slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, num_bytes) } } } impl DataBytesMut for Vec { fn data_bytes_mut(&mut self) -> &mut [u8] { let num_bytes = self.len() * mem::size_of::(); unsafe { slice::from_raw_parts_mut(self.as_mut_ptr() as *mut u8, num_bytes) } } } pub trait Store : DataBytes { fn write_to(&self, filename: &str) -> Result<()> { File::create(filename)?.write_all(self.data_bytes()) } } impl Store for T {} impl Store for [T] where [T]: DataBytes {} pub trait Load : DataBytesMut + Sized { fn new_with_bytes(num_bytes: usize) -> Self; fn load_from(filename: &str) -> Result { let metadata = fs::metadata(filename)?; let mut file = File::open(filename)?; let mut object = Self::new_with_bytes(metadata.len() as usize); assert_eq!(metadata.len() as usize, object.data_bytes_mut().len()); file.read_exact(object.data_bytes_mut())?; Ok(object) } } impl Load for Vec { fn new_with_bytes(num_bytes: usize) -> Self { assert_eq!(num_bytes % mem::size_of::(), 0); let num_elements = num_bytes / mem::size_of::(); (0..num_elements).map(|_| T::default()).collect() } }