1 // Take a look at the license at the top of the repository in the LICENSE file.
2 
3 use serde::de;
4 use serde::de::{Deserialize, Deserializer, EnumAccess, SeqAccess, VariantAccess, Visitor};
5 use serde::ser::{Serialize, SerializeSeq, SerializeTuple, Serializer};
6 
7 use std::fmt;
8 
9 use crate::Caps;
10 use crate::CapsFeatures;
11 use crate::CapsFeaturesRef;
12 use crate::CapsRef;
13 use crate::Structure;
14 use crate::StructureRef;
15 
16 enum CapsVariantKinds {
17     Any,
18     Empty,
19     Some,
20 }
21 
22 const CAPS_VARIANT_ANY_ID: u32 = 0;
23 const CAPS_VARIANT_ANY_STR: &str = "Any";
24 const CAPS_VARIANT_EMPTY_ID: u32 = 1;
25 const CAPS_VARIANT_EMPTY_STR: &str = "Empty";
26 const CAPS_VARIANT_SOME_ID: u32 = 2;
27 const CAPS_VARIANT_SOME_STR: &str = "Some";
28 
29 const CAPS_VARIANT_NAMES: &[&str] = &[
30     CAPS_VARIANT_ANY_STR,
31     CAPS_VARIANT_EMPTY_STR,
32     CAPS_VARIANT_SOME_STR,
33 ];
34 
35 struct CapsItemSe<'a>(&'a StructureRef, Option<&'a CapsFeaturesRef>);
36 impl<'a> Serialize for CapsItemSe<'a> {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>37     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
38         let mut tup = serializer.serialize_tuple(2)?;
39         tup.serialize_element(self.0)?;
40         tup.serialize_element(&self.1)?;
41         tup.end()
42     }
43 }
44 
45 struct CapsForIterSe<'a>(&'a CapsRef);
46 impl<'a> Serialize for CapsForIterSe<'a> {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>47     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
48         let iter = self.0.iter_with_features();
49         let size = iter.size_hint().0;
50         if size > 0 {
51             let mut seq = serializer.serialize_seq(Some(size))?;
52             for (structure, features) in iter {
53                 let features = if !features.is_any()
54                     && features.is_equal(crate::CAPS_FEATURES_MEMORY_SYSTEM_MEMORY.as_ref())
55                 {
56                     None
57                 } else {
58                     Some(features)
59                 };
60                 seq.serialize_element(&CapsItemSe(structure, features))?;
61             }
62             seq.end()
63         } else {
64             let seq = serializer.serialize_seq(None)?;
65             seq.end()
66         }
67     }
68 }
69 
70 impl Serialize for CapsRef {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>71     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
72         if self.is_any() {
73             serializer.serialize_unit_variant(
74                 stringify!(Caps),
75                 CAPS_VARIANT_ANY_ID,
76                 CAPS_VARIANT_ANY_STR,
77             )
78         } else if self.is_empty() {
79             serializer.serialize_unit_variant(
80                 stringify!(Caps),
81                 CAPS_VARIANT_EMPTY_ID,
82                 CAPS_VARIANT_EMPTY_STR,
83             )
84         } else {
85             serializer.serialize_newtype_variant(
86                 stringify!(Caps),
87                 CAPS_VARIANT_SOME_ID,
88                 CAPS_VARIANT_SOME_STR,
89                 &CapsForIterSe(self),
90             )
91         }
92     }
93 }
94 
95 impl Serialize for Caps {
serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>96     fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
97         <CapsRef as Serialize>::serialize(self.as_ref(), serializer)
98     }
99 }
100 
101 struct CapsItemDe(Structure, Option<CapsFeatures>);
102 
103 struct CapsItemVisitor;
104 impl<'de> Visitor<'de> for CapsItemVisitor {
105     type Value = CapsItemDe;
106 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result107     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
108         formatter.write_str("a tuple `(Structure, Option<CapsFeature>)`")
109     }
110 
visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error>111     fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
112         let structure = seq
113             .next_element::<Structure>()?
114             .ok_or_else(|| de::Error::custom("Expected a `Structure` for `Caps` item"))?;
115         let features_option = seq.next_element::<Option<CapsFeatures>>()?.ok_or_else(|| {
116             de::Error::custom("Expected an `Option<CapsFeature>` for `Caps` item")
117         })?;
118 
119         Ok(CapsItemDe(structure, features_option))
120     }
121 }
122 
123 impl<'de> Deserialize<'de> for CapsItemDe {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsItemDe, D::Error>124     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsItemDe, D::Error> {
125         skip_assert_initialized!();
126         deserializer.deserialize_tuple(2, CapsItemVisitor)
127     }
128 }
129 
130 struct CapsSome(Caps);
131 
132 struct CapsSomeVisitor;
133 impl<'de> Visitor<'de> for CapsSomeVisitor {
134     type Value = CapsSome;
135 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result136     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
137         formatter.write_str("a sequence of `(Structure, Option<CapsFeature>)`")
138     }
139 
visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error>140     fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
141         let mut caps = Caps::new_empty();
142         {
143             let caps = caps.get_mut().unwrap();
144             while let Some(caps_item) = seq.next_element::<CapsItemDe>()? {
145                 caps.append_structure_full(caps_item.0, caps_item.1);
146             }
147         }
148         Ok(CapsSome(caps))
149     }
150 }
151 
152 impl<'de> Deserialize<'de> for CapsSome {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsSome, D::Error>153     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsSome, D::Error> {
154         skip_assert_initialized!();
155         deserializer.deserialize_seq(CapsSomeVisitor)
156     }
157 }
158 
159 struct CapsVariantKindsVisitor;
160 impl<'de> Visitor<'de> for CapsVariantKindsVisitor {
161     type Value = CapsVariantKinds;
162 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result163     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
164         formatter.write_str("a Caps variant kind (`Any`, `None` or `Some`)")
165     }
166 
visit_u32<E: de::Error>(self, value: u32) -> Result<Self::Value, E>167     fn visit_u32<E: de::Error>(self, value: u32) -> Result<Self::Value, E> {
168         match value {
169             CAPS_VARIANT_ANY_ID => Ok(CapsVariantKinds::Any),
170             CAPS_VARIANT_EMPTY_ID => Ok(CapsVariantKinds::Empty),
171             CAPS_VARIANT_SOME_ID => Ok(CapsVariantKinds::Some),
172             _ => Err(de::Error::invalid_value(
173                 de::Unexpected::Unsigned(u64::from(value)),
174                 &self,
175             )),
176         }
177     }
178 
visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E>179     fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
180         match value {
181             CAPS_VARIANT_ANY_STR => Ok(CapsVariantKinds::Any),
182             CAPS_VARIANT_EMPTY_STR => Ok(CapsVariantKinds::Empty),
183             CAPS_VARIANT_SOME_STR => Ok(CapsVariantKinds::Some),
184             _ => Err(de::Error::unknown_variant(value, CAPS_VARIANT_NAMES)),
185         }
186     }
187 }
188 
189 impl<'de> Deserialize<'de> for CapsVariantKinds {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>190     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
191         skip_assert_initialized!();
192         deserializer.deserialize_identifier(CapsVariantKindsVisitor)
193     }
194 }
195 
196 struct CapsVisitor;
197 impl<'de> Visitor<'de> for CapsVisitor {
198     type Value = Caps;
199 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result200     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
201         formatter.write_str("a Caps enum (`Any`, `None` or `Some()`)")
202     }
203 
visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error>204     fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
205         let res = match data.variant()? {
206             (CapsVariantKinds::Any, _v) => Caps::new_any(),
207             (CapsVariantKinds::Empty, _v) => Caps::new_empty(),
208             (CapsVariantKinds::Some, v) => v
209                 .newtype_variant::<CapsSome>()
210                 .map(|caps_some| caps_some.0)?,
211         };
212 
213         Ok(res)
214     }
215 }
216 
217 impl<'de> Deserialize<'de> for Caps {
deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>218     fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
219         skip_assert_initialized!();
220         deserializer.deserialize_enum(stringify!(Caps), CAPS_VARIANT_NAMES, CapsVisitor)
221     }
222 }
223 
224 #[cfg(test)]
225 mod tests {
226     use crate::Array;
227     use crate::Caps;
228     use crate::CapsFeatures;
229     use crate::Fraction;
230 
231     #[test]
test_serialize()232     fn test_serialize() {
233         crate::init().unwrap();
234 
235         let caps = Caps::builder("foo/bar")
236             .field("int", 12)
237             .field("bool", true)
238             .field("string", "bla")
239             .field("fraction", Fraction::new(1, 2))
240             .field("array", Array::new(&[&1, &2]))
241             .build();
242 
243         let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string());
244 
245         let res = ron::ser::to_string_pretty(&caps, pretty_config);
246         assert_eq!(
247             Ok(concat!(
248                 "Some([",
249                 "    ((\"foo/bar\", [",
250                 "        (\"int\", \"i32\", 12),",
251                 "        (\"bool\", \"bool\", true),",
252                 "        (\"string\", \"String\", Some(\"bla\")),",
253                 "        (\"fraction\", \"Fraction\", (1, 2)),",
254                 "        (\"array\", \"Array\", [",
255                 "            (\"i32\", 1),",
256                 "            (\"i32\", 2),",
257                 "        ]),",
258                 "    ]), None),",
259                 "])"
260             )
261             .to_owned()),
262             res,
263         );
264 
265         let caps = Caps::builder("foo/bar")
266             .field("int", 12)
267             .field("bool", true)
268             .field("string", "bla")
269             .field("fraction", Fraction::new(1, 2))
270             .field("array", Array::new(&[&1, &2]))
271             .features(&["foo:bar", "foo:baz"])
272             .build();
273 
274         let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string());
275 
276         let res = ron::ser::to_string_pretty(&caps, pretty_config);
277         assert_eq!(
278             Ok(concat!(
279                 "Some([",
280                 "    ((\"foo/bar\", [",
281                 "        (\"int\", \"i32\", 12),",
282                 "        (\"bool\", \"bool\", true),",
283                 "        (\"string\", \"String\", Some(\"bla\")),",
284                 "        (\"fraction\", \"Fraction\", (1, 2)),",
285                 "        (\"array\", \"Array\", [",
286                 "            (\"i32\", 1),",
287                 "            (\"i32\", 2),",
288                 "        ]),",
289                 "    ]), Some(Some([",
290                 "        \"foo:bar\",",
291                 "        \"foo:baz\",",
292                 "    ]))),",
293                 "])"
294             )
295             .to_owned()),
296             res,
297         );
298 
299         let caps = Caps::builder("foo/bar")
300             .field("int", 12)
301             .field("bool", true)
302             .field("string", "bla")
303             .field("fraction", Fraction::new(1, 2))
304             .field("array", Array::new(&[&1, &2]))
305             .any_features()
306             .build();
307 
308         let pretty_config = ron::ser::PrettyConfig::new().with_new_line("".to_string());
309 
310         let res = ron::ser::to_string_pretty(&caps, pretty_config.clone());
311         assert_eq!(
312             Ok(concat!(
313                 "Some([",
314                 "    ((\"foo/bar\", [",
315                 "        (\"int\", \"i32\", 12),",
316                 "        (\"bool\", \"bool\", true),",
317                 "        (\"string\", \"String\", Some(\"bla\")),",
318                 "        (\"fraction\", \"Fraction\", (1, 2)),",
319                 "        (\"array\", \"Array\", [",
320                 "            (\"i32\", 1),",
321                 "            (\"i32\", 2),",
322                 "        ]),",
323                 "    ]), Some(Any)),",
324                 "])"
325             )
326             .to_owned()),
327             res,
328         );
329 
330         let caps_any = Caps::new_any();
331         let res = ron::ser::to_string_pretty(&caps_any, pretty_config.clone());
332         assert_eq!(Ok("Any".to_owned()), res);
333 
334         let caps_empty = Caps::new_empty();
335         let res = ron::ser::to_string_pretty(&caps_empty, pretty_config);
336         assert_eq!(Ok("Empty".to_owned()), res);
337     }
338 
339     #[test]
test_deserialize()340     fn test_deserialize() {
341         use crate::Structure;
342 
343         crate::init().unwrap();
344 
345         let caps_ron = "Any";
346         let caps: Caps = ron::de::from_str(caps_ron).unwrap();
347         assert!(caps.is_any());
348 
349         let caps_ron = "Empty";
350         let caps: Caps = ron::de::from_str(caps_ron).unwrap();
351         assert!(caps.is_empty());
352 
353         let caps_ron = r#"
354             Some([
355                 (
356                     ("foo/bar", [
357                         ("int", "i32", 12),
358                         ("bool", "bool", true),
359                         ("string", "String", Some("bla")),
360                         ("fraction", "Fraction", (1, 2)),
361                         ("array", "Array", [
362                             ("i32", 1),
363                             ("i32", 2),
364                         ]),
365                     ]),
366                     None,
367                 ),
368             ])"#;
369         let caps: Caps = ron::de::from_str(caps_ron).unwrap();
370         let s = caps.structure(0).unwrap();
371         assert_eq!(
372             s,
373             Structure::builder("foo/bar",)
374                 .field("int", 12)
375                 .field("bool", true)
376                 .field("string", "bla")
377                 .field("fraction", Fraction::new(1, 2))
378                 .field("array", Array::new(&[&1, &2]))
379                 .build()
380                 .as_ref()
381         );
382 
383         let caps_ron = r#"
384             Some([
385                 (
386                     ("foo/bar", [
387                         ("int", "i32", 12),
388                         ("bool", "bool", true),
389                         ("string", "String", None),
390                         ("fraction", "Fraction", (1, 2)),
391                         ("array", "Array", [
392                             ("i32", 1),
393                             ("i32", 2),
394                         ]),
395                     ]),
396                     Some(Some(["foo:bar", "foo:baz"])),
397                 ),
398             ])"#;
399         let caps: Caps = ron::de::from_str(caps_ron).unwrap();
400         let s = caps.structure(0).unwrap();
401         let str_none: Option<&str> = None;
402         assert_eq!(
403             s,
404             Structure::builder("foo/bar",)
405                 .field("int", 12)
406                 .field("bool", true)
407                 .field("string", str_none)
408                 .field("fraction", Fraction::new(1, 2))
409                 .field("array", Array::new(&[&1, &2]))
410                 .build()
411                 .as_ref()
412         );
413         let f = caps.features(0).unwrap();
414         assert!(f.is_equal(CapsFeatures::new(&["foo:bar", "foo:baz"]).as_ref()));
415 
416         let caps_ron = r#"
417             Some([
418                 (
419                     ("foo/bar", [
420                         ("int", "i32", 12),
421                         ("bool", "bool", true),
422                         ("string", "String", Some("bla")),
423                         ("fraction", "Fraction", (1, 2)),
424                         ("array", "Array", [
425                             ("i32", 1),
426                             ("i32", 2),
427                         ]),
428                     ]),
429                     Some(Any),
430                 ),
431             ])"#;
432         let caps: Caps = ron::de::from_str(caps_ron).unwrap();
433         let s = caps.structure(0).unwrap();
434         assert_eq!(
435             s,
436             Structure::builder("foo/bar",)
437                 .field("int", 12)
438                 .field("bool", true)
439                 .field("string", "bla")
440                 .field("fraction", Fraction::new(1, 2))
441                 .field("array", Array::new(&[&1, &2]))
442                 .build()
443                 .as_ref()
444         );
445         let f = caps.features(0).unwrap();
446         assert!(f.is_any());
447     }
448 
449     #[test]
test_serde_roundtrip()450     fn test_serde_roundtrip() {
451         crate::init().unwrap();
452 
453         let caps = Caps::new_any();
454         let caps_ser = ron::ser::to_string(&caps).unwrap();
455         let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap();
456         assert!(caps_de.is_any());
457 
458         let caps = Caps::new_empty();
459         let caps_ser = ron::ser::to_string(&caps).unwrap();
460         let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap();
461         assert!(caps_de.is_empty());
462 
463         let caps = Caps::builder("foo/bar")
464             .field("int", 12)
465             .field("bool", true)
466             .field("string", "bla")
467             .field("fraction", Fraction::new(1, 2))
468             .field("array", Array::new(&[&1, &2]))
469             .build();
470         let caps_ser = ron::ser::to_string(&caps).unwrap();
471         let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap();
472         assert!(caps_de.is_strictly_equal(&caps));
473 
474         let caps = Caps::builder("foo/bar")
475             .field("int", 12)
476             .field("bool", true)
477             .field("string", "bla")
478             .field("fraction", Fraction::new(1, 2))
479             .field("array", Array::new(&[&1, &2]))
480             .features(&["foo:bar", "foo:baz"])
481             .build();
482         let caps_ser = ron::ser::to_string(&caps).unwrap();
483         let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap();
484         assert!(caps_de.is_strictly_equal(&caps));
485 
486         let caps = Caps::builder("foo/bar")
487             .field("int", 12)
488             .field("bool", true)
489             .field("string", "bla")
490             .field("fraction", Fraction::new(1, 2))
491             .field("array", Array::new(&[&1, &2]))
492             .any_features()
493             .build();
494         let caps_ser = ron::ser::to_string(&caps).unwrap();
495         let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap();
496         assert!(caps_de.is_strictly_equal(&caps));
497     }
498 }
499