Remove std::iter::Iterator impl from gst::Iterator

It does not work well with possibly errors during iteration and
requiring to possibly resync.
This commit is contained in:
Sebastian Dröge 2018-08-13 20:35:28 +03:00
parent 0d70950821
commit a6d9fe4b0a

View file

@ -18,7 +18,6 @@ use gobject_ffi;
use std::error::Error; use std::error::Error;
use std::ffi::CString; use std::ffi::CString;
use std::fmt; use std::fmt;
use std::iter::Iterator as StdIterator;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
@ -59,6 +58,22 @@ impl<T> Iterator<T>
where where
for<'a> T: FromValueOptional<'a> + 'static, for<'a> T: FromValueOptional<'a> + 'static,
{ {
pub fn next(&mut self) -> Result<Option<T>, IteratorError> {
unsafe {
let mut value = Value::uninitialized();
let res = ffi::gst_iterator_next(self.to_glib_none_mut().0, value.to_glib_none_mut().0);
match res {
ffi::GST_ITERATOR_OK => match value.get::<T>() {
Some(value) => Ok(Some(value)),
None => Err(IteratorError::Error),
},
ffi::GST_ITERATOR_DONE => Ok(None),
ffi::GST_ITERATOR_RESYNC => Err(IteratorError::Resync),
ffi::GST_ITERATOR_ERROR | _ => Err(IteratorError::Error),
}
}
}
pub fn resync(&mut self) { pub fn resync(&mut self) {
unsafe { unsafe {
ffi::gst_iterator_resync(self.to_glib_none_mut().0); ffi::gst_iterator_resync(self.to_glib_none_mut().0);
@ -93,7 +108,7 @@ where
} }
} }
pub fn find_simple<F>(&mut self, func: F) -> Option<T> pub fn find<F>(&mut self, func: F) -> Option<T>
where where
F: FnMut(T) -> bool, F: FnMut(T) -> bool,
{ {
@ -141,7 +156,7 @@ where
} }
} }
pub fn fold_with_early_exit<F, U>(&mut self, init: U, func: F) -> Result<U, IteratorError> pub fn fold<F, U>(&mut self, init: U, func: F) -> Result<U, IteratorError>
where where
F: FnMut(U, T) -> Result<U, U>, F: FnMut(U, T) -> Result<U, U>,
{ {
@ -214,29 +229,6 @@ where
} }
} }
impl<T> StdIterator for Iterator<T>
where
for<'a> T: FromValueOptional<'a> + 'static,
{
type Item = Result<T, IteratorError>;
fn next(&mut self) -> Option<Result<T, IteratorError>> {
unsafe {
let mut value = Value::uninitialized();
let res = ffi::gst_iterator_next(self.to_glib_none_mut().0, value.to_glib_none_mut().0);
match res {
ffi::GST_ITERATOR_OK => match value.get::<T>() {
Some(value) => Some(Ok(value)),
None => Some(Err(IteratorError::Error)),
},
ffi::GST_ITERATOR_DONE => None,
ffi::GST_ITERATOR_RESYNC => Some(Err(IteratorError::Resync)),
ffi::GST_ITERATOR_ERROR | _ => Some(Err(IteratorError::Error)),
}
}
}
}
#[repr(C)] #[repr(C)]
struct RsIterator<T, I: IteratorImpl<T>> struct RsIterator<T, I: IteratorImpl<T>>
where where
@ -616,35 +608,19 @@ mod tests {
let vec = vec![1i32, 2, 3]; let vec = vec![1i32, 2, 3];
let mut it = Iterator::from_vec(vec); let mut it = Iterator::from_vec(vec);
let val = it.next().unwrap(); let val = it.next();
assert_eq!(val, Ok(1)); assert_eq!(val, Ok(Some(1)));
let val = it.next().unwrap(); let val = it.next();
assert_eq!(val, Ok(2)); assert_eq!(val, Ok(Some(2)));
let val = it.next().unwrap(); let val = it.next();
assert_eq!(val, Ok(3)); assert_eq!(val, Ok(Some(3)));
assert!(it.next().is_none()); assert_eq!(it.next(), Ok(None));
let vec = vec![1i32, 2, 3];
let it = Iterator::from_vec(vec);
let vals: Vec<_> = it.map(|v| v.unwrap()).collect();
assert_eq!(vals, [1, 2, 3]);
let vec = vec![1i32, 2, 3]; let vec = vec![1i32, 2, 3];
let mut it = Iterator::from_vec(vec); let mut it = Iterator::from_vec(vec);
let mut vals = Vec::new(); let mut vals = Vec::new();
while let Some(res) = it.next() { while let Ok(Some(res)) = it.next() {
match res { vals.push(res);
Ok(v) => vals.push(v),
_ => unreachable!(),
}
}
assert_eq!(vals, [1, 2, 3]);
let vec = vec![1i32, 2, 3];
let it = Iterator::from_vec(vec);
let mut vals = Vec::new();
for v in it {
vals.push(v.unwrap());
} }
assert_eq!(vals, [1, 2, 3]); assert_eq!(vals, [1, 2, 3]);
} }
@ -654,8 +630,12 @@ mod tests {
::init().unwrap(); ::init().unwrap();
let vec = vec![1i32, 2, 3]; let vec = vec![1i32, 2, 3];
let it = Iterator::from_vec(vec).filter(|val| val % 2 == 1); let mut it = Iterator::from_vec(vec).filter(|val| val % 2 == 1);
let vals: Vec<_> = it.map(|v| v.unwrap()).collect();
let mut vals = Vec::new();
while let Ok(Some(res)) = it.next() {
vals.push(res);
}
assert_eq!(vals, [1, 3]); assert_eq!(vals, [1, 3]);
} }
@ -665,13 +645,8 @@ mod tests {
// Our find // Our find
let vec = vec![1i32, 2, 3]; let vec = vec![1i32, 2, 3];
let val = Iterator::from_vec(vec).find_simple(|val| val == 2); let val = Iterator::from_vec(vec).find(|val| val == 2);
assert_eq!(val.unwrap(), 2); assert_eq!(val.unwrap(), 2);
// Find from std::iter::Iterator
let vec = vec![1i32, 2, 3];
let val = Iterator::from_vec(vec).find(|val| val.unwrap() == 2);
assert_eq!(val.unwrap(), Ok(2));
} }
#[test] #[test]
@ -691,18 +666,10 @@ mod tests {
// Our fold // Our fold
let vec = vec![1i32, 2, 3]; let vec = vec![1i32, 2, 3];
let res = Iterator::from_vec(vec).fold_with_early_exit(0, |mut sum, val| { let res = Iterator::from_vec(vec).fold(0, |mut sum, val| {
sum += val; sum += val;
Ok(sum) Ok(sum)
}); });
assert_eq!(res.unwrap(), 6); assert_eq!(res.unwrap(), 6);
// Fold from std::iter::Iterator
let vec = vec![1i32, 2, 3];
let res = Iterator::from_vec(vec).fold(0, |mut sum, val| {
sum += val.unwrap();
sum
});
assert_eq!(res, 6);
} }
} }