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

View file

@ -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<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)]
mod tests {
use super::*;

View file

@ -57,32 +57,6 @@ impl 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")]
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<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 {
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 {
<CapsRef as fmt::Debug>::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::<Caps>();
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::<Caps>();
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> 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 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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);
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> 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,