-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
63b4989
commit aafa215
Showing
3 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
use crate::Scope; | ||
|
||
pub trait AsyncIterator { | ||
type Item; | ||
|
||
// fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) | ||
// -> std::task::Poll<Option<Self::Item>>; | ||
// | ||
// how do you do this? | ||
// | ||
// fn next(&mut self) -> impl Future<Output = Option<Self::Item>> { | ||
// pin!(self); | ||
// std::future::poll_fn(|cx| this.poll_next(cx)) | ||
// } | ||
|
||
async fn next(&mut self) -> Option<Self::Item>; | ||
|
||
fn filter( | ||
self, | ||
op: impl async FnMut(&Self::Item) -> bool, | ||
) -> impl AsyncIterator<Item = Self::Item> | ||
where | ||
Self: Sized, | ||
{ | ||
Filter { | ||
iter: self, | ||
filter_op: op, | ||
} | ||
} | ||
} | ||
|
||
pub trait IntoAsyncIter { | ||
type Item; | ||
|
||
// FIXME: The Scope type needs to not carry R. | ||
fn into_async_iter<R: Send>( | ||
self, | ||
scope: &Scope<'_, '_, R>, | ||
) -> impl AsyncIterator<Item = Self::Item>; | ||
} | ||
|
||
impl<T: AsyncIterator> IntoAsyncIter for T { | ||
type Item = T::Item; | ||
|
||
fn into_async_iter<R: Send>( | ||
self, | ||
_scope: &Scope<'_, '_, R>, | ||
) -> impl AsyncIterator<Item = Self::Item> { | ||
self | ||
} | ||
} | ||
|
||
struct Filter<I, O> | ||
where | ||
I: AsyncIterator, | ||
O: async FnMut(&I::Item) -> bool, | ||
{ | ||
iter: I, | ||
filter_op: O, | ||
} | ||
|
||
impl<I, O> AsyncIterator for Filter<I, O> | ||
where | ||
I: AsyncIterator, | ||
O: async FnMut(&I::Item) -> bool, | ||
{ | ||
type Item = I::Item; | ||
|
||
async fn next(&mut self) -> Option<Self::Item> { | ||
loop { | ||
let item = self.iter.next().await?; | ||
if (self.filter_op)(&item).await { | ||
return Some(item); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use crate::{AsyncIterator, IntoAsyncIter, Scope}; | ||
|
||
pub trait Stream: IntoAsyncIter { | ||
fn filter(self, op: impl async FnMut(&Self::Item) -> bool) -> impl Stream<Item = Self::Item> | ||
where | ||
Self: Sized, | ||
{ | ||
Filter { | ||
stream: self, | ||
filter_op: op, | ||
} | ||
} | ||
|
||
async fn for_each(&mut self, mut op: impl async FnMut(Self::Item)) | ||
where | ||
Self: Sized, | ||
{ | ||
self.fold((), async |(), item| op(item).await).await | ||
} | ||
|
||
async fn fold<R>(&mut self, start: R, op: impl async FnMut(R, Self::Item) -> R) -> R; | ||
} | ||
|
||
struct Filter<S, O> | ||
where | ||
S: Stream, | ||
O: async FnMut(&S::Item) -> bool, | ||
{ | ||
stream: S, | ||
filter_op: O, | ||
} | ||
|
||
impl<S, O> Stream for Filter<S, O> | ||
where | ||
S: Stream, | ||
O: async FnMut(&S::Item) -> bool, | ||
{ | ||
async fn fold<R>(&mut self, start: R, mut op: impl async FnMut(R, Self::Item) -> R) -> R { | ||
self.stream | ||
.fold(start, async |acc, item| { | ||
if (self.filter_op)(&item).await { | ||
op(acc, item).await | ||
} else { | ||
acc | ||
} | ||
}) | ||
.await | ||
} | ||
} | ||
|
||
impl<S, O> IntoAsyncIter for Filter<S, O> | ||
where | ||
S: Stream, | ||
O: async FnMut(&S::Item) -> bool, | ||
{ | ||
type Item = S::Item; | ||
|
||
fn into_async_iter<R: Send>( | ||
self, | ||
scope: &Scope<'_, '_, R>, | ||
) -> impl AsyncIterator<Item = Self::Item> { | ||
let iter = self.stream.into_async_iter(scope); | ||
iter.filter(self.filter_op) | ||
} | ||
} |