From 5721f3774002bd5e4823d1e46e75a701dd607727 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Sun, 6 Aug 2023 18:49:51 -0600 Subject: [PATCH 1/5] `try_len` method --- src/lib.rs | 16 ++++++++++++++++ src/size_hint.rs | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index c9bad16eb..2c9abba00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3840,6 +3840,22 @@ pub trait Itertools : Iterator { { MultiUnzip::multiunzip(self) } + + /// Returns the length of the iterator if one exists. + /// + /// ``` + /// use itertools::Itertools; + /// + /// assert_eq!([0; 10].into_iter().try_len(), Some(10)); + /// assert_eq!((10..15).try_len(), Some(5)); + /// assert_eq!((15..10).try_len(), Some(0)); + /// assert_eq!((10..).try_len(), None); + /// ``` + fn try_len(self) -> Option + where Self: Sized + { + size_hint::try_len(self) + } } impl Itertools for T where T: Iterator { } diff --git a/src/size_hint.rs b/src/size_hint.rs index 71ea1412b..e329165c0 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -117,3 +117,12 @@ pub fn min(a: SizeHint, b: SizeHint) -> SizeHint { }; (lower, upper) } + +/// Returns the length of the iterator if one exists. +#[inline] +pub fn try_len(it: impl Iterator) -> Option { + match it.size_hint() { + (lo, Some(hi)) if lo == hi => Some(lo), + _ => None + } +} \ No newline at end of file From 6e54b0fa8b4615a799418dd50e0efc5ef1ff2c27 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Sun, 6 Aug 2023 19:02:01 -0600 Subject: [PATCH 2/5] take by ref --- src/lib.rs | 2 +- src/size_hint.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2c9abba00..52a8f3e8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3851,7 +3851,7 @@ pub trait Itertools : Iterator { /// assert_eq!((15..10).try_len(), Some(0)); /// assert_eq!((10..).try_len(), None); /// ``` - fn try_len(self) -> Option + fn try_len(&self) -> Option where Self: Sized { size_hint::try_len(self) diff --git a/src/size_hint.rs b/src/size_hint.rs index e329165c0..b221583f7 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -120,7 +120,7 @@ pub fn min(a: SizeHint, b: SizeHint) -> SizeHint { /// Returns the length of the iterator if one exists. #[inline] -pub fn try_len(it: impl Iterator) -> Option { +pub fn try_len(it: &impl Iterator) -> Option { match it.size_hint() { (lo, Some(hi)) if lo == hi => Some(lo), _ => None From 952d8c4c87826a0413f0ae7ed8a5aee257d1c0a9 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:48:54 -0600 Subject: [PATCH 3/5] match other `sizehint` function conventions --- src/lib.rs | 3 ++- src/size_hint.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 52a8f3e8a..1244ab9a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3842,6 +3842,7 @@ pub trait Itertools : Iterator { } /// Returns the length of the iterator if one exists. + /// Relies on the [`size_hint`] of the iterator being correct. /// /// ``` /// use itertools::Itertools; @@ -3854,7 +3855,7 @@ pub trait Itertools : Iterator { fn try_len(&self) -> Option where Self: Sized { - size_hint::try_len(self) + size_hint::try_len(self.size_hint()) } } diff --git a/src/size_hint.rs b/src/size_hint.rs index b221583f7..dfe69d1d9 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -120,8 +120,8 @@ pub fn min(a: SizeHint, b: SizeHint) -> SizeHint { /// Returns the length of the iterator if one exists. #[inline] -pub fn try_len(it: &impl Iterator) -> Option { - match it.size_hint() { +pub fn try_len(sh: SizeHint) -> Option { + match sh { (lo, Some(hi)) if lo == hi => Some(lo), _ => None } From 87ad574a88b93e01b7ccbd8e62c85cf7f1cc43cf Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Tue, 8 Aug 2023 19:54:26 -0600 Subject: [PATCH 4/5] Result not Option, inline, no Sized bound, improve docs --- src/lib.rs | 19 ++++++++++++------- src/size_hint.rs | 6 +++--- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1244ab9a2..08bc2e059 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3842,18 +3842,23 @@ pub trait Itertools : Iterator { } /// Returns the length of the iterator if one exists. - /// Relies on the [`size_hint`] of the iterator being correct. + /// Otherwise return `self.size_hint()`. + /// + /// Fallible [`ExactSizeIterator::len`]. + /// + /// Inherits guarantees and restrictions from [`Iterator::size_hint`]. /// /// ``` /// use itertools::Itertools; /// - /// assert_eq!([0; 10].into_iter().try_len(), Some(10)); - /// assert_eq!((10..15).try_len(), Some(5)); - /// assert_eq!((15..10).try_len(), Some(0)); - /// assert_eq!((10..).try_len(), None); + /// 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) -> Option - where Self: Sized + #[inline] + fn try_len(&self) -> Result { size_hint::try_len(self.size_hint()) } diff --git a/src/size_hint.rs b/src/size_hint.rs index dfe69d1d9..dbd5624e6 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -120,9 +120,9 @@ pub fn min(a: SizeHint, b: SizeHint) -> SizeHint { /// Returns the length of the iterator if one exists. #[inline] -pub fn try_len(sh: SizeHint) -> Option { +pub fn try_len(sh: SizeHint) -> Result { match sh { - (lo, Some(hi)) if lo == hi => Some(lo), - _ => None + (lo, Some(hi)) if lo == hi => Ok(lo), + _ => Err(sh) } } \ No newline at end of file From 068de35d95d345ea6bf112ecdf8de504cdb3b334 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:21:03 -0600 Subject: [PATCH 5/5] inline function source code and remove annotation --- src/lib.rs | 10 ++++++---- src/size_hint.rs | 9 --------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 08bc2e059..41bedfcab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3857,10 +3857,12 @@ pub trait Itertools : Iterator { /// assert_eq!((10..).try_len(), Err((usize::MAX, None))); /// assert_eq!((10..15).filter(|x| x % 2 == 0).try_len(), Err((0, Some(5)))); /// ``` - #[inline] - fn try_len(&self) -> Result - { - size_hint::try_len(self.size_hint()) + fn try_len(&self) -> Result { + let sh = self.size_hint(); + match sh { + (lo, Some(hi)) if lo == hi => Ok(lo), + _ => Err(sh), + } } } diff --git a/src/size_hint.rs b/src/size_hint.rs index dbd5624e6..71ea1412b 100644 --- a/src/size_hint.rs +++ b/src/size_hint.rs @@ -117,12 +117,3 @@ pub fn min(a: SizeHint, b: SizeHint) -> SizeHint { }; (lower, upper) } - -/// Returns the length of the iterator if one exists. -#[inline] -pub fn try_len(sh: SizeHint) -> Result { - match sh { - (lo, Some(hi)) if lo == hi => Ok(lo), - _ => Err(sh) - } -} \ No newline at end of file