From 3670076f07d1d29b6525097d3fdd32c57f7cb310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 16 Oct 2021 23:13:31 +0300 Subject: [PATCH] gstreamer: Implement IntoIterator / FromIterator for Buffer, BufferList, Caps, CapsFeatures, StreamCollection and Structure Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/285 --- gstreamer/src/buffer.rs | 9 +++ gstreamer/src/bufferlist.rs | 42 +++++++++++ gstreamer/src/caps.rs | 116 +++++++++++++++++++++-------- gstreamer/src/caps_features.rs | 21 ++++++ gstreamer/src/stream_collection.rs | 9 +++ gstreamer/src/structure.rs | 9 +++ 6 files changed, 175 insertions(+), 31 deletions(-) diff --git a/gstreamer/src/buffer.rs b/gstreamer/src/buffer.rs index 80d89ac2a..85e936447 100644 --- a/gstreamer/src/buffer.rs +++ b/gstreamer/src/buffer.rs @@ -903,6 +903,15 @@ define_iter!( } ); +impl<'a> IntoIterator for &'a BufferRef { + type IntoIter = Iter<'a>; + type Item = &'a MemoryRef; + + fn into_iter(self) -> Self::IntoIter { + self.iter_memories() + } +} + define_iter!( IterOwned, &'a BufferRef, diff --git a/gstreamer/src/bufferlist.rs b/gstreamer/src/bufferlist.rs index 41d86a742..73d778b58 100644 --- a/gstreamer/src/bufferlist.rs +++ b/gstreamer/src/bufferlist.rs @@ -272,6 +272,48 @@ define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| { list.get_owned(idx) }); +impl<'a> IntoIterator for &'a BufferListRef { + type IntoIter = Iter<'a>; + type Item = &'a BufferRef; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a> std::iter::FromIterator<&'a BufferRef> for BufferList { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + let iter = iter.into_iter(); + + let mut list = BufferList::new_sized(iter.size_hint().0); + + { + let list = list.get_mut().unwrap(); + iter.for_each(|b| list.add(b.to_owned())); + } + + list + } +} + +impl std::iter::FromIterator for BufferList { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + + let iter = iter.into_iter(); + + let mut list = BufferList::new_sized(iter.size_hint().0); + + { + let list = list.get_mut().unwrap(); + iter.for_each(|b| list.add(b)); + } + + list + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/gstreamer/src/caps.rs b/gstreamer/src/caps.rs index f15c11f10..e7bd16e76 100644 --- a/gstreamer/src/caps.rs +++ b/gstreamer/src/caps.rs @@ -57,32 +57,6 @@ impl Caps { caps } - #[allow(clippy::should_implement_trait)] - pub fn from_iter<'a>(iter: impl IntoIterator) -> Self { - assert_initialized_main_thread!(); - let mut caps = Caps::new_empty(); - - iter.into_iter() - .for_each(|s| caps.get_mut().unwrap().append_structure(s.to_owned())); - - caps - } - - pub fn from_iter_with_features<'a, 'b>( - iter: impl IntoIterator, - ) -> Self { - assert_initialized_main_thread!(); - let mut caps = Caps::new_empty(); - - iter.into_iter().for_each(|(s, f)| { - caps.get_mut() - .unwrap() - .append_structure_full(s.to_owned(), Some(f.to_owned())) - }); - - caps - } - #[doc(alias = "gst_caps_fixate")] pub fn fixate(&mut self) { skip_assert_initialized!(); @@ -170,6 +144,65 @@ impl str::FromStr for Caps { } } +impl<'a> std::iter::FromIterator<&'a StructureRef> for Caps { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + let mut caps = Caps::new_empty(); + + { + let caps = caps.get_mut().unwrap(); + iter.into_iter() + .for_each(|s| caps.append_structure(s.to_owned())); + } + + caps + } +} + +impl std::iter::FromIterator for Caps { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + let mut caps = Caps::new_empty(); + + { + let caps = caps.get_mut().unwrap(); + iter.into_iter().for_each(|s| caps.append_structure(s)); + } + + caps + } +} + +impl<'a, 'b> std::iter::FromIterator<(&'a StructureRef, &'b CapsFeaturesRef)> for Caps { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + let mut caps = Caps::new_empty(); + + { + let caps = caps.get_mut().unwrap(); + iter.into_iter() + .for_each(|(s, f)| caps.append_structure_full(s.to_owned(), Some(f.to_owned()))); + } + + caps + } +} + +impl std::iter::FromIterator<(Structure, CapsFeatures)> for Caps { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + let mut caps = Caps::new_empty(); + + { + let caps = caps.get_mut().unwrap(); + iter.into_iter() + .for_each(|(s, f)| caps.append_structure_full(s, Some(f))); + } + + caps + } +} + impl CapsRef { pub fn set_simple(&mut self, values: &[(&str, &(dyn ToSendValue + Sync))]) { for &(name, value) in values { @@ -561,6 +594,24 @@ define_iter!( } ); +impl<'a> IntoIterator for &'a CapsRef { + type IntoIter = IterFeatures<'a>; + type Item = (&'a StructureRef, &'a CapsFeaturesRef); + + fn into_iter(self) -> Self::IntoIter { + self.iter_with_features() + } +} + +impl<'a> IntoIterator for &'a mut CapsRef { + type IntoIter = IterFeaturesMut<'a>; + type Item = (&'a mut StructureRef, &'a mut CapsFeaturesRef); + + fn into_iter(self) -> Self::IntoIter { + self.iter_with_features_mut() + } +} + impl fmt::Debug for Caps { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { ::fmt(self, f) @@ -927,13 +978,16 @@ mod tests { .structure(Structure::builder("video/x-raw").build()) .build(); - let audio = Caps::from_iter(caps.iter().filter(|s| s.name() == "audio/x-raw")); + let audio = caps + .iter() + .filter(|s| s.name() == "audio/x-raw") + .collect::(); assert_eq!(audio.to_string(), "audio/x-raw"); - let audio = Caps::from_iter_with_features( - caps.iter_with_features() - .filter(|(s, _)| s.name() == "audio/x-raw"), - ); + let audio = caps + .iter_with_features() + .filter(|(s, _)| s.name() == "audio/x-raw") + .collect::(); assert_eq!(audio.to_string(), "audio/x-raw(ANY)"); } } diff --git a/gstreamer/src/caps_features.rs b/gstreamer/src/caps_features.rs index 49dcdc655..f776b37d8 100644 --- a/gstreamer/src/caps_features.rs +++ b/gstreamer/src/caps_features.rs @@ -520,6 +520,27 @@ impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> ExactSizeIterator for Iter<'a> {} +impl<'a> IntoIterator for &'a CapsFeaturesRef { + type IntoIter = Iter<'a>; + type Item = &'a str; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'a> std::iter::FromIterator<&'a str> for CapsFeatures { + fn from_iter>(iter: T) -> Self { + assert_initialized_main_thread!(); + + let mut features = CapsFeatures::new_empty(); + + iter.into_iter().for_each(|f| features.add(f)); + + features + } +} + impl fmt::Debug for CapsFeaturesRef { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("CapsFeatures") diff --git a/gstreamer/src/stream_collection.rs b/gstreamer/src/stream_collection.rs index 011be8741..1d2b04655 100644 --- a/gstreamer/src/stream_collection.rs +++ b/gstreamer/src/stream_collection.rs @@ -124,6 +124,15 @@ impl StreamCollection { } } +impl<'a> IntoIterator for &'a StreamCollection { + type IntoIter = Iter<'a>; + type Item = Stream; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + pub struct Debug<'a>(&'a StreamCollection); impl<'a> fmt::Debug for Debug<'a> { diff --git a/gstreamer/src/structure.rs b/gstreamer/src/structure.rs index 1008e32b9..9018f5873 100644 --- a/gstreamer/src/structure.rs +++ b/gstreamer/src/structure.rs @@ -835,6 +835,15 @@ impl<'a> DoubleEndedIterator for Iter<'a> { impl<'a> ExactSizeIterator for Iter<'a> {} +impl<'a> IntoIterator for &'a StructureRef { + type IntoIter = Iter<'a>; + type Item = (&'static str, &'a SendValue); + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + #[derive(Debug)] pub struct Builder { s: Structure,