add stream-min

poc-serde-support
yjhmelody 5 years ago
parent da795dec7b
commit b942d0a405

@ -0,0 +1,60 @@
use std::marker::PhantomData;
use std::cmp::{Ordering, Ord};
use std::pin::Pin;
use pin_project_lite::pin_project;
use crate::future::Future;
use crate::stream::Stream;
use crate::task::{Context, Poll};
pin_project! {
#[doc(hidden)]
#[allow(missing_debug_implementations)]
pub struct MinFuture<S, F, T> {
#[pin]
stream: S,
_compare: PhantomData<F>,
min: Option<T>,
}
}
impl<S, F, T> MinFuture<S, F, T> {
pub(super) fn new(stream: S) -> Self {
Self {
stream,
_compare: PhantomData,
min: None,
}
}
}
impl<S, F> Future for MinFuture<S, F, S::Item>
where
S: Stream,
S::Item: Ord,
F: FnMut(&S::Item, &S::Item) -> Ordering,
{
type Output = Option<S::Item>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let next = futures_core::ready!(this.stream.poll_next(cx));
match next {
Some(new) => {
cx.waker().wake_by_ref();
match this.min.take() {
None => *this.min = Some(new),
Some(old) => match new.cmp(&old) {
Ordering::Less => *this.min = Some(new),
_ => *this.min = Some(old),
},
}
Poll::Pending
}
None => Poll::Ready(this.min.take()),
}
}
}

@ -41,6 +41,7 @@ mod le;
mod lt;
mod map;
mod max_by;
mod min;
mod min_by;
mod min_by_key;
mod next;
@ -71,6 +72,7 @@ use last::LastFuture;
use le::LeFuture;
use lt::LtFuture;
use max_by::MaxByFuture;
use min::MinFuture;
use min_by::MinByFuture;
use min_by_key::MinByKeyFuture;
use next::NextFuture;
@ -753,6 +755,41 @@ extension_trait! {
self,
compare: F,
) -> impl Future<Output = Option<Self::Item>> [MinByFuture<Self, F, Self::Item>]
where
Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{
MinByFuture::new(self, compare)
}
#[doc = r#"
Returns the element that gives the minimum value. If several elements are equally minimum,
the first element is returned. If the stream is empty, `None` is returned.
# Examples
```
# fn main() { async_std::task::block_on(async {
#
use std::collections::VecDeque;
use async_std::prelude::*;
let s: VecDeque<usize> = vec![1, 2, 3].into_iter().collect();
let min = s.clone().min().await;
assert_eq!(min, Some(1));
let min = VecDeque::<usize>::new().min().await;
assert_eq!(min, None);
#
# }) }
```
"#]
fn min_by<F>(
self,
compare: F,
) -> impl Future<Output = Option<Self::Item>> [MinByFuture<Self, F, Self::Item>]
where
Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Loading…
Cancel
Save