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