heim_common/utils/
iter.rs

1//! Internal extensions for `Iterator`s.
2
3use std::convert::TryFrom;
4use std::io;
5use std::str::FromStr;
6
7use crate::{Error, Result};
8
9/// Extension trait for all `T: Iterator`.
10///
11/// Used across the `heim` sub-crates only.
12pub trait TryIterator: Iterator {
13    /// Attempt to fetch next element from iterator,
14    /// but instead of returning `Option<T>` returns `Result<T>`.
15    fn try_next(&mut self) -> Result<<Self as Iterator>::Item>;
16
17    /// Attempt to fetch next element from iterator
18    /// and try to convert it into `R` type.
19    ///
20    /// Type `R` should implement `TryFrom<Iterator::Item>`.
21    fn try_from_next<R, E>(&mut self) -> Result<R>
22    where
23        R: TryFrom<<Self as Iterator>::Item, Error = E>,
24        Error: From<E>;
25}
26
27/// Extension trait for all `T: Iterator`.
28///
29/// Used across the `heim` sub-crates only.
30pub trait ParseIterator<I>: TryIterator<Item = I>
31where
32    I: AsRef<str>,
33{
34    /// Attempt to to parse next yielded element from the iterator.
35    ///
36    /// Type `R` should implement `std::str::FromStr` trait in order
37    /// to be able parsed from the iterator element.
38    fn try_parse_next<R, E>(&mut self) -> Result<R>
39    where
40        R: FromStr<Err = E>,
41        Error: From<E>;
42}
43
44impl<T> TryIterator for T
45where
46    T: Iterator,
47{
48    fn try_next(&mut self) -> Result<<Self as Iterator>::Item> {
49        self.next()
50            .ok_or_else(|| io::Error::from(io::ErrorKind::InvalidData))
51            .map_err(Into::into)
52    }
53
54    fn try_from_next<R, E>(&mut self) -> Result<R>
55    where
56        R: TryFrom<<Self as Iterator>::Item, Error = E>,
57        Error: From<E>,
58    {
59        let value = self.try_next()?;
60
61        TryFrom::try_from(value).map_err(Into::into)
62    }
63}
64
65impl<T, I> ParseIterator<I> for T
66where
67    T: TryIterator<Item = I>,
68    I: AsRef<str>,
69{
70    fn try_parse_next<R, E>(&mut self) -> Result<R>
71    where
72        R: FromStr<Err = E>,
73        Error: From<E>,
74    {
75        let value = self.try_next()?;
76
77        FromStr::from_str(value.as_ref()).map_err(Into::into)
78    }
79}