lib_contra/
serialize.rs

1use crate::{error::SuccessResult, position::Position};
2
3pub mod json;
4
5/// Allows for the serialization of the implemented type
6///
7/// Implementors must provide the functionality to write *self* into any [Serializer].
8///
9/// # Example
10/// Best to not implemented by hand but rather derived via the Serialize derive macro of the [proc_contra](https://docs.rs/proc_contra/) crate.
11/// See: [Contra](https://docs.rs/contra/)
12/// ```
13/// use crate::{lib_contra::{serialize::Serialize, serialize::Serializer, position::Position, error::SuccessResult}};
14/// struct Point {
15///     x: f32,
16///     y: f32,
17///     z: f32
18/// }
19///
20/// impl Serialize for Point {
21///     fn serialize<S: Serializer>(&self, ser: &mut S, _pos: &Position) -> SuccessResult {
22///         ser.begin_struct("Point", 3)?;
23///     
24///         ser.serialize_field("x", &self.x, &Position::Trailing)?;
25///         ser.serialize_field("y", &self.y, &Position::Trailing)?;
26///         ser.serialize_field("z", &self.z, &Position::Closing)?;
27///     
28///         ser.end_struct("Point")?;
29///     
30///         Ok(())
31///     }
32/// }
33/// ```
34pub trait Serialize: Sized {
35    fn serialize<S: Serializer>(&self, ser: &mut S, pos: &Position) -> SuccessResult;
36}
37
38macro_rules! impl_serialize_primitive {
39    ($type: ident, $ser_func: ident) => {
40        impl Serialize for $type {
41            fn serialize<S: Serializer>(&self, ser: &mut S, _pos: &Position) -> SuccessResult {
42                ser.$ser_func(self)?;
43
44                Ok(())
45            }
46        }
47    };
48}
49
50impl_serialize_primitive!(i8, serialize_i8);
51impl_serialize_primitive!(i16, serialize_i16);
52impl_serialize_primitive!(i32, serialize_i32);
53impl_serialize_primitive!(i64, serialize_i64);
54impl_serialize_primitive!(i128, serialize_i128);
55impl_serialize_primitive!(u8, serialize_u8);
56impl_serialize_primitive!(u16, serialize_u16);
57impl_serialize_primitive!(u32, serialize_u32);
58impl_serialize_primitive!(u64, serialize_u64);
59impl_serialize_primitive!(u128, serialize_u128);
60impl_serialize_primitive!(f32, serialize_f32);
61impl_serialize_primitive!(f64, serialize_f64);
62impl_serialize_primitive!(usize, serialize_usize);
63impl_serialize_primitive!(isize, serialize_isize);
64impl_serialize_primitive!(String, serialize_str);
65
66impl Serialize for &str {
67    fn serialize<S: Serializer>(&self, ser: &mut S, _pos: &Position) -> SuccessResult {
68        ser.serialize_str(self)
69    }
70}
71
72impl<Item: Serialize> Serialize for Vec<Item> {
73    fn serialize<S: Serializer>(&self, ser: &mut S, _pos: &Position) -> SuccessResult {
74        let len = self.len();
75        ser.begin_collection(stringify!(Vec<Item>), len)?;
76
77        let mut iter = self.iter();
78        let closing_item = iter.next_back();
79        for (i, trailing_item) in iter.enumerate() {
80            ser.serialize_item(i, trailing_item, &Position::Trailing)?;
81        }
82        if closing_item.is_some() {
83            ser.serialize_item(self.len() - 1, closing_item.unwrap(), &Position::Closing)?;
84        }
85
86        ser.end_collection(stringify!(Vec<Item>))?;
87
88        Ok(())
89    }
90}
91
92macro_rules! decl_serialize_primitive {
93    ($type: ident, $ser_func: ident) => {
94        fn $ser_func(&mut self, value: &$type) -> SuccessResult;
95    };
96}
97
98/// Handles the serialization and formatting of an arbitrary serializable
99///
100/// Any Serializer must implement methods that allow for the serialization of all supported data types.
101/// These methods are then called in the implementation (most often derived) of the [Serialize](crate::serialize::Serialize) trait.
102pub trait Serializer {
103    fn begin_struct(&mut self, name: &str, fields: usize) -> SuccessResult;
104    fn end_struct(&mut self, name: &str) -> SuccessResult;
105
106    fn begin_collection(&mut self, name: &str, size: usize) -> SuccessResult;
107    fn end_collection(&mut self, name: &str) -> SuccessResult;
108
109    fn serialize_item<V: Serialize>(&mut self, i: usize, item: &V, pos: &Position)
110        -> SuccessResult;
111
112    fn serialize_field<V: Serialize>(
113        &mut self,
114        identifier: &str,
115        value: &V,
116        pos: &Position,
117    ) -> SuccessResult;
118    fn serialize_value<V: Serialize>(&mut self, value: &V, pos: &Position) -> SuccessResult;
119
120    fn serialize_str(&mut self, value: &str) -> SuccessResult;
121
122    decl_serialize_primitive!(i8, serialize_i8);
123    decl_serialize_primitive!(i16, serialize_i16);
124    decl_serialize_primitive!(i32, serialize_i32);
125    decl_serialize_primitive!(i64, serialize_i64);
126    decl_serialize_primitive!(i128, serialize_i128);
127    decl_serialize_primitive!(u8, serialize_u8);
128    decl_serialize_primitive!(u16, serialize_u16);
129    decl_serialize_primitive!(u32, serialize_u32);
130    decl_serialize_primitive!(u64, serialize_u64);
131    decl_serialize_primitive!(u128, serialize_u128);
132    decl_serialize_primitive!(f32, serialize_f32);
133    decl_serialize_primitive!(f64, serialize_f64);
134    decl_serialize_primitive!(usize, serialize_usize);
135    decl_serialize_primitive!(isize, serialize_isize);
136}