Skip to content

Commit

Permalink
Merge #723
Browse files Browse the repository at this point in the history
723: `try_len` method r=phimuemue a=Easyoakland

Add method to get the length of an iterator if the `size_hint` is consistent.
Reasons why this would be useful:
1. It makes it more obvious when getting the length with `it.try_len().unwrap()` than with the match statement.
2. Iterator adapters that increase the length of iteration are not supposed to implement `ExactSizeIter` as indicated [here](https://doc.rust-lang.org/std/iter/trait.ExactSizeIterator.html#when-shouldnt-an-adapter-be-exactsizeiterator). This could be used in those cases.


Co-authored-by: Easyoakland <97992568+Easyoakland@users.noreply.github.com>
  • Loading branch information
bors[bot] and Easyoakland committed Aug 9, 2023
2 parents 052423a + 068de35 commit c5afdd3
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/lib.rs
Expand Up @@ -3840,6 +3840,30 @@ pub trait Itertools : Iterator {
{
MultiUnzip::multiunzip(self)
}

/// Returns the length of the iterator if one exists.
/// Otherwise return `self.size_hint()`.
///
/// Fallible [`ExactSizeIterator::len`].
///
/// Inherits guarantees and restrictions from [`Iterator::size_hint`].
///
/// ```
/// use itertools::Itertools;
///
/// assert_eq!([0; 10].iter().try_len(), Ok(10));
/// assert_eq!((10..15).try_len(), Ok(5));
/// assert_eq!((15..10).try_len(), Ok(0));
/// assert_eq!((10..).try_len(), Err((usize::MAX, None)));
/// assert_eq!((10..15).filter(|x| x % 2 == 0).try_len(), Err((0, Some(5))));
/// ```
fn try_len(&self) -> Result<usize, size_hint::SizeHint> {
let sh = self.size_hint();
match sh {
(lo, Some(hi)) if lo == hi => Ok(lo),
_ => Err(sh),
}
}
}

impl<T: ?Sized> Itertools for T where T: Iterator { }
Expand Down

0 comments on commit c5afdd3

Please sign in to comment.