/* wearechat - generic multiplayer game with voip Copyright (C) 2025 metamuffin This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License only. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ use crate::packets::{Data, Object, Resource}; use anyhow::Result; use std::{ io::{Read, Write}, marker::PhantomData, }; pub trait ReadWrite: Sized { fn write(&self, w: &mut dyn Write) -> Result<()>; fn read(r: &mut dyn Read) -> Result; fn write_alloc(&self) -> Vec { let mut buf = Vec::new(); self.write(&mut buf).unwrap(); buf } } impl ReadWrite for f32 { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(&self.to_be_bytes())?; Ok(()) } fn read(r: &mut dyn Read) -> Result { let mut buf = [0; 4]; r.read_exact(&mut buf)?; Ok(f32::from_be_bytes(buf)) } } impl ReadWrite for u32 { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(&self.to_be_bytes())?; Ok(()) } fn read(r: &mut dyn Read) -> Result { let mut buf = [0; 4]; r.read_exact(&mut buf)?; Ok(u32::from_be_bytes(buf)) } } impl ReadWrite for Vec { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(&self)?; Ok(()) } fn read(r: &mut dyn Read) -> Result { let mut buf = Vec::new(); r.read_to_end(&mut buf)?; Ok(buf) } } impl ReadWrite for String { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(self.as_bytes())?; Ok(()) } fn read(r: &mut dyn Read) -> Result { let mut buf = Vec::new(); r.read_to_end(&mut buf)?; Ok(String::from_utf8(buf)?) } } impl ReadWrite for Data { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(&(self.0.len() as u32).to_be_bytes())?; w.write_all(&self.0)?; Ok(()) } fn read(r: &mut dyn Read) -> Result { let mut size = [0; 4]; r.read_exact(&mut size)?; let size = u32::from_be_bytes(size); let mut buf = vec![0; size as usize]; r.read_exact(&mut buf)?; Ok(Self(buf)) } } impl ReadWrite for Resource { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(&self.0)?; Ok(()) } fn read(r: &mut dyn Read) -> Result { let mut s = Self([0; 32], PhantomData); r.read_exact(&mut s.0)?; Ok(s) } } impl ReadWrite for Object { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(&self.0.to_be_bytes())?; Ok(()) } fn read(r: &mut dyn Read) -> Result { let mut s = [0; 16]; r.read_exact(&mut s)?; Ok(Object(u128::from_be_bytes(s))) } } impl ReadWrite for [T; N] { fn write(&self, w: &mut dyn Write) -> Result<()> { for e in self { e.write(w)?; } Ok(()) } fn read(r: &mut dyn Read) -> Result { [(); N].try_map(|()| T::read(r)) } }