pub use enumset; pub use flate2; #[cfg(feature = "random")] pub use generate_random; #[cfg(feature = "random")] pub use rand; #[cfg(feature = "serde")] pub use serde; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use enumset::{EnumSet, EnumSetType, EnumSetTypeWithRepr}; use mt_data_derive::mt_derive; pub use mt_data_derive::{MtDeserialize, MtSerialize}; use paste::paste; use std::{ collections::{HashMap, HashSet}, convert::Infallible, fmt, io::{self, Read, Write}, num::TryFromIntError, }; use thiserror::Error; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; #[cfg(feature = "random")] use generate_random::GenerateRandom; use crate as mt_data; #[derive(Error, Debug)] #[error("variable length")] pub struct VarLen; #[derive(Error, Debug)] pub enum SerializeError { #[error("io error: {0}")] IoError(#[from] io::Error), #[error("collection too big: {0}")] TooBig(#[from] TryFromIntError), #[error("unimplemented")] Unimplemented, } impl From for DeserializeError { fn from(_err: Infallible) -> Self { unreachable!("infallible") } } #[derive(Error, Debug)] pub enum DeserializeError { #[error("io error: {0}")] IoError(#[from] io::Error), #[error("variable length not supported")] NoVarlen(#[from] VarLen), #[error("collection too big: {0}")] TooBig(#[from] TryFromIntError), #[error("unimplemented")] Unimplemented, } impl From for SerializeError { fn from(_err: Infallible) -> Self { unreachable!("infallible") } } pub trait MtCfg: Sized + MtSerialize + MtDeserialize + TryFrom + TryInto { type TryFromError: Into; type TryIntoError: Into; #[inline] fn utf16() -> bool { false } fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> { Ok(Self::try_from(len) .map_err(|e| e.into())? .mt_serialize::(writer)?) } } pub type DefaultCfg = u16; pub trait MtSerialize: Sized { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError>; } pub trait MtDeserialize: Sized { fn mt_deserialize(reader: &mut impl Read) -> Result; } impl MtCfg for u8 { type TryFromError = TryFromIntError; type TryIntoError = Infallible; } impl MtCfg for u16 { type TryFromError = TryFromIntError; type TryIntoError = Infallible; } impl MtCfg for u32 { type TryFromError = TryFromIntError; type TryIntoError = TryFromIntError; } impl MtCfg for u64 { type TryFromError = TryFromIntError; type TryIntoError = TryFromIntError; } pub struct NoLen; impl MtSerialize for NoLen { fn mt_serialize(&self, _writer: &mut impl Write) -> Result<(), SerializeError> { Ok(()) } } impl MtDeserialize for NoLen { fn mt_deserialize(_reader: &mut impl Read) -> Result { Ok(Self) } } impl TryFrom for NoLen { type Error = Infallible; fn try_from(_x: usize) -> Result { Ok(Self) } } impl TryInto for NoLen { type Error = VarLen; fn try_into(self) -> Result { Err(VarLen) } } impl MtCfg for NoLen { type TryFromError = Infallible; type TryIntoError = VarLen; } pub struct Utf16(pub B); impl MtSerialize for Utf16 { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { self.0.mt_serialize::(writer) } } impl MtDeserialize for Utf16 { fn mt_deserialize(reader: &mut impl Read) -> Result { Ok(Self(B::mt_deserialize::(reader)?)) } } impl TryFrom for Utf16 { type Error = B::TryFromError; fn try_from(x: usize) -> Result { Ok(Self(x.try_into()?)) } } impl TryInto for Utf16 { type Error = B::TryIntoError; fn try_into(self) -> Result { self.0.try_into() } } impl MtCfg for Utf16 { type TryFromError = B::TryFromError; type TryIntoError = B::TryIntoError; #[inline] fn utf16() -> bool { true } } impl MtSerialize for u8 { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { writer.write_u8(*self)?; Ok(()) } } impl MtDeserialize for u8 { fn mt_deserialize(reader: &mut impl Read) -> Result { Ok(reader.read_u8()?) } } impl MtSerialize for i8 { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { writer.write_i8(*self)?; Ok(()) } } impl MtDeserialize for i8 { fn mt_deserialize(reader: &mut impl Read) -> Result { Ok(reader.read_i8()?) } } macro_rules! impl_num { ($T:ty) => { impl MtSerialize for $T { fn mt_serialize( &self, writer: &mut impl Write, ) -> Result<(), SerializeError> { paste! { writer.[]::(*self)?; } Ok(()) } } impl MtDeserialize for $T { fn mt_deserialize(reader: &mut impl Read) -> Result { paste! { Ok(reader.[]::()?) } } } }; } impl_num!(u16); impl_num!(i16); impl_num!(u32); impl_num!(i32); impl_num!(f32); impl_num!(u64); impl_num!(i64); impl_num!(f64); impl MtSerialize for () { fn mt_serialize(&self, _writer: &mut impl Write) -> Result<(), SerializeError> { Ok(()) } } impl MtSerialize for bool { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { (*self as u8).mt_serialize::(writer) } } impl MtSerialize for [T; N] { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { for item in self.iter() { item.mt_serialize::(writer)?; } Ok(()) } } impl> MtSerialize for EnumSet { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { self.as_repr().mt_serialize::(writer) } } impl MtSerialize for Option { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { match self { Some(item) => item.mt_serialize::(writer), None => Ok(()), } } } impl MtSerialize for Vec { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { C::write_len(self.len(), writer)?; for item in self.iter() { item.mt_serialize::(writer)?; } Ok(()) } } impl MtSerialize for HashSet { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { C::write_len(self.len(), writer)?; for item in self.iter() { item.mt_serialize::(writer)?; } Ok(()) } } impl MtSerialize for HashMap where K: MtSerialize + std::cmp::Eq + std::hash::Hash, V: MtSerialize, { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { C::write_len(self.len(), writer)?; for (key, value) in self.iter() { key.mt_serialize::(writer)?; value.mt_serialize::(writer)?; } Ok(()) } } impl MtSerialize for String { fn mt_serialize(&self, writer: &mut impl Write) -> Result<(), SerializeError> { if C::utf16() { // TODO Err(SerializeError::Unimplemented) } else { C::write_len(self.len(), writer)?; writer.write_all(self.as_bytes())?; Ok(()) } } } mod to_clt; mod to_srv; pub use to_clt::*; pub use to_srv::*;