gstreamer: Implement IntoIterator / FromIterator for Buffer, BufferList, Caps, CapsFeatures, StreamCollection and Structure

Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/issues/285
This commit is contained in:
Sebastian Dröge 2021-10-16 23:13:31 +03:00
parent 219616ced0
commit 3670076f07
6 changed files with 175 additions and 31 deletions

View file

@ -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!( define_iter!(
IterOwned, IterOwned,
&'a BufferRef, &'a BufferRef,

View file

@ -272,6 +272,48 @@ define_iter!(IterOwned, Buffer, |list: &BufferListRef, idx| {
list.get_owned(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<T: IntoIterator<Item = &'a BufferRef>>(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<Buffer> for BufferList {
fn from_iter<T: IntoIterator<Item = Buffer>>(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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -57,32 +57,6 @@ impl Caps {
caps caps
} }
#[allow(clippy::should_implement_trait)]
pub fn from_iter<'a>(iter: impl IntoIterator<Item = &'a StructureRef>) -> 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<Item = (&'a StructureRef, &'b CapsFeaturesRef)>,
) -> 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")] #[doc(alias = "gst_caps_fixate")]
pub fn fixate(&mut self) { pub fn fixate(&mut self) {
skip_assert_initialized!(); skip_assert_initialized!();
@ -170,6 +144,65 @@ impl str::FromStr for Caps {
} }
} }
impl<'a> std::iter::FromIterator<&'a StructureRef> for Caps {
fn from_iter<T: IntoIterator<Item = &'a StructureRef>>(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<Structure> for Caps {
fn from_iter<T: IntoIterator<Item = Structure>>(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<T: IntoIterator<Item = (&'a StructureRef, &'b CapsFeaturesRef)>>(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<T: IntoIterator<Item = (Structure, CapsFeatures)>>(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 { impl CapsRef {
pub fn set_simple(&mut self, values: &[(&str, &(dyn ToSendValue + Sync))]) { pub fn set_simple(&mut self, values: &[(&str, &(dyn ToSendValue + Sync))]) {
for &(name, value) in values { 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 { impl fmt::Debug for Caps {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<CapsRef as fmt::Debug>::fmt(self, f) <CapsRef as fmt::Debug>::fmt(self, f)
@ -927,13 +978,16 @@ mod tests {
.structure(Structure::builder("video/x-raw").build()) .structure(Structure::builder("video/x-raw").build())
.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::<Caps>();
assert_eq!(audio.to_string(), "audio/x-raw"); assert_eq!(audio.to_string(), "audio/x-raw");
let audio = Caps::from_iter_with_features( let audio = caps
caps.iter_with_features() .iter_with_features()
.filter(|(s, _)| s.name() == "audio/x-raw"), .filter(|(s, _)| s.name() == "audio/x-raw")
); .collect::<Caps>();
assert_eq!(audio.to_string(), "audio/x-raw(ANY)"); assert_eq!(audio.to_string(), "audio/x-raw(ANY)");
} }
} }

View file

@ -520,6 +520,27 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
impl<'a> ExactSizeIterator 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<T: IntoIterator<Item = &'a str>>(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 { impl fmt::Debug for CapsFeaturesRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("CapsFeatures") f.debug_tuple("CapsFeatures")

View file

@ -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); pub struct Debug<'a>(&'a StreamCollection);
impl<'a> fmt::Debug for Debug<'a> { impl<'a> fmt::Debug for Debug<'a> {

View file

@ -835,6 +835,15 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
impl<'a> ExactSizeIterator 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)] #[derive(Debug)]
pub struct Builder { pub struct Builder {
s: Structure, s: Structure,