From 0aac05572750209d7be7c21c38ec601a245e242b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Sun, 22 Jul 2018 15:48:26 +0200 Subject: [PATCH] Caps: serde: use a placeholder for `CapsFeature` `CapsFeature` is not available in `gstreamer-rs` yet. Use a placeholder with a `None` value for now. --- gstreamer/src/caps_serde.rs | 93 ++++++++++++++++++++++++++++------- gstreamer/src/sample_serde.rs | 8 +-- 2 files changed, 79 insertions(+), 22 deletions(-) diff --git a/gstreamer/src/caps_serde.rs b/gstreamer/src/caps_serde.rs index a297b6588..33d6f5583 100644 --- a/gstreamer/src/caps_serde.rs +++ b/gstreamer/src/caps_serde.rs @@ -6,23 +6,38 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use serde::de; use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor}; -use serde::ser::{Serialize, Serializer, SerializeSeq}; +use serde::ser::{Serialize, Serializer, SerializeSeq, SerializeTuple}; use std::fmt; use Caps; use CapsRef; use Structure; +use StructureRef; -impl<'a> Serialize for CapsRef { +// `CapsFeature` is not available in `gstreamer-rs` yet +struct CapsItemSe<'a>(&'a StructureRef); +impl<'a> Serialize for CapsItemSe<'a> { + fn serialize(&self, serializer: S) -> Result { + let mut tup = serializer.serialize_tuple(2)?; + tup.serialize_element(self.0)?; + // `CapsFeature` is not available in `gstreamer-rs` yet + // Fake the type for now and use `None` as a value + tup.serialize_element::>(&None)?; + tup.end() + } +} + +impl Serialize for CapsRef { fn serialize(&self, serializer: S) -> Result { let iter = self.iter(); let size = iter.size_hint().0; if size > 0 { let mut seq = serializer.serialize_seq(Some(size))?; for structure in iter { - seq.serialize_element(structure)?; + seq.serialize_element(&CapsItemSe(structure))?; } seq.end() } else { @@ -32,26 +47,65 @@ impl<'a> Serialize for CapsRef { } } -impl<'a> Serialize for Caps { +impl Serialize for Caps { fn serialize(&self, serializer: S) -> Result { self.as_ref().serialize(serializer) } } +// `CapsFeature` is not available in `gstreamer-rs` yet +struct CapsItemDe(Structure); +impl From for Structure { + fn from(caps_item: CapsItemDe) -> Structure { + caps_item.0 + } +} + +struct CapsItemVisitor; +impl<'de> Visitor<'de> for CapsItemVisitor { + type Value = CapsItemDe; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a tuple `(Structure, Option)`") + } + + fn visit_seq>(self, mut seq: A) -> Result { + let structure = seq.next_element::()? + .ok_or(de::Error::custom("Expected a `Structure` for `Caps` item"))?; + // `CapsFeature` is not available in `gstreamer-rs` yet + // Fake the type for now and expect `None` as a value + let feature_option = seq.next_element::>()? + .ok_or(de::Error::custom("Expected an `Option` for `Caps` item"))?; + if feature_option.is_some() { + Err(de::Error::custom( + "Found a value for `CapsFeature`, expected `None` (not implemented yet)" + )) + } else { + Ok(CapsItemDe(structure)) + } + } +} + +impl<'de> Deserialize<'de> for CapsItemDe { + fn deserialize>(deserializer: D) -> Result { + deserializer.deserialize_tuple(2, CapsItemVisitor) + } +} + struct CapsVisitor; impl<'de> Visitor<'de> for CapsVisitor { type Value = Caps; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a sequence of `Structure`s") + formatter.write_str("a sequence of `(Structure, Option)`") } fn visit_seq>(self, mut seq: A) -> Result { let mut caps = Caps::new_empty(); { let caps = caps.get_mut().unwrap(); - while let Some(structure) = seq.next_element::()? { - caps.append_structure(structure); + while let Some(caps_item) = seq.next_element::()? { + caps.append_structure(caps_item.into()); } } Ok(caps) @@ -92,7 +146,7 @@ mod tests { Ok( concat!( "[", - " (\"foo/bar\", [", + " ((\"foo/bar\", [", " (\"int\", \"i32\", 12),", " (\"bool\", \"bool\", true),", " (\"string\", \"String\", \"bla\"),", @@ -101,7 +155,7 @@ mod tests { " (\"i32\", 1),", " (\"i32\", 2),", " ]),", - " ]),", + " ]), None),", "]" ) .to_owned() @@ -118,16 +172,19 @@ mod tests { let caps_ron = r#" [ - ("foo/bar", [ - ("int", "i32", 12), - ("bool", "bool", true), - ("string", "String", "bla"), - ("fraction", "Fraction", (1, 2)), - ("array", "Array", [ - ("i32", 1), - ("i32", 2), + ( + ("foo/bar", [ + ("int", "i32", 12), + ("bool", "bool", true), + ("string", "String", "bla"), + ("fraction", "Fraction", (1, 2)), + ("array", "Array", [ + ("i32", 1), + ("i32", 2), + ]), ]), - ]), + None, + ), ]"#; let caps: Caps = ron::de::from_str(caps_ron).unwrap(); let s = caps.get_structure(0).unwrap(); diff --git a/gstreamer/src/sample_serde.rs b/gstreamer/src/sample_serde.rs index e92c132d0..e5718a942 100644 --- a/gstreamer/src/sample_serde.rs +++ b/gstreamer/src/sample_serde.rs @@ -152,10 +152,10 @@ mod tests { " )),", " buffer_list: None,", " caps: Some([", - " (\"sample/caps\", [", + " ((\"sample/caps\", [", " (\"int\", \"i32\", 12),", " (\"bool\", \"bool\", true),", - " ]),", + " ]), None),", " ]),", " segment: Some((", " flags: (", @@ -257,10 +257,10 @@ mod tests { )), buffer_list: None, caps: Some([ - ("sample/caps", [ + (("sample/caps", [ ("int", "i32", 12), ("bool", "bool", true), - ]), + ]), None), ]), segment: Some(( flags: (