mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-01-05 00:38:40 +00:00
Implement Iterator::size_hint(), ExactSizeIterator and DoubleEndedIterator for our iterators
This commit is contained in:
parent
deef22cd28
commit
154e996e2d
3 changed files with 126 additions and 33 deletions
|
@ -199,8 +199,41 @@ impl<'a> Iterator for StreamCollectionIterator<'a> {
|
||||||
Stream(gst::gst_object_ref(stream as *mut gst::GstObject) as *mut gst::GstStream)
|
Stream(gst::gst_object_ref(stream as *mut gst::GstObject) as *mut gst::GstStream)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
if self.position == self.length {
|
||||||
|
return (0, Some(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
let remaining = (self.length - self.position) as usize;
|
||||||
|
|
||||||
|
(remaining, Some(remaining))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> DoubleEndedIterator for StreamCollectionIterator<'a> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.position == self.length {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.length -= 1;
|
||||||
|
|
||||||
|
let stream =
|
||||||
|
unsafe { gst::gst_stream_collection_get_stream(self.collection.0, self.length) };
|
||||||
|
if stream.is_null() {
|
||||||
|
self.position = self.length;
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(unsafe {
|
||||||
|
Stream(gst::gst_object_ref(stream as *mut gst::GstObject) as *mut gst::GstStream)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for StreamCollectionIterator<'a> {}
|
||||||
|
|
||||||
impl Clone for StreamCollection {
|
impl Clone for StreamCollection {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -116,6 +116,22 @@ impl Structure {
|
||||||
pub fn iter<'a>(&'a self) -> Iter<'a> {
|
pub fn iter<'a>(&'a self) -> Iter<'a> {
|
||||||
Iter::new(self)
|
Iter::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_nth_field_name<'a>(&'a self, idx: u32) -> Option<&'a str> {
|
||||||
|
unsafe {
|
||||||
|
let field_name = gst::gst_structure_nth_field_name(self.0, idx);
|
||||||
|
if field_name.is_null() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cstr = CStr::from_ptr(field_name);
|
||||||
|
Some(cstr.to_str().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn n_fields(&self) -> u32 {
|
||||||
|
unsafe { gst::gst_structure_n_fields(self.0) as u32 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Structure {
|
impl Clone for Structure {
|
||||||
|
@ -152,7 +168,7 @@ pub struct FieldIterator<'a> {
|
||||||
|
|
||||||
impl<'a> FieldIterator<'a> {
|
impl<'a> FieldIterator<'a> {
|
||||||
pub fn new(structure: &'a Structure) -> FieldIterator<'a> {
|
pub fn new(structure: &'a Structure) -> FieldIterator<'a> {
|
||||||
let n_fields = unsafe { gst::gst_structure_n_fields(structure.0) } as u32;
|
let n_fields = structure.n_fields();
|
||||||
|
|
||||||
FieldIterator {
|
FieldIterator {
|
||||||
structure: structure,
|
structure: structure,
|
||||||
|
@ -170,34 +186,49 @@ impl<'a> Iterator for FieldIterator<'a> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
if let Some(field_name) = self.structure.get_nth_field_name(self.idx) {
|
||||||
let field_name = gst::gst_structure_nth_field_name(self.structure.0, self.idx);
|
self.idx += 1;
|
||||||
if field_name.is_null() {
|
Some(field_name)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
if self.idx == self.n_fields {
|
||||||
|
return (0, Some(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
let remaining = (self.n_fields - self.idx) as usize;
|
||||||
|
|
||||||
|
(remaining, Some(remaining))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DoubleEndedIterator for FieldIterator<'a> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.idx == self.n_fields {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.idx += 1;
|
|
||||||
|
|
||||||
let cstr = CStr::from_ptr(field_name);
|
self.n_fields -= 1;
|
||||||
Some(cstr.to_str().unwrap())
|
if let Some(field_name) = self.structure.get_nth_field_name(self.n_fields) {
|
||||||
|
Some(field_name)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for FieldIterator<'a> {}
|
||||||
|
|
||||||
pub struct Iter<'a> {
|
pub struct Iter<'a> {
|
||||||
structure: &'a Structure,
|
iter: FieldIterator<'a>,
|
||||||
idx: u32,
|
|
||||||
n_fields: u32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iter<'a> {
|
impl<'a> Iter<'a> {
|
||||||
pub fn new(structure: &'a Structure) -> Iter<'a> {
|
pub fn new(structure: &'a Structure) -> Iter<'a> {
|
||||||
let n_fields = unsafe { gst::gst_structure_n_fields(structure.0) } as u32;
|
Iter { iter: FieldIterator::new(structure) }
|
||||||
|
|
||||||
Iter {
|
|
||||||
structure: structure,
|
|
||||||
idx: 0,
|
|
||||||
n_fields: n_fields,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,26 +236,32 @@ impl<'a> Iterator for Iter<'a> {
|
||||||
type Item = (&'a str, ValueRef<'a>);
|
type Item = (&'a str, ValueRef<'a>);
|
||||||
|
|
||||||
fn next(&mut self) -> Option<(&'a str, ValueRef<'a>)> {
|
fn next(&mut self) -> Option<(&'a str, ValueRef<'a>)> {
|
||||||
if self.idx >= self.n_fields {
|
if let Some(f) = self.iter.next() {
|
||||||
return None;
|
let v = self.iter.structure.get_value(f);
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let field_name = gst::gst_structure_nth_field_name(self.structure.0, self.idx);
|
|
||||||
if field_name.is_null() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
self.idx += 1;
|
|
||||||
|
|
||||||
let cstr = CStr::from_ptr(field_name);
|
|
||||||
let f = cstr.to_str().unwrap();
|
|
||||||
let v = self.structure.get_value(f);
|
|
||||||
|
|
||||||
Some((f, v.unwrap()))
|
Some((f, v.unwrap()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
self.iter.size_hint()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DoubleEndedIterator for Iter<'a> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
if let Some(f) = self.iter.next_back() {
|
||||||
|
let v = self.iter.structure.get_value(f);
|
||||||
|
Some((f, v.unwrap()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ExactSizeIterator for Iter<'a> {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -215,8 +215,31 @@ impl<'a, T: Tag<'a>> Iterator for TagIterator<'a, T> {
|
||||||
|
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
if self.idx == self.size {
|
||||||
|
return (0, Some(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
let remaining = (self.size - self.idx) as usize;
|
||||||
|
|
||||||
|
(remaining, Some(remaining))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Tag<'a>> DoubleEndedIterator for TagIterator<'a, T> {
|
||||||
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.idx == self.size {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.size -= 1;
|
||||||
|
self.taglist.get_index::<T>(self.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Tag<'a>> ExactSizeIterator for TagIterator<'a, T> {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Reference in a new issue