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