Skip to main content

sqlite3_ext/
iterator.rs

1//! Provides FallibleIteratorMut and FallibleIterator.
2//!
3//! The FallibleIterator trait is a re-export from [fallible_iterator].
4pub use fallible_iterator::FallibleIterator;
5
6/// Provides a FallibleIterator over mutable references.
7///
8/// Ordinarily a [FallibleIterator] iterates over owned items, which makes this trait
9/// incompatible with it. The [map](Self::map) method allows converting this trait into a
10/// FallibleIterator, and it's also possible to use with a `while let` loop:
11///
12/// ```
13/// use sqlite3_ext::FallibleIteratorMut;
14///
15/// fn dump<I: FallibleIteratorMut>(mut it: I) -> Result<(), I::Error>
16/// where
17///     I::Item: std::fmt::Debug,
18/// {
19///     while let Some(x) = it.next()? {
20///         println!("{:?}", x);
21///     }
22///     Ok(())
23/// }
24/// ```
25pub trait FallibleIteratorMut {
26    /// The type of item being iterated.
27    type Item;
28    /// The type of error that can be returned by this iterator.
29    type Error;
30
31    /// Works like [FallibleIterator::next], except instead of returning `Self::Item`, it
32    /// returns `&mut Self::Item`.
33    fn next(&mut self) -> Result<Option<&mut Self::Item>, Self::Error>;
34
35    /// See [Iterator::size_hint].
36    #[inline]
37    fn size_hint(&self) -> (usize, Option<usize>) {
38        (0, None)
39    }
40
41    /// Convert this iterator into a [FallibleIterator] by applying a function to each
42    /// element.
43    #[inline]
44    fn map<F, B>(&mut self, f: F) -> Map<Self, F>
45    where
46        Self: Sized,
47        F: FnMut(&mut Self::Item) -> Result<B, Self::Error>,
48    {
49        Map { it: self, f }
50    }
51}
52
53pub struct Map<'a, I, F> {
54    it: &'a mut I,
55    f: F,
56}
57
58impl<'a, I, F, B> FallibleIterator for Map<'a, I, F>
59where
60    I: FallibleIteratorMut,
61    F: FnMut(&mut I::Item) -> Result<B, I::Error>,
62{
63    type Item = B;
64    type Error = I::Error;
65
66    #[inline]
67    fn next(&mut self) -> Result<Option<B>, I::Error> {
68        match self.it.next() {
69            Ok(Some(v)) => Ok(Some((self.f)(v)?)),
70            Ok(None) => Ok(None),
71            Err(e) => Err(e),
72        }
73    }
74
75    #[inline]
76    fn size_hint(&self) -> (usize, Option<usize>) {
77        self.it.size_hint()
78    }
79}