il2_iltags/tags/serialization/
mod.rs

1/*
2 * BSD 3-Clause License
3 *
4 * Copyright (c) 2020, InterlockLedger Network
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * * Redistributions of source code must retain the above copyright notice, this
11 *   list of conditions and the following disclaimer.
12 *
13 * * Redistributions in binary form must reproduce the above copyright notice,
14 *   this list of conditions and the following disclaimer in the documentation
15 *   and/or other materials provided with the distribution.
16 *
17 * * Neither the name of the copyright holder nor the names of its
18 *   contributors may be used to endorse or promote products derived from
19 *   this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32//! This module implements serializer and deserializer traits. They are similar to
33//! their counterparts from [`crate::io::data`] but returns [`crate::tags::Result`]
34//! instead of [`crate::io::Result`]. Furthermore, they also adds the ability to
35//! serialize and deserialize bytes and other usefull data types.
36#[cfg(test)]
37mod tests;
38
39use super::Result;
40use crate::io::data::*;
41use crate::io::{Reader, Writer};
42
43//=============================================================================
44// ValueDeserializer
45//-----------------------------------------------------------------------------
46/// This trait adds the ability to deserialize fixed size values.
47///
48/// Since 1.2.0.
49pub trait ValueDeserializer<T: Sized + Copy> {
50    /// Deserializes the value.
51    ///
52    /// Returns:
53    /// - Ok(v): For success;
54    /// - Err(_): For failure;
55    fn deserialize_value(&mut self) -> Result<T>;
56}
57
58impl<T: Sized + Copy> ValueDeserializer<T> for dyn ValueReader<T> + '_ {
59    #[inline]
60    fn deserialize_value(&mut self) -> Result<T> {
61        let v: T = self.read_value()?;
62        Ok(v)
63    }
64}
65
66impl<T: Sized + Copy, R: ValueReader<T>> ValueDeserializer<T> for R {
67    #[inline]
68    fn deserialize_value(&mut self) -> Result<T> {
69        let v: T = self.read_value()?;
70        Ok(v)
71    }
72}
73
74// Default implementation of ValueDeserializer for dyn Reader.
75macro_rules! valuedeserializer_def_impl {
76    ($type: ty, $read_func: ident) => {
77        impl ValueDeserializer<$type> for dyn Reader + '_ {
78            #[inline]
79            fn deserialize_value(&mut self) -> Result<$type> {
80                let v: $type = $read_func(self)?;
81                Ok(v)
82            }
83        }
84    };
85}
86
87valuedeserializer_def_impl!(u8, read_u8);
88valuedeserializer_def_impl!(i8, read_i8);
89valuedeserializer_def_impl!(u16, read_u16);
90valuedeserializer_def_impl!(i16, read_i16);
91valuedeserializer_def_impl!(u32, read_u32);
92valuedeserializer_def_impl!(i32, read_i32);
93valuedeserializer_def_impl!(u64, read_u64);
94valuedeserializer_def_impl!(i64, read_i64);
95valuedeserializer_def_impl!(f32, read_f32);
96valuedeserializer_def_impl!(f64, read_f64);
97
98//=============================================================================
99// ILIntDeserializer
100//-----------------------------------------------------------------------------
101/// This trait adds the ability to deserialize ILInt values.
102///
103/// Since 1.2.0.
104pub trait ILIntDeserializer {
105    /// Deserializes an ILInt value.
106    ///
107    /// Returns:
108    /// - Ok(v): For success;
109    /// - Err(_): For failure;
110    fn deserialize_ilint(&mut self) -> Result<u64>;
111}
112
113impl ILIntDeserializer for dyn ILIntReader + '_ {
114    #[inline]
115    fn deserialize_ilint(&mut self) -> Result<u64> {
116        let v: u64 = self.read_ilint()?;
117        Ok(v)
118    }
119}
120
121impl<R: ILIntReader> ILIntDeserializer for R {
122    #[inline]
123    fn deserialize_ilint(&mut self) -> Result<u64> {
124        let v: u64 = self.read_ilint()?;
125        Ok(v)
126    }
127}
128
129impl ILIntDeserializer for dyn Reader + '_ {
130    #[inline]
131    fn deserialize_ilint(&mut self) -> Result<u64> {
132        let v: u64 = self.read_ilint()?;
133        Ok(v)
134    }
135}
136
137//=============================================================================
138// StringDeserializer
139//-----------------------------------------------------------------------------
140/// This trait adds the ability to deserialize UTF-8 strings.
141///
142/// Since 1.2.0.
143pub trait StringDeserializer {
144    /// Deserializes an UTF-8 String with a given size.
145    ///
146    /// Arguments:
147    /// - `size`: Number of bytes to read.
148    ///
149    /// Returns:
150    /// - Ok(v): For success;
151    /// - Err(_): For failure;
152    fn deserialize_string(&mut self, size: usize) -> Result<String>;
153}
154
155impl StringDeserializer for dyn StringValueReader + '_ {
156    #[inline]
157    fn deserialize_string(&mut self, size: usize) -> Result<String> {
158        let v: String = self.read_string(size)?;
159        Ok(v)
160    }
161}
162
163impl<R: StringValueReader> StringDeserializer for R {
164    #[inline]
165    fn deserialize_string(&mut self, size: usize) -> Result<String> {
166        let v: String = self.read_string(size)?;
167        Ok(v)
168    }
169}
170
171impl StringDeserializer for dyn Reader + '_ {
172    #[inline]
173    fn deserialize_string(&mut self, size: usize) -> Result<String> {
174        let v: String = self.read_string(size)?;
175        Ok(v)
176    }
177}
178
179//=============================================================================
180// ByteArrayDeserializer
181//-----------------------------------------------------------------------------
182/// This trait adds the ability to deserialize byte arrays.
183///
184/// Since 1.2.0.
185pub trait ByteArrayDeserializer {
186    /// Deserializes a byte array of a given size.
187    ///
188    /// Arguments:
189    /// - `size`: The number of bytes to read;
190    ///
191    /// Returns:
192    /// - Ok(v): A vector with the bytes read;
193    /// - Err(e): In case of error;    
194    fn deserialize_bytes(&mut self, size: usize) -> Result<Vec<u8>>;
195
196    /// Deserializes a byte array of a given size into a vector.
197    ///
198    /// Arguments:
199    /// - `size`: The number of bytes to read;
200    /// - `vec`: The vector that will receive the data;
201    ///
202    /// Returns:
203    /// - Ok(v): A vector with the bytes read;
204    /// - Err(e): In case of error;    
205    fn deserialize_bytes_into_vec(&mut self, size: usize, vec: &mut Vec<u8>) -> Result<()> {
206        vec.resize(size, 0);
207        self.deserialize_bytes_into_slice(vec.as_mut_slice())
208    }
209
210    /// Deserializes a byte array of a given size into slice.
211    ///
212    /// Arguments:
213    /// - `buff`: The vector that will receive the data;
214    ///
215    /// Returns:
216    /// - Ok(v): A vector with the bytes read;
217    /// - Err(e): In case of error;    
218    fn deserialize_bytes_into_slice(&mut self, buff: &mut [u8]) -> Result<()>;
219}
220
221impl ByteArrayDeserializer for dyn Reader + '_ {
222    #[inline]
223    fn deserialize_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
224        let mut ret: Vec<u8> = vec![0; size];
225        self.read_all(ret.as_mut_slice())?;
226        Ok(ret)
227    }
228
229    #[inline]
230    fn deserialize_bytes_into_slice(&mut self, buff: &mut [u8]) -> Result<()> {
231        self.read_all(buff)?;
232        Ok(())
233    }
234}
235
236impl<R: Reader> ByteArrayDeserializer for R {
237    #[inline]
238    fn deserialize_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
239        let mut ret: Vec<u8> = vec![0; size];
240        self.read_all(ret.as_mut_slice())?;
241        Ok(ret)
242    }
243
244    #[inline]
245    fn deserialize_bytes_into_slice(&mut self, buff: &mut [u8]) -> Result<()> {
246        self.read_all(buff)?;
247        Ok(())
248    }
249}
250
251//=============================================================================
252// ValueSerializer
253//-----------------------------------------------------------------------------
254/// This trait adds the ability to serialize values.
255///
256/// Since 1.2.0.
257pub trait ValueSerializer<T> {
258    /// Serializes a value.
259    ///
260    /// Arguments:
261    /// - `value`: The value to write;
262    ///
263    /// Returns:
264    /// - Ok(()): For success;
265    /// - Err(_): For failure;
266    fn serialize_value(&mut self, value: T) -> Result<()>;
267}
268
269impl<T> ValueSerializer<T> for dyn ValueWriter<T> + '_ {
270    #[inline]
271    fn serialize_value(&mut self, value: T) -> Result<()> {
272        self.write_value(value)?;
273        Ok(())
274    }
275}
276
277impl<T, W: ValueWriter<T>> ValueSerializer<T> for W {
278    #[inline]
279    fn serialize_value(&mut self, value: T) -> Result<()> {
280        self.write_value(value)?;
281        Ok(())
282    }
283}
284
285// Default implementation of ValueWriter for the concrete type and dyn Writer.
286macro_rules! valueserializer_def_impl {
287    ($type: ty, $write_func: ident) => {
288        impl ValueSerializer<$type> for dyn Writer + '_ {
289            #[inline]
290            fn serialize_value(&mut self, value: $type) -> Result<()> {
291                $write_func(value, self)?;
292                Ok(())
293            }
294        }
295    };
296}
297
298valueserializer_def_impl!(u8, write_u8);
299valueserializer_def_impl!(i8, write_i8);
300valueserializer_def_impl!(u16, write_u16);
301valueserializer_def_impl!(i16, write_i16);
302valueserializer_def_impl!(u32, write_u32);
303valueserializer_def_impl!(i32, write_i32);
304valueserializer_def_impl!(u64, write_u64);
305valueserializer_def_impl!(i64, write_i64);
306valueserializer_def_impl!(f32, write_f32);
307valueserializer_def_impl!(f64, write_f64);
308valueserializer_def_impl!(&str, write_string);
309
310//=============================================================================
311// ILIntSerializer
312//-----------------------------------------------------------------------------
313/// This trait adds the ability to serialize ILInt values.
314///
315/// Since 1.2.0.
316pub trait ILIntSerializer {
317    /// Serializes an ILInt value.
318    ///
319    /// Arguments:
320    /// - `value`: The value to write;
321    ///
322    /// Returns:
323    /// - Ok(()): For success;
324    /// - Err(_): For failure;
325    fn serialize_ilint(&mut self, value: u64) -> Result<()>;
326}
327
328impl ILIntSerializer for dyn ILIntWriter + '_ {
329    #[inline]
330    fn serialize_ilint(&mut self, value: u64) -> Result<()> {
331        self.write_ilint(value)?;
332        Ok(())
333    }
334}
335
336impl<W: ILIntWriter> ILIntSerializer for W {
337    #[inline]
338    fn serialize_ilint(&mut self, value: u64) -> Result<()> {
339        self.write_ilint(value)?;
340        Ok(())
341    }
342}
343
344impl ILIntSerializer for dyn Writer + '_ {
345    #[inline]
346    fn serialize_ilint(&mut self, value: u64) -> Result<()> {
347        self.write_ilint(value)?;
348        Ok(())
349    }
350}
351
352//=============================================================================
353// ByteArraySerializer
354//-----------------------------------------------------------------------------
355/// This trait adds the ability to serialize byte arrays.
356///
357/// Since 1.2.0.
358pub trait ByteArraySerializer {
359    /// Serializes a byte array as a vector.
360    ///
361    /// This method has been deprecated because because it is equivalent to
362    /// [`ByteArraySerializer::serialize_bytes()`].
363    ///
364    /// Arguments:
365    /// - `value`: The value to write;
366    ///
367    /// Returns:
368    /// - Ok(()): For success;
369    /// - Err(_): For failure;
370    #[inline]
371    #[deprecated]
372    #[allow(clippy::ptr_arg)]
373    fn serialize_byte_vec(&mut self, vec: &Vec<u8>) -> Result<()> {
374        self.serialize_bytes(vec)
375    }
376
377    /// Serializes a byte array as a slice.
378    ///
379    /// Arguments:
380    /// - `value`: The value to write;
381    ///
382    /// Returns:
383    /// - Ok(()): For success;
384    /// - Err(_): For failure;
385    fn serialize_bytes(&mut self, buff: &[u8]) -> Result<()>;
386}
387
388impl ByteArraySerializer for dyn Writer + '_ {
389    #[inline]
390    fn serialize_bytes(&mut self, buff: &[u8]) -> Result<()> {
391        self.write_all(buff)?;
392        Ok(())
393    }
394}
395
396impl<W: Writer> ByteArraySerializer for W {
397    #[inline]
398    fn serialize_bytes(&mut self, buff: &[u8]) -> Result<()> {
399        self.write_all(buff)?;
400        Ok(())
401    }
402}
403
404//=============================================================================
405// Legacy functions
406//-----------------------------------------------------------------------------
407/// Serializes an u64 as an ILInt value.
408///
409/// Arguments:
410/// - `value`: The value to write;
411/// - `writer`: The writer;
412///
413/// Returns:
414/// - Ok(v): The value read;
415/// - Err(x): In case of error;
416pub fn serialize_ilint(value: u64, writer: &mut dyn Writer) -> Result<()> {
417    writer.serialize_ilint(value)
418}
419
420/// Unserializes an ILInt value.
421///
422/// Arguments:
423/// - `reader`: The reader;
424///
425/// Returns:
426/// - Ok(v): The value read;
427/// - Err(x): In case of error;
428pub fn deserialize_ilint(reader: &mut dyn Reader) -> Result<u64> {
429    reader.deserialize_ilint()
430}
431
432/// Serializes a byte array.
433///
434/// Arguments:
435/// - `bytes`: The bytes to be written;
436/// - `writer`: The writer;
437///
438/// Returns:
439/// - Ok(()): On success;
440/// - Err(e): In case of error;
441pub fn serialize_bytes(bytes: &[u8], writer: &mut dyn Writer) -> Result<()> {
442    writer.serialize_bytes(bytes)
443}
444
445/// Deserializes a byte array of a given size.
446///
447/// Arguments:
448/// - `reader`: The reader;
449/// - `size`: The number of bytes to read;
450///
451/// Returns:
452/// - Ok(v): A vector with the bytes read;
453/// - Err(e): In case of error;
454pub fn deserialize_bytes(size: usize, reader: &mut dyn Reader) -> Result<Vec<u8>> {
455    reader.deserialize_bytes(size)
456}
457
458/// Deserializes a byte array of a given size into a vector.
459///
460/// Arguments:
461/// - `reader`: The reader;
462/// - `size`: The number of bytes to read;
463/// - `vec`: The vector that will receive the data;
464///
465/// Returns:
466/// - Ok(v): A vector with the bytes read;
467/// - Err(e): In case of error;
468pub fn deserialize_bytes_into_vec(
469    size: usize,
470    reader: &mut dyn Reader,
471    vec: &mut Vec<u8>,
472) -> Result<()> {
473    reader.deserialize_bytes_into_vec(size, vec)
474}
475
476//=============================================================================
477// SignedILIntDeserializer
478//-----------------------------------------------------------------------------
479/// This trait adds the ability to deserialize signed ILInt values.
480///
481/// New since 1.3.0.
482pub trait SignedILIntDeserializer {
483    /// Deserializes an ILInt value.
484    ///
485    /// Returns:
486    /// - Ok(v): For success;
487    /// - Err(_): For failure;
488    fn deserialize_signed_ilint(&mut self) -> Result<i64>;
489}
490
491impl SignedILIntDeserializer for dyn SignedILIntReader + '_ {
492    #[inline]
493    fn deserialize_signed_ilint(&mut self) -> Result<i64> {
494        let v: i64 = self.read_signed_ilint()?;
495        Ok(v)
496    }
497}
498
499impl<R: SignedILIntReader> SignedILIntDeserializer for R {
500    #[inline]
501    fn deserialize_signed_ilint(&mut self) -> Result<i64> {
502        let v: i64 = self.read_signed_ilint()?;
503        Ok(v)
504    }
505}
506
507impl SignedILIntDeserializer for dyn Reader + '_ {
508    #[inline]
509    fn deserialize_signed_ilint(&mut self) -> Result<i64> {
510        let v: i64 = self.read_signed_ilint()?;
511        Ok(v)
512    }
513}
514
515//=============================================================================
516// SignedILIntSerializer
517//-----------------------------------------------------------------------------
518/// This trait adds the ability to serialize signed ILInt values.
519///
520/// Since 1.2.0.
521pub trait SignedILIntSerializer {
522    /// Serializes an ILInt value.
523    ///
524    /// Arguments:
525    /// - `value`: The value to write;
526    ///
527    /// Returns:
528    /// - Ok(()): For success;
529    /// - Err(_): For failure;
530    fn serialize_signed_ilint(&mut self, value: i64) -> Result<()>;
531}
532
533impl SignedILIntSerializer for dyn SignedILIntWriter + '_ {
534    #[inline]
535    fn serialize_signed_ilint(&mut self, value: i64) -> Result<()> {
536        self.write_signed_ilint(value)?;
537        Ok(())
538    }
539}
540
541impl<W: SignedILIntWriter> SignedILIntSerializer for W {
542    #[inline]
543    fn serialize_signed_ilint(&mut self, value: i64) -> Result<()> {
544        self.write_signed_ilint(value)?;
545        Ok(())
546    }
547}
548
549impl SignedILIntSerializer for dyn Writer + '_ {
550    #[inline]
551    fn serialize_signed_ilint(&mut self, value: i64) -> Result<()> {
552        self.write_signed_ilint(value)?;
553        Ok(())
554    }
555}