mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-01-02 23:38:45 +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)
|
||||
})
|
||||
}
|
||||
|
||||
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 {
|
||||
fn clone(&self) -> Self {
|
||||
unsafe {
|
||||
|
|
|
@ -116,6 +116,22 @@ impl Structure {
|
|||
pub fn iter<'a>(&'a self) -> Iter<'a> {
|
||||
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 {
|
||||
|
@ -152,7 +168,7 @@ pub struct FieldIterator<'a> {
|
|||
|
||||
impl<'a> 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 {
|
||||
structure: structure,
|
||||
|
@ -170,34 +186,49 @@ impl<'a> Iterator for FieldIterator<'a> {
|
|||
return None;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let field_name = gst::gst_structure_nth_field_name(self.structure.0, self.idx);
|
||||
if field_name.is_null() {
|
||||
return None;
|
||||
}
|
||||
if let Some(field_name) = self.structure.get_nth_field_name(self.idx) {
|
||||
self.idx += 1;
|
||||
Some(field_name)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let cstr = CStr::from_ptr(field_name);
|
||||
Some(cstr.to_str().unwrap())
|
||||
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;
|
||||
}
|
||||
|
||||
self.n_fields -= 1;
|
||||
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> {
|
||||
structure: &'a Structure,
|
||||
idx: u32,
|
||||
n_fields: u32,
|
||||
iter: FieldIterator<'a>,
|
||||
}
|
||||
|
||||
impl<'a> Iter<'a> {
|
||||
pub fn new(structure: &'a Structure) -> Iter<'a> {
|
||||
let n_fields = unsafe { gst::gst_structure_n_fields(structure.0) } as u32;
|
||||
|
||||
Iter {
|
||||
structure: structure,
|
||||
idx: 0,
|
||||
n_fields: n_fields,
|
||||
}
|
||||
Iter { iter: FieldIterator::new(structure) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,26 +236,32 @@ impl<'a> Iterator for Iter<'a> {
|
|||
type Item = (&'a str, ValueRef<'a>);
|
||||
|
||||
fn next(&mut self) -> Option<(&'a str, ValueRef<'a>)> {
|
||||
if self.idx >= self.n_fields {
|
||||
return None;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if let Some(f) = self.iter.next() {
|
||||
let v = self.iter.structure.get_value(f);
|
||||
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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -215,8 +215,31 @@ impl<'a, T: Tag<'a>> Iterator for TagIterator<'a, T> {
|
|||
|
||||
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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in a new issue