From 6b4dfd4973f0bdd341de4b5ed47d50e3f707ce8c Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 16 Feb 2024 16:12:07 +0100 Subject: [PATCH 1/3] add filter method --- src/iter/mod.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 5 ++-- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/iter/mod.rs b/src/iter/mod.rs index 9954a89..30193d8 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -33,6 +33,17 @@ pub trait Iterator { Map::new(self, f) } + /// Creates an iterator which uses a closure to determine if an element should be yielded. + #[must_use = "iterators do nothing unless iterated over"] + fn filter

(self, predicate: P) -> Filter + where + P: async FnMut(&Self::Item) -> bool, + // P: FnMut(&Self::Item) -> bool, + Self: Sized, + { + Filter::new(self, predicate) + } + /// Transforms an iterator into a collection. #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] async fn collect>(self) -> B @@ -63,3 +74,55 @@ pub trait Iterator { LendMut::new(self) } } + +/// An async iterator that filters the elements of `iter` with `predicate`. +/// +/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter`]: crate::Iterator::filter +/// [`Iterator`]: crate::Iterator +#[derive(Debug)] +pub struct Filter +where + I: crate::Iterator, + P: async FnMut(&I::Item) -> bool, +{ + iter: I, + predicate: P, +} + +impl crate::Iterator for Filter +where + I: crate::Iterator, + P: async FnMut(&I::Item) -> bool, +{ + type Item = I::Item; + + async fn next(&mut self) -> Option { + loop { + let item = self.iter.next().await?; + if (self.predicate)(&item).await { + return Some(item); + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +impl Filter +where + I: crate::Iterator, + P: async FnMut(&I::Item) -> bool, +{ + pub(crate) fn new(stream: I, predicate: P) -> Self { + Self { + iter: stream, + predicate, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 42947b3..a52d4e7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,9 +18,8 @@ //! the traits, use `async_trait`. //! #![cfg_attr(not(feature = "std"), no_std)] -#![allow(incomplete_features)] -#![feature(return_position_impl_trait_in_trait)] -#![feature(async_fn_in_trait)] +#![allow(async_fn_in_trait)] +#![feature(async_closure)] #![forbid(unsafe_code, future_incompatible)] #![deny(missing_debug_implementations, nonstandard_style)] #![warn(missing_docs)] From 6f3fac1ba3a2a1da3831e222dfaa7ed7d2fc298e Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 16 Feb 2024 16:13:02 +0100 Subject: [PATCH 2/3] move `filter` to its own file --- src/iter/filter.rs | 51 +++++++++++++++++++++++++++++++++++++++++++ src/iter/mod.rs | 54 ++-------------------------------------------- 2 files changed, 53 insertions(+), 52 deletions(-) create mode 100644 src/iter/filter.rs diff --git a/src/iter/filter.rs b/src/iter/filter.rs new file mode 100644 index 0000000..1f59239 --- /dev/null +++ b/src/iter/filter.rs @@ -0,0 +1,51 @@ +/// An async iterator that filters the elements of `iter` with `predicate`. +/// +/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter`]: crate::Iterator::filter +/// [`Iterator`]: crate::Iterator +#[derive(Debug)] +pub struct Filter +where + I: crate::Iterator, + P: async FnMut(&I::Item) -> bool, +{ + iter: I, + predicate: P, +} + +impl crate::Iterator for Filter +where + I: crate::Iterator, + P: async FnMut(&I::Item) -> bool, +{ + type Item = I::Item; + + async fn next(&mut self) -> Option { + loop { + let item = self.iter.next().await?; + if (self.predicate)(&item).await { + return Some(item); + } + } + } + + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +impl Filter +where + I: crate::Iterator, + P: async FnMut(&I::Item) -> bool, +{ + pub(crate) fn new(stream: I, predicate: P) -> Self { + Self { + iter: stream, + predicate, + } + } +} diff --git a/src/iter/mod.rs b/src/iter/mod.rs index 30193d8..cf6fd79 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -1,7 +1,9 @@ +mod filter; mod lend; mod lend_mut; mod map; +pub use filter::Filter; pub use lend::Lend; pub use lend_mut::LendMut; pub use map::Map; @@ -74,55 +76,3 @@ pub trait Iterator { LendMut::new(self) } } - -/// An async iterator that filters the elements of `iter` with `predicate`. -/// -/// This `struct` is created by the [`filter`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`filter`]: crate::Iterator::filter -/// [`Iterator`]: crate::Iterator -#[derive(Debug)] -pub struct Filter -where - I: crate::Iterator, - P: async FnMut(&I::Item) -> bool, -{ - iter: I, - predicate: P, -} - -impl crate::Iterator for Filter -where - I: crate::Iterator, - P: async FnMut(&I::Item) -> bool, -{ - type Item = I::Item; - - async fn next(&mut self) -> Option { - loop { - let item = self.iter.next().await?; - if (self.predicate)(&item).await { - return Some(item); - } - } - } - - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } -} - -impl Filter -where - I: crate::Iterator, - P: async FnMut(&I::Item) -> bool, -{ - pub(crate) fn new(stream: I, predicate: P) -> Self { - Self { - iter: stream, - predicate, - } - } -} From 39dc56b75c7546bf3e29ba9c1b13b7a0188087db Mon Sep 17 00:00:00 2001 From: Yosh Date: Fri, 16 Feb 2024 16:15:53 +0100 Subject: [PATCH 3/3] fix a var name --- src/iter/filter.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/iter/filter.rs b/src/iter/filter.rs index 1f59239..387acf7 100644 --- a/src/iter/filter.rs +++ b/src/iter/filter.rs @@ -42,10 +42,7 @@ where I: crate::Iterator, P: async FnMut(&I::Item) -> bool, { - pub(crate) fn new(stream: I, predicate: P) -> Self { - Self { - iter: stream, - predicate, - } + pub(crate) fn new(iter: I, predicate: P) -> Self { + Self { iter, predicate } } }