use crate::error::Error; use std::io::{Read, Write}; pub fn read_u8(reader: &mut R) -> Result { let mut bytes = [0u8; 1]; reader.read_exact(&mut bytes)?; Ok(u8::from_le_bytes(bytes)) } pub fn write_u8(v: u8, writer: &mut W) -> Result<(), Error> { writer.write_all(&v.to_le_bytes())?; Ok(()) } pub fn read_u16(reader: &mut R) -> Result { let mut bytes = [0u8; 2]; reader.read_exact(&mut bytes)?; Ok(u16::from_le_bytes(bytes)) } pub fn write_u16(v: u16, writer: &mut W) -> Result<(), Error> { writer.write_all(&v.to_le_bytes())?; Ok(()) } pub fn read_i32(reader: &mut R) -> Result { let mut bytes = [0u8; 4]; reader.read_exact(&mut bytes)?; Ok(i32::from_le_bytes(bytes)) } pub fn write_i32(v: i32, writer: &mut W) -> Result<(), Error> { writer.write_all(&v.to_le_bytes())?; Ok(()) } pub fn read_u32(reader: &mut R) -> Result { let mut bytes = [0u8; 4]; reader.read_exact(&mut bytes)?; Ok(u32::from_le_bytes(bytes)) } pub fn write_u32(v: u32, writer: &mut W) -> Result<(), Error> { writer.write_all(&v.to_le_bytes())?; Ok(()) } pub fn read_f32(reader: &mut R) -> Result { let mut bytes = [0u8; 4]; reader.read_exact(&mut bytes)?; Ok(f32::from_le_bytes(bytes)) } pub fn write_f32(v: f32, writer: &mut W) -> Result<(), Error> { writer.write_all(&v.to_le_bytes())?; Ok(()) } pub fn read_usize(reader: &mut R) -> Result { read_i32(reader)?.try_into().map_err(|_| Error::InvalidSave) } pub fn write_usize(v: usize, writer: &mut W) -> Result<(), Error> { let v: i32 = v.try_into().map_err(|_| Error::InvalidSave)?; write_i32(v, writer) } pub fn read_string(reader: &mut R) -> Result { let string_len = read_usize(reader)?; let bytes = read_bytevec(reader, string_len)?; String::from_utf8(bytes).map_err(|_| Error::InvalidSave) } pub fn write_str(s: &str, writer: &mut W) -> Result<(), Error> { write_usize(s.len(), writer)?; writer.write_all(s.as_bytes())?; Ok(()) } pub fn read_vec(len: usize, mut reader: F) -> Result, Error> where F: FnMut() -> Result, { let mut vec = Vec::with_capacity(len); for _ in 0..len { vec.push(reader()?); } Ok(vec) } pub fn read_array(mut reader: F) -> Result<[T; LEN], Error> where F: FnMut() -> Result, T: Default + Copy, { let mut arr = [Default::default(); LEN]; for slot in &mut arr { *slot = reader()?; } Ok(arr) } pub fn read_magic(reader: &mut R, magic_bytes: &[u8]) -> Result<(), Error> { let mut header = [0u8; 16]; reader.read_exact(&mut header)?; if header != *magic_bytes { return Err(Error::InvalidSave); } Ok(()) } pub fn read_version(reader: &mut R) -> Result<[i32; 4], Error> { read_array(|| read_i32(reader)) } pub fn read_bytevec(reader: &mut R, len: usize) -> Result, Error> { let mut vec = vec![0u8; len]; reader.read_exact(&mut vec)?; Ok(vec) }