mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/data/mod.rs')
| -rw-r--r-- | src/data/mod.rs | 588 |
1 files changed, 277 insertions, 311 deletions
diff --git a/src/data/mod.rs b/src/data/mod.rs index b8ab386..cf1b19f 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -7,365 +7,331 @@ pub mod command; pub mod dynamic; pub mod schematic; -pub struct DataRead<'d> -{ - data: &'d [u8] +pub struct DataRead<'d> { + data: &'d [u8], } -macro_rules!make_read -{ - ($name:ident, $type:ty) => - { - pub fn $name(&mut self) -> Result<$type, ReadError> - { - const LEN: usize = std::mem::size_of::<$type>(); - if self.data.len() < LEN - { - return Err(ReadError::Underflow{need: LEN, have: self.data.len()}); - } - let mut output = [0u8; LEN]; - output.copy_from_slice(&self.data[..LEN]); - self.data = &self.data[LEN..]; - Ok(<$type>::from_be_bytes(output)) - } - }; +macro_rules! make_read { + ($name:ident, $type:ty) => { + pub fn $name(&mut self) -> Result<$type, ReadError> { + const LEN: usize = std::mem::size_of::<$type>(); + if self.data.len() < LEN { + return Err(ReadError::Underflow { + need: LEN, + have: self.data.len(), + }); + } + let mut output = [0u8; LEN]; + output.copy_from_slice(&self.data[..LEN]); + self.data = &self.data[LEN..]; + Ok(<$type>::from_be_bytes(output)) + } + }; } -impl<'d> DataRead<'d> -{ - pub fn new(data: &'d [u8]) -> Self - { - Self{data} - } - - pub fn read_bool(&mut self) -> Result<bool, ReadError> - { - Ok(self.read_u8()? != 0) - } - - make_read!(read_u8, u8); - make_read!(read_i8, i8); - make_read!(read_u16, u16); - make_read!(read_i16, i16); - make_read!(read_u32, u32); - make_read!(read_i32, i32); - make_read!(read_f32, f32); - make_read!(read_u64, u64); - make_read!(read_i64, i64); - make_read!(read_f64, f64); - - pub fn read_utf(&mut self) -> Result<&'d str, ReadError> - { - if self.data.len() < 2 - { - return Err(ReadError::Underflow{need: 2, have: self.data.len()}); - } - let len = u16::from_be_bytes([self.data[0], self.data[1]]); - let end = 2 + len as usize; - if self.data.len() < end - { - return Err(ReadError::Underflow{need: end, have: self.data.len()}); - } - let result = std::str::from_utf8(&self.data[2..end])?; - self.data = &self.data[end..]; - Ok(result) - } - - pub fn read_bytes(&mut self, dst: &mut [u8]) -> Result<(), ReadError> - { - if self.data.len() < dst.len() - { - return Err(ReadError::Underflow{need: dst.len(), have: self.data.len()}); - } - dst.copy_from_slice(&self.data[..dst.len()]); - self.data = &self.data[dst.len()..]; - Ok(()) - } - - pub fn read_vec(&mut self, dst: &mut Vec<u8>, len: usize) -> Result<(), ReadError> - { - if self.data.len() < len - { - return Err(ReadError::Underflow{need: len, have: self.data.len()}); - } - dst.extend_from_slice(&self.data[..len]); - self.data = &self.data[len..]; - Ok(()) - } +impl<'d> DataRead<'d> { + pub fn new(data: &'d [u8]) -> Self { + Self { data } + } + + pub fn read_bool(&mut self) -> Result<bool, ReadError> { + Ok(self.read_u8()? != 0) + } + + make_read!(read_u8, u8); + make_read!(read_i8, i8); + make_read!(read_u16, u16); + make_read!(read_i16, i16); + make_read!(read_u32, u32); + make_read!(read_i32, i32); + make_read!(read_f32, f32); + make_read!(read_u64, u64); + make_read!(read_i64, i64); + make_read!(read_f64, f64); + + pub fn read_utf(&mut self) -> Result<&'d str, ReadError> { + if self.data.len() < 2 { + return Err(ReadError::Underflow { + need: 2, + have: self.data.len(), + }); + } + let len = u16::from_be_bytes([self.data[0], self.data[1]]); + let end = 2 + len as usize; + if self.data.len() < end { + return Err(ReadError::Underflow { + need: end, + have: self.data.len(), + }); + } + let result = std::str::from_utf8(&self.data[2..end])?; + self.data = &self.data[end..]; + Ok(result) + } + + pub fn read_bytes(&mut self, dst: &mut [u8]) -> Result<(), ReadError> { + if self.data.len() < dst.len() { + return Err(ReadError::Underflow { + need: dst.len(), + have: self.data.len(), + }); + } + dst.copy_from_slice(&self.data[..dst.len()]); + self.data = &self.data[dst.len()..]; + Ok(()) + } + + pub fn read_vec(&mut self, dst: &mut Vec<u8>, len: usize) -> Result<(), ReadError> { + if self.data.len() < len { + return Err(ReadError::Underflow { + need: len, + have: self.data.len(), + }); + } + dst.extend_from_slice(&self.data[..len]); + self.data = &self.data[len..]; + Ok(()) + } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum ReadError -{ - Underflow{need: usize, have: usize}, - Utf8(Utf8Error), +pub enum ReadError { + Underflow { need: usize, have: usize }, + Utf8(Utf8Error), } -impl From<Utf8Error> for ReadError -{ - fn from(err: Utf8Error) -> Self - { - Self::Utf8(err) - } +impl From<Utf8Error> for ReadError { + fn from(err: Utf8Error) -> Self { + Self::Utf8(err) + } } -impl fmt::Display for ReadError -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result - { - match self - { - Self::Underflow{need, have} => write!(f, "buffer underflow (expected {need} but got {have})"), - Self::Utf8(..) => f.write_str("malformed utf-8 in string"), - } - } +impl fmt::Display for ReadError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Underflow { need, have } => { + write!(f, "buffer underflow (expected {need} but got {have})") + } + Self::Utf8(..) => f.write_str("malformed utf-8 in string"), + } + } } -impl Error for ReadError -{ - fn source(&self) -> Option<&(dyn Error + 'static)> - { - match self - { - Self::Utf8(e) => Some(e), - _ => None, - } - } +impl Error for ReadError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + Self::Utf8(e) => Some(e), + _ => None, + } + } } -enum WriteBuff<'d> -{ - // unlike the DataRead want to access the written region after - Ref{raw: &'d mut [u8], pos: usize}, - Vec(Vec<u8>), +enum WriteBuff<'d> { + // unlike the DataRead want to access the written region after + Ref { raw: &'d mut [u8], pos: usize }, + Vec(Vec<u8>), } -impl<'d> WriteBuff<'d> -{ - fn check_capacity(&self, need: usize) -> Result<(), WriteError> - { - match self - { - Self::Ref{raw, pos} if raw.len() - pos < need => Err(WriteError::Overflow{need, have: raw.len() - pos}), - _ => Ok(()), - } - } - - fn write(&mut self, data: &[u8]) - { - match self - { - Self::Ref{raw, pos} => - { - let end = *pos + data.len(); - raw[*pos..end].copy_from_slice(data); - *pos += data.len(); - }, - Self::Vec(v) => v.extend_from_slice(data), - } - } +impl<'d> WriteBuff<'d> { + fn check_capacity(&self, need: usize) -> Result<(), WriteError> { + match self { + Self::Ref { raw, pos } if raw.len() - pos < need => Err(WriteError::Overflow { + need, + have: raw.len() - pos, + }), + _ => Ok(()), + } + } + + fn write(&mut self, data: &[u8]) { + match self { + Self::Ref { raw, pos } => { + let end = *pos + data.len(); + raw[*pos..end].copy_from_slice(data); + *pos += data.len(); + } + Self::Vec(v) => v.extend_from_slice(data), + } + } } -pub struct DataWrite<'d> -{ - data: WriteBuff<'d> +pub struct DataWrite<'d> { + data: WriteBuff<'d>, } -macro_rules!make_write -{ - ($name:ident, $type:ty) => - { - pub fn $name(&mut self, val: $type) -> Result<(), WriteError> - { - const LEN: usize = std::mem::size_of::<$type>(); - self.data.check_capacity(LEN)?; - self.data.write(&<$type>::to_be_bytes(val)); - Ok(()) - } - }; +macro_rules! make_write { + ($name:ident, $type:ty) => { + pub fn $name(&mut self, val: $type) -> Result<(), WriteError> { + const LEN: usize = std::mem::size_of::<$type>(); + self.data.check_capacity(LEN)?; + self.data.write(&<$type>::to_be_bytes(val)); + Ok(()) + } + }; } -impl<'d> DataWrite<'d> -{ - pub fn write_bool(&mut self, val: bool) -> Result<(), WriteError> - { - self.write_u8(val as u8) - } - - make_write!(write_u8, u8); - make_write!(write_i8, i8); - make_write!(write_u16, u16); - make_write!(write_i16, i16); - make_write!(write_u32, u32); - make_write!(write_i32, i32); - make_write!(write_f32, f32); - make_write!(write_u64, u64); - make_write!(write_i64, i64); - make_write!(write_f64, f64); - - pub fn write_utf(&mut self, val: &str) -> Result<(), WriteError> - { - if val.len() > u16::MAX as usize - { - return Err(WriteError::TooLong{len: val.len()}); - } - self.data.check_capacity(2 + val.len())?; - self.data.write(&u16::to_be_bytes(val.len() as u16)); - self.data.write(val.as_bytes()); - Ok(()) - } - - pub fn write_bytes(&mut self, val: &[u8]) -> Result<(), WriteError> - { - self.data.check_capacity(val.len())?; - self.data.write(val); - Ok(()) - } - - pub fn is_owned(&self) -> bool - { - match self.data - { - WriteBuff::Vec(..) => true, - _ => false, - } - } - - pub fn get_written(&self) -> &[u8] - { - match &self.data - { - WriteBuff::Ref{raw, pos} => &raw[..*pos], - WriteBuff::Vec(v) => &v, - } - } +impl<'d> DataWrite<'d> { + pub fn write_bool(&mut self, val: bool) -> Result<(), WriteError> { + self.write_u8(val as u8) + } + + make_write!(write_u8, u8); + make_write!(write_i8, i8); + make_write!(write_u16, u16); + make_write!(write_i16, i16); + make_write!(write_u32, u32); + make_write!(write_i32, i32); + make_write!(write_f32, f32); + make_write!(write_u64, u64); + make_write!(write_i64, i64); + make_write!(write_f64, f64); + + pub fn write_utf(&mut self, val: &str) -> Result<(), WriteError> { + if val.len() > u16::MAX as usize { + return Err(WriteError::TooLong { len: val.len() }); + } + self.data.check_capacity(2 + val.len())?; + self.data.write(&u16::to_be_bytes(val.len() as u16)); + self.data.write(val.as_bytes()); + Ok(()) + } + + pub fn write_bytes(&mut self, val: &[u8]) -> Result<(), WriteError> { + self.data.check_capacity(val.len())?; + self.data.write(val); + Ok(()) + } + + pub fn is_owned(&self) -> bool { + match self.data { + WriteBuff::Vec(..) => true, + _ => false, + } + } + + pub fn get_written(&self) -> &[u8] { + match &self.data { + WriteBuff::Ref { raw, pos } => &raw[..*pos], + WriteBuff::Vec(v) => &v, + } + } } -impl DataWrite<'static> -{ - pub fn new() -> Self - { - Self{data: WriteBuff::Vec(Vec::new())} - } +impl DataWrite<'static> { + pub fn new() -> Self { + Self { + data: WriteBuff::Vec(Vec::new()), + } + } } #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum WriteError -{ - Overflow{need: usize, have: usize}, - TooLong{len: usize}, +pub enum WriteError { + Overflow { need: usize, have: usize }, + TooLong { len: usize }, } -impl fmt::Display for WriteError -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result - { - match self - { - Self::Overflow{need, have} => write!(f, "buffer overflow (expected {need} but got {have})"), - Self::TooLong{len} => write!(f, "string too long ({len} bytes of {})", u16::MAX), - } - } +impl fmt::Display for WriteError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Overflow { need, have } => { + write!(f, "buffer overflow (expected {need} but got {have})") + } + Self::TooLong { len } => write!(f, "string too long ({len} bytes of {})", u16::MAX), + } + } } impl Error for WriteError {} -impl<'d> From<&'d mut [u8]> for DataWrite<'d> -{ - fn from(value: &'d mut [u8]) -> Self - { - Self{data: WriteBuff::Ref{raw: value, pos: 0}} - } +impl<'d> From<&'d mut [u8]> for DataWrite<'d> { + fn from(value: &'d mut [u8]) -> Self { + Self { + data: WriteBuff::Ref { raw: value, pos: 0 }, + } + } } -impl From<Vec<u8>> for DataWrite<'static> -{ - fn from(value: Vec<u8>) -> Self - { - Self{data: WriteBuff::Vec(value)} - } +impl From<Vec<u8>> for DataWrite<'static> { + fn from(value: Vec<u8>) -> Self { + Self { + data: WriteBuff::Vec(value), + } + } } -impl<'d> TryFrom<DataWrite<'d>> for Vec<u8> -{ - type Error = (); - - fn try_from(value: DataWrite<'d>) -> Result<Self, Self::Error> - { - match value.data - { - WriteBuff::Vec(v) => Ok(v), - _ => Err(()), - } - } +impl<'d> TryFrom<DataWrite<'d>> for Vec<u8> { + type Error = (); + + fn try_from(value: DataWrite<'d>) -> Result<Self, Self::Error> { + match value.data { + WriteBuff::Vec(v) => Ok(v), + _ => Err(()), + } + } } -pub trait Serializer<D> -{ - type ReadError; - type WriteError; - - fn deserialize(&mut self, buff: &mut DataRead<'_>) -> Result<D, Self::ReadError>; - - fn serialize(&mut self, buff: &mut DataWrite<'_>, data: &D) -> Result<(), Self::WriteError>; +pub trait Serializer<D> { + type ReadError; + type WriteError; + + fn deserialize(&mut self, buff: &mut DataRead<'_>) -> Result<D, Self::ReadError>; + + fn serialize(&mut self, buff: &mut DataWrite<'_>, data: &D) -> Result<(), Self::WriteError>; } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct GridPos(pub u16, pub u16); -impl From<u32> for GridPos -{ - fn from(value: u32) -> Self - { - GridPos((value >> 16) as u16, value as u16) - } +impl From<u32> for GridPos { + fn from(value: u32) -> Self { + GridPos((value >> 16) as u16, value as u16) + } } -impl From<GridPos> for u32 -{ - fn from(value: GridPos) -> Self - { - ((value.0 as u32) << 16) | (value.1 as u32) - } +impl From<GridPos> for u32 { + fn from(value: GridPos) -> Self { + ((value.0 as u32) << 16) | (value.1 as u32) + } } #[cfg(test)] -mod test -{ - use super::*; - - #[test] - fn read() - { - let mut read = DataRead::new("Thé qûick ઉrown fox 🦘 over\0\rthe lazy dog.".as_bytes()); - assert_eq!(read.read_u8(), Ok(84)); - assert_eq!(read.read_i8(), Ok(104)); - assert_eq!(read.read_i8(), Ok(-61)); - assert_eq!(read.read_u16(), Ok(43296)); - assert_eq!(read.read_i16(), Ok(29123)); - assert_eq!(read.read_i16(), Ok(-17559)); - assert_eq!(read.read_i32(), Ok(1667965152)); - assert_eq!(read.read_i32(), Ok(-1433832849)); - assert_eq!(read.read_i64(), Ok(8605851562280493296)); - assert_eq!(read.read_i64(), Ok(-6942694510468635278)); - assert_eq!(read.read_utf(), Ok("the lazy dog.")); - } - - #[test] - fn write() - { - let mut write = DataWrite::new(); - assert_eq!(write.write_u8(84), Ok(())); - assert_eq!(write.write_i8(104), Ok(())); - assert_eq!(write.write_i8(-61), Ok(())); - assert_eq!(write.write_u16(43296), Ok(())); - assert_eq!(write.write_i16(29123), Ok(())); - assert_eq!(write.write_i16(-17559), Ok(())); - assert_eq!(write.write_i32(1667965152), Ok(())); - assert_eq!(write.write_i32(-1433832849), Ok(())); - assert_eq!(write.write_i64(8605851562280493296), Ok(())); - assert_eq!(write.write_i64(-6942694510468635278), Ok(())); - assert_eq!(write.write_utf("the lazy dog."), Ok(())); - assert_eq!(write.get_written(), "Thé qûick ઉrown fox 🦘 over\0\rthe lazy dog.".as_bytes()); - } +mod test { + use super::*; + + #[test] + fn read() { + let mut read = DataRead::new("Thé qûick ઉrown fox 🦘 over\0\rthe lazy dog.".as_bytes()); + assert_eq!(read.read_u8(), Ok(84)); + assert_eq!(read.read_i8(), Ok(104)); + assert_eq!(read.read_i8(), Ok(-61)); + assert_eq!(read.read_u16(), Ok(43296)); + assert_eq!(read.read_i16(), Ok(29123)); + assert_eq!(read.read_i16(), Ok(-17559)); + assert_eq!(read.read_i32(), Ok(1667965152)); + assert_eq!(read.read_i32(), Ok(-1433832849)); + assert_eq!(read.read_i64(), Ok(8605851562280493296)); + assert_eq!(read.read_i64(), Ok(-6942694510468635278)); + assert_eq!(read.read_utf(), Ok("the lazy dog.")); + } + + #[test] + fn write() { + let mut write = DataWrite::new(); + assert_eq!(write.write_u8(84), Ok(())); + assert_eq!(write.write_i8(104), Ok(())); + assert_eq!(write.write_i8(-61), Ok(())); + assert_eq!(write.write_u16(43296), Ok(())); + assert_eq!(write.write_i16(29123), Ok(())); + assert_eq!(write.write_i16(-17559), Ok(())); + assert_eq!(write.write_i32(1667965152), Ok(())); + assert_eq!(write.write_i32(-1433832849), Ok(())); + assert_eq!(write.write_i64(8605851562280493296), Ok(())); + assert_eq!(write.write_i64(-6942694510468635278), Ok(())); + assert_eq!(write.write_utf("the lazy dog."), Ok(())); + assert_eq!( + write.get_written(), + "Thé qûick ઉrown fox 🦘 over\0\rthe lazy dog.".as_bytes() + ); + } } |