lib_contra/
lib.rs

1//! Function implementation for [contra](https://docs.rs/contra)
2//!
3//! Provides the function and traits needed for the serialization and deserialization of any arbitrary object.
4
5pub mod deserialize;
6pub mod error;
7pub mod formatter;
8pub mod persistent;
9pub mod position;
10pub mod serialize;
11
12#[cfg(test)]
13mod test {
14    use crate::{
15        deserialize::{json::FromJson, Deserialize, Visitor},
16        error::SuccessResult,
17        position::Position,
18        serialize::{json::IntoJson, Serialize, Serializer},
19    };
20
21    #[derive(Debug, PartialEq)]
22    struct PrimitiveDataTypesStruct {
23        i8: i32,
24        i16: i16,
25        i32: i32,
26        i64: i64,
27        i128: i128,
28        u8: u32,
29        u16: u16,
30        u32: u32,
31        u64: u64,
32        u128: u128,
33        usize: usize,
34        isize: isize,
35        string: String,
36        f32: f32,
37        f64: f64,
38    }
39
40    impl PrimitiveDataTypesStruct {
41        fn new() -> Self {
42            PrimitiveDataTypesStruct {
43                i8: 1000,
44                i16: i16::MAX,
45                i32: i32::MAX,
46                i64: i64::MAX,
47                i128: i128::MAX,
48                u8: 1000,
49                u16: u16::MAX,
50                u32: u32::MAX,
51                u64: u64::MAX,
52                u128: u128::MAX,
53                f32: f32::MAX,
54                f64: f64::MAX,
55                usize: usize::MAX,
56                isize: isize::MAX,
57                string: "Hello World!".to_string(),
58            }
59        }
60    }
61
62    impl Serialize for PrimitiveDataTypesStruct {
63        fn serialize<S: Serializer>(&self, ser: &mut S, _pos: &Position) -> SuccessResult {
64            ser.begin_struct("PrimitiveDataTypesStruct", 15)?;
65
66            ser.serialize_field("i8", &self.i8, &Position::Trailing)?;
67            ser.serialize_field("i16", &self.i16, &Position::Trailing)?;
68            ser.serialize_field("i32", &self.i32, &Position::Trailing)?;
69            ser.serialize_field("i64", &self.i64, &Position::Trailing)?;
70            ser.serialize_field("i128", &self.i128, &Position::Trailing)?;
71            ser.serialize_field("u8", &self.u8, &Position::Trailing)?;
72            ser.serialize_field("u16", &self.u16, &Position::Trailing)?;
73            ser.serialize_field("u32", &self.u32, &Position::Trailing)?;
74            ser.serialize_field("u64", &self.u64, &Position::Trailing)?;
75            ser.serialize_field("u128", &self.u128, &Position::Trailing)?;
76            ser.serialize_field("f32", &self.f32, &Position::Trailing)?;
77            ser.serialize_field("f64", &self.f64, &Position::Trailing)?;
78            ser.serialize_field("usize", &self.usize, &Position::Trailing)?;
79            ser.serialize_field("isize", &self.isize, &Position::Trailing)?;
80            ser.serialize_field("string", &self.string, &Position::Closing)?;
81
82            ser.end_struct("PrimitiveDataTypesStruct")?;
83
84            Ok(())
85        }
86    }
87
88    impl Deserialize for PrimitiveDataTypesStruct {
89        fn deserialize<D: crate::deserialize::Deserializer>(
90            de: D,
91        ) -> Result<Self, crate::error::AnyError> {
92            enum Field {
93                I8,
94                I16,
95                I32,
96                I64,
97                I128,
98                U8,
99                U16,
100                U32,
101                U64,
102                U128,
103                F32,
104                F64,
105                Usize,
106                Isize,
107                String,
108            }
109            impl Deserialize for Field {
110                fn deserialize<D: crate::deserialize::Deserializer>(
111                    de: D,
112                ) -> Result<Self, crate::error::AnyError> {
113                    struct FieldVisitor {}
114                    impl Visitor for FieldVisitor {
115                        type Value = Field;
116
117                        fn expected_a(self) -> String {
118                            "PrimitiveDataTypesStruct field".to_string()
119                        }
120
121                        fn visit_str(self, v: &str) -> Result<Self::Value, crate::error::AnyError> {
122                            match v {
123                                "i8" => Ok(Field::I8),
124                                "i16" => Ok(Field::I16),
125                                "i32" => Ok(Field::I32),
126                                "i64" => Ok(Field::I64),
127                                "i128" => Ok(Field::I128),
128                                "u8" => Ok(Field::U8),
129                                "u16" => Ok(Field::U16),
130                                "u32" => Ok(Field::U32),
131                                "u64" => Ok(Field::U64),
132                                "u128" => Ok(Field::U128),
133                                "f32" => Ok(Field::F32),
134                                "f64" => Ok(Field::F64),
135                                "usize" => Ok(Field::Usize),
136                                "isize" => Ok(Field::Isize),
137                                "string" => Ok(Field::String),
138                                val => Err(format!("unknown field {}", val).into()),
139                            }
140                        }
141                    }
142                    de.deserialize_str(FieldVisitor {})
143                }
144            }
145
146            struct PrimitiveDataTypesStructVisitor {}
147            impl Visitor for PrimitiveDataTypesStructVisitor {
148                type Value = PrimitiveDataTypesStruct;
149
150                fn expected_a(self) -> String {
151                    "PrimitiveDataTypesStruct".to_string()
152                }
153
154                fn visit_map<M: crate::deserialize::MapAccess>(
155                    self,
156                    mut map: M,
157                ) -> Result<Self::Value, crate::error::AnyError> {
158                    let mut i8 = None;
159                    let mut i16 = None;
160                    let mut i32 = None;
161                    let mut i64 = None;
162                    let mut i128 = None;
163                    let mut u8 = None;
164                    let mut u16 = None;
165                    let mut u32 = None;
166                    let mut u64 = None;
167                    let mut u128 = None;
168                    let mut f32 = None;
169                    let mut f64 = None;
170                    let mut usize = None;
171                    let mut isize = None;
172                    let mut string = None;
173
174                    while let Some(key) = map.next_key()? {
175                        match key {
176                            Field::I8 => {
177                                if i8.is_some() {
178                                    return Err("duplicate field i8".into());
179                                }
180                                i8 = Some(map.next_value()?)
181                            }
182                            Field::I16 => {
183                                if i16.is_some() {
184                                    return Err("duplicate field i16".into());
185                                }
186                                i16 = Some(map.next_value()?)
187                            }
188                            Field::I32 => {
189                                if i32.is_some() {
190                                    return Err("duplicate field i32".into());
191                                }
192                                i32 = Some(map.next_value()?)
193                            }
194                            Field::I64 => {
195                                if i64.is_some() {
196                                    return Err("duplicate field i64".into());
197                                }
198                                i64 = Some(map.next_value()?)
199                            }
200                            Field::I128 => {
201                                if i128.is_some() {
202                                    return Err("duplicate field i128".into());
203                                }
204                                i128 = Some(map.next_value()?)
205                            }
206                            Field::U8 => {
207                                if u8.is_some() {
208                                    return Err("duplicate field u8".into());
209                                }
210                                u8 = Some(map.next_value()?)
211                            }
212                            Field::U16 => {
213                                if u16.is_some() {
214                                    return Err("duplicate field u16".into());
215                                }
216                                u16 = Some(map.next_value()?)
217                            }
218                            Field::U32 => {
219                                if u32.is_some() {
220                                    return Err("duplicate field u32".into());
221                                }
222                                u32 = Some(map.next_value()?)
223                            }
224                            Field::U64 => {
225                                if u64.is_some() {
226                                    return Err("duplicate field u64".into());
227                                }
228                                u64 = Some(map.next_value()?)
229                            }
230                            Field::U128 => {
231                                if u128.is_some() {
232                                    return Err("duplicate field u128".into());
233                                }
234                                u128 = Some(map.next_value()?)
235                            }
236                            Field::F32 => {
237                                if f32.is_some() {
238                                    return Err("duplicate field f32".into());
239                                }
240                                f32 = Some(map.next_value()?)
241                            }
242                            Field::F64 => {
243                                if f64.is_some() {
244                                    return Err("duplicate field f64".into());
245                                }
246                                f64 = Some(map.next_value()?)
247                            }
248                            Field::Usize => {
249                                if usize.is_some() {
250                                    return Err("duplicate field usize".into());
251                                }
252                                usize = Some(map.next_value()?)
253                            }
254                            Field::Isize => {
255                                if isize.is_some() {
256                                    return Err("duplicate field isize".into());
257                                }
258                                isize = Some(map.next_value()?)
259                            }
260                            Field::String => {
261                                if string.is_some() {
262                                    return Err("duplicate field string".into());
263                                }
264                                string = Some(map.next_value()?)
265                            }
266                        }
267                    }
268
269                    let i8 = i8.ok_or_else(|| "missing field i8")?;
270                    let i16 = i16.ok_or_else(|| "missing field i16")?;
271                    let i32 = i32.ok_or_else(|| "missing field i32")?;
272                    let i64 = i64.ok_or_else(|| "missing field i64")?;
273                    let i128 = i128.ok_or_else(|| "missing field i128")?;
274                    let u8 = u8.ok_or_else(|| "missing field u8")?;
275                    let u16 = u16.ok_or_else(|| "missing field u16")?;
276                    let u32 = u32.ok_or_else(|| "missing field u32")?;
277                    let u64 = u64.ok_or_else(|| "missing field u64")?;
278                    let u128 = u128.ok_or_else(|| "missing field u128")?;
279                    let f32 = f32.ok_or_else(|| "missing field f32")?;
280                    let f64 = f64.ok_or_else(|| "missing field f64")?;
281                    let usize = usize.ok_or_else(|| "missing field usize")?;
282                    let isize = isize.ok_or_else(|| "missing field isize")?;
283                    let string = string.ok_or_else(|| "missing field string")?;
284
285                    Ok(PrimitiveDataTypesStruct {
286                        i8: i8,
287                        i16: i16,
288                        i32: i32,
289                        i64: i64,
290                        i128: i128,
291                        u8: u8,
292                        u16: u16,
293                        u32: u32,
294                        u64: u64,
295                        u128: u128,
296                        f32: f32,
297                        f64: f64,
298                        usize: usize,
299                        isize: isize,
300                        string: string,
301                    })
302                }
303            }
304
305            de.deserialize_map(PrimitiveDataTypesStructVisitor {})
306        }
307    }
308
309    #[test]
310    fn reconstruction_of_struct_works() {
311        let obj = PrimitiveDataTypesStruct::new();
312        let json = IntoJson::to_json(&obj);
313        dbg!(&json);
314        assert!(json.is_ok());
315        let result = FromJson::from_json(&json.unwrap());
316        dbg!(&result);
317        assert!(result.is_ok());
318        assert_eq!(obj, result.unwrap());
319    }
320}