possible/
iter.rs

1use super::Possible;
2use core::iter::FusedIterator;
3
4impl<T> Possible<T> {
5    /// Returns an iterator over the possibly contained value.
6    ///
7    /// # Examples
8    ///
9    /// ```
10    /// use possible::Possible;
11    ///
12    /// let x = Possible::Some(4);
13    /// assert_eq!(x.iter().next(), Some(&4));
14    ///
15    /// let x: Possible<u32> = Possible::None;
16    /// assert_eq!(x.iter().next(), None);
17    /// ```
18    #[inline]
19    pub const fn iter(&self) -> Iter<'_, T> {
20        Iter {
21            inner: Item { opt: self.as_ref() },
22        }
23    }
24
25    /// Returns a mutable iterator over the possibly contained value.
26    ///
27    /// # Examples
28    ///
29    /// ```
30    /// use possible::Possible;
31    ///
32    /// let mut x = Possible::Some(4);
33    /// match x.iter_mut().next() {
34    ///     Some(v) => *v = 42,
35    ///     None => {},
36    /// }
37    /// assert_eq!(x, Possible::Some(42));
38    ///
39    /// let mut x: Possible<u32> = Possible::None;
40    /// assert_eq!(x.iter_mut().next(), None);
41    ///
42    /// let mut x: Possible<u32> = Possible::Void;
43    /// assert_eq!(x.iter_mut().next(), None);
44    /// ```
45    #[inline]
46    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
47        IterMut {
48            inner: Item { opt: self.as_mut() },
49        }
50    }
51}
52
53/// An iterator over a reference to the [`Some`] variant of an [`Possible`].
54///
55/// The iterator yields one value if the [`Possible`] is a [`Some`], otherwise none.
56///
57/// This `struct` is created by the [`Possible::iter`] function.
58#[derive(Debug)]
59pub struct Iter<'a, A: 'a> {
60    inner: Item<&'a A>,
61}
62
63impl<'a, A> Iterator for Iter<'a, A> {
64    type Item = &'a A;
65
66    #[inline]
67    fn next(&mut self) -> Option<&'a A> {
68        self.inner.next()
69    }
70
71    #[inline]
72    fn size_hint(&self) -> (usize, Option<usize>) {
73        self.inner.size_hint()
74    }
75}
76
77impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
78    #[inline]
79    fn next_back(&mut self) -> Option<&'a A> {
80        self.inner.next_back()
81    }
82}
83
84impl<A> ExactSizeIterator for Iter<'_, A> {}
85
86impl<A> FusedIterator for Iter<'_, A> {}
87
88impl<A> Clone for Iter<'_, A> {
89    #[inline]
90    fn clone(&self) -> Self {
91        Iter {
92            inner: self.inner.clone(),
93        }
94    }
95}
96
97/// An iterator over a mutable reference to the [`Some`] variant of an [`Possible`].
98///
99/// The iterator yields one value if the [`Possible`] is a [`Some`], otherwise none.
100///
101/// This `struct` is created by the [`Possible::iter_mut`] function.
102#[derive(Debug)]
103pub struct IterMut<'a, A: 'a> {
104    inner: Item<&'a mut A>,
105}
106
107impl<'a, A> Iterator for IterMut<'a, A> {
108    type Item = &'a mut A;
109
110    #[inline]
111    fn next(&mut self) -> Option<&'a mut A> {
112        self.inner.next()
113    }
114
115    #[inline]
116    fn size_hint(&self) -> (usize, Option<usize>) {
117        self.inner.size_hint()
118    }
119}
120
121impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
122    #[inline]
123    fn next_back(&mut self) -> Option<&'a mut A> {
124        self.inner.next_back()
125    }
126}
127
128impl<A> ExactSizeIterator for IterMut<'_, A> {}
129
130impl<A> FusedIterator for IterMut<'_, A> {}
131
132/// An iterator over the value in [`Some`] variant of an [`Possible`].
133///
134/// The iterator yields one value if the [`Possible`] is a [`Some`], otherwise none.
135///
136/// This `struct` is created by the [`Possible::into_iter`] function.
137#[derive(Clone, Debug)]
138pub struct IntoIter<A> {
139    inner: Item<A>,
140}
141
142impl<A> Iterator for IntoIter<A> {
143    type Item = A;
144
145    #[inline]
146    fn next(&mut self) -> Option<A> {
147        self.inner.next()
148    }
149
150    #[inline]
151    fn size_hint(&self) -> (usize, Option<usize>) {
152        self.inner.size_hint()
153    }
154}
155
156impl<A> DoubleEndedIterator for IntoIter<A> {
157    #[inline]
158    fn next_back(&mut self) -> Option<A> {
159        self.inner.next_back()
160    }
161}
162
163impl<A> ExactSizeIterator for IntoIter<A> {}
164
165impl<A> FusedIterator for IntoIter<A> {}
166
167#[derive(Clone, Debug)]
168struct Item<A> {
169    opt: Possible<A>,
170}
171
172impl<A> Iterator for Item<A> {
173    type Item = A;
174
175    #[inline]
176    fn next(&mut self) -> Option<A> {
177        match self.opt.take() {
178            Possible::Some(v) => Some(v),
179            Possible::None | Possible::Void => None,
180        }
181    }
182
183    #[inline]
184    fn size_hint(&self) -> (usize, Option<usize>) {
185        match self.opt {
186            Possible::Some(_) => (1, Option::Some(1)),
187            Possible::None | Possible::Void => (0, Option::Some(0)),
188        }
189    }
190}
191
192impl<A> DoubleEndedIterator for Item<A> {
193    #[inline]
194    fn next_back(&mut self) -> Option<A> {
195        match self.opt.take() {
196            Possible::Some(v) => Some(v),
197            Possible::None | Possible::Void => None,
198        }
199    }
200}
201
202impl<A> ExactSizeIterator for Item<A> {}
203
204impl<A> FusedIterator for Item<A> {}
205
206impl<T> IntoIterator for Possible<T> {
207    type Item = T;
208    type IntoIter = IntoIter<T>;
209
210    /// Returns a consuming iterator over the possibly contained value.
211    ///
212    /// # Examples
213    ///
214    /// ```
215    /// use possible::Possible;
216    ///
217    /// let x = Possible::Some("string");
218    /// let v: Vec<&str> = x.into_iter().collect();
219    /// assert_eq!(v, ["string"]);
220    ///
221    /// let x = Possible::None;
222    /// let v: Vec<&str> = x.into_iter().collect();
223    /// assert!(v.is_empty());
224    /// ```
225    #[inline]
226    fn into_iter(self) -> IntoIter<T> {
227        IntoIter {
228            inner: Item { opt: self },
229        }
230    }
231}
232
233impl<'a, T> IntoIterator for &'a Possible<T> {
234    type Item = &'a T;
235    type IntoIter = Iter<'a, T>;
236
237    fn into_iter(self) -> Iter<'a, T> {
238        self.iter()
239    }
240}
241
242impl<'a, T> IntoIterator for &'a mut Possible<T> {
243    type Item = &'a mut T;
244    type IntoIter = IterMut<'a, T>;
245
246    fn into_iter(self) -> IterMut<'a, T> {
247        self.iter_mut()
248    }
249}