1pub use save_state_derive::*;
2
3use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
4use paste::paste;
5use std::convert::From;
6use std::io::{
7 self, Cursor, Error as ioError, ErrorKind as ioErrorKind, Read, Result as ioResult, Write,
8};
9
10type CiboriumSerIoError = ciborium::ser::Error<io::Error>;
11type CiboriumDeIoError = ciborium::de::Error<io::Error>;
12pub type Result<T> = std::result::Result<T, Error>;
13
14pub fn serialize_into<W, T>(writer: W, value: &T) -> Result<()>
15where
16 W: std::io::Write,
17 T: serde::Serialize,
18{
19 ciborium::ser::into_writer(value, writer).map_err(|e| e.into())
20}
21
22pub fn deserialize_from<R, T>(reader: R) -> Result<T>
23where
24 R: std::io::Read,
25 T: serde::de::DeserializeOwned,
26{
27 ciborium::de::from_reader(reader).map_err(|e| e.into())
28}
29
30pub fn serialized_size<T>(value: &T) -> Result<u64>
31where
32 T: serde::Serialize,
33{
34 let mut counter = Counter::default();
35 ciborium::ser::into_writer(value, &mut counter)?;
36 Ok(counter.counter)
37}
38
39#[derive(Default)]
42struct Counter {
43 counter: u64,
44}
45
46impl Counter {
47 #[inline]
48 fn add(&mut self, c: usize) -> ioResult<()> {
49 let (counter, overflow) = self.counter.overflowing_add(c as u64);
51 self.counter = counter;
52
53 if overflow {
54 Err(ioError::new(
55 ioErrorKind::InvalidInput,
56 "write length exceed u64 limit",
57 ))
58 } else {
59 Ok(())
60 }
61 }
62}
63
64impl Write for Counter {
65 #[inline]
66 fn write(&mut self, buf: &[u8]) -> ioResult<usize> {
67 self.add(buf.len())?;
68 Ok(buf.len())
69 }
70
71 #[inline]
72 fn write_vectored(&mut self, bufs: &[std::io::IoSlice<'_>]) -> ioResult<usize> {
73 let len = bufs.iter().map(|b| b.len()).sum();
74 self.add(len)?;
75 Ok(len)
76 }
77
78 #[inline]
79 fn write_all(&mut self, buf: &[u8]) -> ioResult<()> {
80 self.add(buf.len())?;
81 Ok(())
82 }
83
84 #[inline]
85 fn flush(&mut self) -> ioResult<()> {
86 Ok(())
87 }
88}
89
90pub trait Savable {
91 fn save<W: Write>(&self, writer: &mut W) -> Result<()>;
92 fn load<R: Read>(&mut self, reader: &mut R) -> Result<()>;
93 #[inline]
96 fn save_size(&self) -> Result<u64> {
97 let mut counter = Counter::default();
98 self.save(&mut counter)?;
99 Ok(counter.counter)
100 }
101}
102
103pub fn save_object<T: Savable>(object: &T) -> Result<Vec<u8>> {
104 let mut result = Vec::new();
105 object.save(&mut result)?;
106
107 Ok(result)
108}
109
110pub fn load_object<T: Savable>(object: &mut T, data: &[u8]) -> Result<()> {
111 let mut cursor = Cursor::new(data);
112 object.load(&mut cursor)?;
113
114 let (remaining_data_len, overflow) = (data.len() as u64).overflowing_sub(cursor.position());
115 assert!(!overflow);
116
117 if remaining_data_len > 0 {
118 Err(Error::TrailingData(remaining_data_len))
119 } else {
120 Ok(())
121 }
122}
123
124#[derive(thiserror::Error, Debug)]
125pub enum Error {
126 #[error("Io Eror: {0}")]
127 IoError(ioError),
128 #[error("Cobr Serialization Error: {0}")]
129 CiboriumSerialization(CiboriumSerIoError),
130 #[error("Cobr Deserialization Error: {0}")]
131 CiboriumDeserialization(CiboriumDeIoError),
132 #[error("After loading an object, some data still remained ({0} bytes)")]
133 TrailingData(u64),
134 #[error("Enum could not be loaded correctly due to corrupted data ({0})")]
135 InvalidEnumVariant(usize),
136}
137
138impl From<ioError> for Error {
139 fn from(e: ioError) -> Self {
140 Error::IoError(e)
141 }
142}
143
144impl From<CiboriumSerIoError> for Error {
145 fn from(e: CiboriumSerIoError) -> Self {
146 Self::CiboriumSerialization(e)
147 }
148}
149
150impl From<CiboriumDeIoError> for Error {
151 fn from(e: CiboriumDeIoError) -> Self {
152 Self::CiboriumDeserialization(e)
153 }
154}
155
156macro_rules! impl_primitive {
157 ($struct_name: ident $(, $g: tt)? ) => {
158 impl Savable for $struct_name {
159 #[inline]
160 fn save<W: ::std::io::Write>(&self, writer: &mut W) -> Result<()> {
161 paste!(writer.[<write_ $struct_name>]$($g<LittleEndian>)?(*self)?);
162 Ok(())
163 }
164
165 #[inline]
166 fn load<R: ::std::io::Read>(&mut self, reader: &mut R) -> Result<()> {
167 *self = paste!(reader.[<read_ $struct_name>]$($g<LittleEndian>)?()?);
168 Ok(())
169 }
170
171 #[inline]
172 fn save_size(&self) -> Result<u64> {
173 Ok(::std::mem::size_of::<Self>() as u64)
174 }
175 }
176 };
177}
178
179macro_rules! impl_savable_with_serde {
181 ($struct_name: ident $(<$($generics: ident),+>)?) => {
182 impl $(<$($generics: serde::Serialize + serde::de::DeserializeOwned),+>)? Savable for $struct_name $(<$($generics),+>)?{
183 #[inline]
184 fn save<W: ::std::io::Write>(&self, writer: &mut W) -> Result<()> {
185 serialize_into(writer, self)?;
186 Ok(())
187 }
188
189 #[inline]
190 fn load<R: ::std::io::Read>(&mut self, reader: &mut R) -> Result<()> {
191 let obj = deserialize_from(reader)?;
192 let _ = ::std::mem::replace(self, obj);
193 Ok(())
194 }
195 }
196 };
197}
198
199macro_rules! impl_for_tuple {
200 ($($id: tt $tuple_element: ident),+) => {
201 impl<$($tuple_element),+> Savable for ($($tuple_element),+)
202 where $($tuple_element: Savable),+
203 {
204 #[inline]
205 fn save<W: ::std::io::Write>(&self, mut writer: &mut W) -> Result<()> {
206 $(<$tuple_element as Savable>::save(&self.$id, &mut writer)?;)+
207 Ok(())
208 }
209
210 #[inline]
211 fn load<R: ::std::io::Read>(&mut self, mut reader: &mut R) -> Result<()> {
212 $(<$tuple_element as Savable>::load(&mut self.$id, &mut reader)?;)+
213 Ok(())
214 }
215 }
216 };
217}
218
219impl_primitive!(u8);
220impl_primitive!(u16, ::);
221impl_primitive!(u32, ::);
222impl_primitive!(u64, ::);
223impl_primitive!(i8);
224impl_primitive!(i16, ::);
225impl_primitive!(i32, ::);
226impl_primitive!(i64, ::);
227impl_primitive!(f32, ::);
228impl_primitive!(f64, ::);
229impl_savable_with_serde!(bool);
230impl_savable_with_serde!(char);
231impl_savable_with_serde!(String);
232impl_savable_with_serde!(Vec<T>);
233
234impl_for_tuple!(0 A0, 1 A1);
235impl_for_tuple!(0 A0, 1 A1, 2 A2);
236impl_for_tuple!(0 A0, 1 A1, 2 A2, 3 A3);
237impl_for_tuple!(0 A0, 1 A1, 2 A2, 3 A3, 4 A4);
238impl_for_tuple!(0 A0, 1 A1, 2 A2, 3 A3, 4 A4, 5 A5);
239impl_for_tuple!(0 A0, 1 A1, 2 A2, 3 A3, 4 A4, 5 A5, 6 A6);
240impl_for_tuple!(0 A0, 1 A1, 2 A2, 3 A3, 4 A4, 5 A5, 6 A6, 7 A7);
241impl_for_tuple!(0 A0, 1 A1, 2 A2, 3 A3, 4 A4, 5 A5, 6 A6, 7 A7, 8 A8);
242
243impl Savable for usize {
244 fn save<W: ::std::io::Write>(&self, writer: &mut W) -> Result<()> {
245 writer.write_u64::<LittleEndian>(*self as u64)?;
246 Ok(())
247 }
248
249 fn load<R: ::std::io::Read>(&mut self, reader: &mut R) -> Result<()> {
250 *self = reader.read_u64::<LittleEndian>()? as usize;
251 Ok(())
252 }
253
254 fn save_size(&self) -> Result<u64> {
255 Ok(::std::mem::size_of::<u64>() as u64)
256 }
257}
258
259impl Savable for isize {
260 fn save<W: ::std::io::Write>(&self, writer: &mut W) -> Result<()> {
261 writer.write_i64::<LittleEndian>(*self as i64)?;
262 Ok(())
263 }
264
265 fn load<R: ::std::io::Read>(&mut self, reader: &mut R) -> Result<()> {
266 *self = reader.read_i64::<LittleEndian>()? as isize;
267 Ok(())
268 }
269
270 fn save_size(&self) -> Result<u64> {
271 Ok(::std::mem::size_of::<i64>() as u64)
272 }
273}
274
275impl<T, const N: usize> Savable for [T; N]
278where
279 T: Savable,
280{
281 fn save<W: ::std::io::Write>(&self, mut writer: &mut W) -> Result<()> {
282 for element in self {
283 element.save(&mut writer)?;
284 }
285 Ok(())
286 }
287
288 fn load<R: ::std::io::Read>(&mut self, mut reader: &mut R) -> Result<()> {
289 for element in self {
290 element.load(&mut reader)?;
291 }
292 Ok(())
293 }
294}
295
296impl<T> Savable for Option<T>
297where
298 T: Savable + Default,
299{
300 fn save<W: Write>(&self, mut writer: &mut W) -> Result<()> {
301 match self {
302 Some(s) => {
303 true.save(&mut writer)?;
304 s.save(&mut writer)?;
305 }
306 None => false.save(&mut writer)?,
307 }
308 Ok(())
309 }
310
311 fn load<R: Read>(&mut self, mut reader: &mut R) -> Result<()> {
312 let mut value = false;
313 value.load(&mut reader)?;
314
315 if value {
316 match self {
317 Some(s) => {
318 s.load(&mut reader)?;
319 }
320 None => {
321 let mut s = T::default();
322 s.load(&mut reader)?;
323 self.replace(s);
324 }
325 }
326 } else {
327 *self = None;
328 }
329
330 Ok(())
331 }
332}
333
334impl<T> Savable for std::marker::PhantomData<T> {
335 fn save<W: Write>(&self, _writer: &mut W) -> Result<()> {
336 Ok(())
337 }
338
339 fn load<R: Read>(&mut self, _reader: &mut R) -> Result<()> {
340 Ok(())
341 }
342}
343
344impl Savable for () {
345 fn save<W: Write>(&self, _writer: &mut W) -> Result<()> {
346 Ok(())
347 }
348
349 fn load<R: Read>(&mut self, _reader: &mut R) -> Result<()> {
350 Ok(())
351 }
352}