]> git.lizzy.rs Git - mt_ser.git/blob - src/lib.rs
derive serialize for enums
[mt_ser.git] / src / lib.rs
1 pub use enumset;
2 pub use flate2;
3 pub use paste::paste;
4
5 #[cfg(feature = "random")]
6 pub use generate_random;
7
8 #[cfg(feature = "random")]
9 pub use rand;
10
11 #[cfg(feature = "serde")]
12 pub use serde;
13
14 use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
15 use enumset::{EnumSet, EnumSetType, EnumSetTypeWithRepr};
16 use mt_data_derive::mt_derive;
17 pub use mt_data_derive::{MtDeserialize, MtSerialize};
18 use std::{
19     collections::{HashMap, HashSet},
20     convert::Infallible,
21     fmt,
22     io::{self, Read, Write},
23     num::TryFromIntError,
24     ops::Deref,
25 };
26 use thiserror::Error;
27
28 #[cfg(feature = "serde")]
29 use serde::{Deserialize, Serialize};
30
31 #[cfg(feature = "random")]
32 use generate_random::GenerateRandom;
33
34 use crate as mt_data;
35
36 #[derive(Error, Debug)]
37 #[error("variable length")]
38 pub struct VarLen;
39
40 #[derive(Error, Debug)]
41 pub enum SerializeError {
42     #[error("io error: {0}")]
43     IoError(#[from] io::Error),
44     #[error("collection too big: {0}")]
45     TooBig(#[from] TryFromIntError),
46     #[error("unimplemented")]
47     Unimplemented,
48 }
49
50 impl From<Infallible> for DeserializeError {
51     fn from(_err: Infallible) -> Self {
52         unreachable!("infallible")
53     }
54 }
55
56 #[derive(Error, Debug)]
57 pub enum DeserializeError {
58     #[error("io error: {0}")]
59     IoError(#[from] io::Error),
60     #[error("variable length not supported")]
61     NoVarlen(#[from] VarLen),
62     #[error("collection too big: {0}")]
63     TooBig(#[from] TryFromIntError),
64     #[error("unimplemented")]
65     Unimplemented,
66 }
67
68 impl From<Infallible> for SerializeError {
69     fn from(_err: Infallible) -> Self {
70         unreachable!("infallible")
71     }
72 }
73
74 pub trait MtCfg:
75     Sized
76     + MtSerialize
77     + MtDeserialize
78     + TryFrom<usize, Error = Self::TryFromError>
79     + TryInto<usize, Error = Self::TryIntoError>
80 {
81     type TryFromError: Into<SerializeError>;
82     type TryIntoError: Into<DeserializeError>;
83
84     #[inline]
85     fn utf16() -> bool {
86         false
87     }
88
89     fn write_len(len: usize, writer: &mut impl Write) -> Result<(), SerializeError> {
90         Ok(Self::try_from(len)
91             .map_err(|e| e.into())?
92             .mt_serialize::<DefCfg>(writer)?)
93     }
94 }
95
96 pub type DefCfg = u16;
97
98 pub trait MtSerialize: Sized {
99     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError>;
100 }
101
102 pub trait MtDeserialize: Sized {
103     fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError>;
104 }
105
106 impl MtCfg for u8 {
107     type TryFromError = TryFromIntError;
108     type TryIntoError = Infallible;
109 }
110
111 impl MtCfg for u16 {
112     type TryFromError = TryFromIntError;
113     type TryIntoError = Infallible;
114 }
115
116 impl MtCfg for u32 {
117     type TryFromError = TryFromIntError;
118     type TryIntoError = TryFromIntError;
119 }
120
121 impl MtCfg for u64 {
122     type TryFromError = TryFromIntError;
123     type TryIntoError = TryFromIntError;
124 }
125
126 pub struct NoLen;
127
128 impl MtSerialize for NoLen {
129     fn mt_serialize<C: MtCfg>(&self, _writer: &mut impl Write) -> Result<(), SerializeError> {
130         Ok(())
131     }
132 }
133
134 impl MtDeserialize for NoLen {
135     fn mt_deserialize<C: MtCfg>(_reader: &mut impl Read) -> Result<Self, DeserializeError> {
136         Ok(Self)
137     }
138 }
139
140 impl TryFrom<usize> for NoLen {
141     type Error = Infallible;
142
143     fn try_from(_x: usize) -> Result<Self, Self::Error> {
144         Ok(Self)
145     }
146 }
147
148 impl TryInto<usize> for NoLen {
149     type Error = VarLen;
150
151     fn try_into(self) -> Result<usize, Self::Error> {
152         Err(VarLen)
153     }
154 }
155
156 impl MtCfg for NoLen {
157     type TryFromError = Infallible;
158     type TryIntoError = VarLen;
159 }
160
161 pub struct Utf16<B: MtCfg>(pub B);
162
163 impl<B: MtCfg> MtSerialize for Utf16<B> {
164     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
165         self.0.mt_serialize::<DefCfg>(writer)
166     }
167 }
168
169 impl<B: MtCfg> MtDeserialize for Utf16<B> {
170     fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
171         Ok(Self(B::mt_deserialize::<DefCfg>(reader)?))
172     }
173 }
174
175 impl<B: MtCfg> TryFrom<usize> for Utf16<B> {
176     type Error = B::TryFromError;
177
178     fn try_from(x: usize) -> Result<Self, Self::Error> {
179         Ok(Self(x.try_into()?))
180     }
181 }
182
183 impl<B: MtCfg> TryInto<usize> for Utf16<B> {
184     type Error = B::TryIntoError;
185
186     fn try_into(self) -> Result<usize, Self::Error> {
187         self.0.try_into()
188     }
189 }
190
191 impl<B: MtCfg> MtCfg for Utf16<B> {
192     type TryFromError = B::TryFromError;
193     type TryIntoError = B::TryIntoError;
194
195     #[inline]
196     fn utf16() -> bool {
197         true
198     }
199 }
200
201 impl MtSerialize for u8 {
202     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
203         writer.write_u8(*self)?;
204         Ok(())
205     }
206 }
207
208 impl MtDeserialize for u8 {
209     fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
210         Ok(reader.read_u8()?)
211     }
212 }
213
214 impl MtSerialize for i8 {
215     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
216         writer.write_i8(*self)?;
217         Ok(())
218     }
219 }
220
221 impl MtDeserialize for i8 {
222     fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
223         Ok(reader.read_i8()?)
224     }
225 }
226
227 macro_rules! impl_num {
228     ($T:ty) => {
229         impl MtSerialize for $T {
230             fn mt_serialize<C: MtCfg>(
231                 &self,
232                 writer: &mut impl Write,
233             ) -> Result<(), SerializeError> {
234                 paste! {
235                     writer.[<write_ $T>]::<BigEndian>(*self)?;
236                 }
237                 Ok(())
238             }
239         }
240
241         impl MtDeserialize for $T {
242             fn mt_deserialize<C: MtCfg>(reader: &mut impl Read) -> Result<Self, DeserializeError> {
243                 paste! {
244                     Ok(reader.[<read_ $T>]::<BigEndian>()?)
245                 }
246             }
247         }
248     };
249 }
250
251 impl_num!(u16);
252 impl_num!(i16);
253
254 impl_num!(u32);
255 impl_num!(i32);
256 impl_num!(f32);
257
258 impl_num!(u64);
259 impl_num!(i64);
260 impl_num!(f64);
261
262 impl MtSerialize for () {
263     fn mt_serialize<C: MtCfg>(&self, _writer: &mut impl Write) -> Result<(), SerializeError> {
264         Ok(())
265     }
266 }
267
268 impl MtSerialize for bool {
269     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
270         (*self as u8).mt_serialize::<DefCfg>(writer)
271     }
272 }
273
274 impl<T: MtSerialize, const N: usize> MtSerialize for [T; N] {
275     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
276         self.as_slice().mt_serialize::<NoLen>(writer)
277     }
278 }
279
280 impl<T: MtSerialize> MtSerialize for &[T] {
281     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
282         C::write_len(self.len(), writer)?;
283         for item in self.iter() {
284             item.mt_serialize::<DefCfg>(writer)?;
285         }
286         Ok(())
287     }
288 }
289
290 impl<T: MtSerialize, E: EnumSetTypeWithRepr<Repr = T>> MtSerialize for EnumSet<E> {
291     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
292         self.as_repr().mt_serialize::<DefCfg>(writer)
293     }
294 }
295
296 impl<T: MtSerialize> MtSerialize for Option<T> {
297     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
298         match self {
299             Some(item) => item.mt_serialize::<C>(writer),
300             None => Ok(()),
301         }
302     }
303 }
304
305 impl<T: MtSerialize> MtSerialize for Vec<T> {
306     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
307         self.as_slice().mt_serialize::<C>(writer)
308     }
309 }
310
311 impl<T: MtSerialize> MtSerialize for HashSet<T> {
312     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
313         C::write_len(self.len(), writer)?;
314         for item in self.iter() {
315             item.mt_serialize::<DefCfg>(writer)?;
316         }
317         Ok(())
318     }
319 }
320
321 impl<K, V> MtSerialize for HashMap<K, V>
322 where
323     K: MtSerialize + std::cmp::Eq + std::hash::Hash,
324     V: MtSerialize,
325 {
326     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
327         C::write_len(self.len(), writer)?;
328         for (key, value) in self.iter() {
329             key.mt_serialize::<DefCfg>(writer)?;
330             value.mt_serialize::<DefCfg>(writer)?;
331         }
332         Ok(())
333     }
334 }
335
336 impl MtSerialize for String {
337     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
338         if C::utf16() {
339             self.encode_utf16()
340                 .collect::<Vec<_>>()
341                 .mt_serialize::<C>(writer)
342         } else {
343             self.as_bytes().mt_serialize::<C>(writer)
344         }
345     }
346 }
347
348 impl<T: MtSerialize> MtSerialize for Box<T> {
349     fn mt_serialize<C: MtCfg>(&self, writer: &mut impl Write) -> Result<(), SerializeError> {
350         self.deref().mt_serialize::<C>(writer)
351     }
352 }
353
354 mod to_clt;
355 mod to_srv;
356
357 pub use to_clt::*;
358 pub use to_srv::*;