Skip to content

Commit d0ef48c

Browse files
committed
Sketch out nth_back
1 parent fa28893 commit d0ef48c

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

src/stream/double_ended/mod.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
mod nth_back;
2+
3+
use nth_back::NthBackFuture;
4+
15
extension_trait! {
26
use crate::stream::Stream;
37

48
use std::pin::Pin;
59
use std::task::{Context, Poll};
610

11+
712
#[doc = r#"
813
Something fancy
914
"#]
@@ -17,6 +22,36 @@ extension_trait! {
1722
Something else
1823
"#]
1924
pub trait DoubleEndedStreamExt: crate::stream::DoubleEndedStream {
25+
26+
#[doc = r#"
27+
Returns the nth element from the back of the stream.
28+
29+
# Examples
30+
31+
Basic usage:
32+
33+
```
34+
# fn main() { async_std::task::block_on(async {
35+
#
36+
use async_std::stream::double_ended::DoubleEndedStreamExt;
37+
use async_std::stream;
38+
39+
let mut s = stream::from_iter(vec![1u8, 2, 3, 4, 5]);
40+
41+
let second = s.nth_back(1).await;
42+
assert_eq!(second, Some(4));
43+
#
44+
# }) }
45+
```
46+
"#]
47+
fn nth_back(
48+
&mut self,
49+
n: usize,
50+
) -> impl Future<Output = Option<Self::Item>> + '_ [NthBackFuture<'_, Self>]
51+
where
52+
Self: Unpin + Sized,
53+
{
54+
NthBackFuture::new(self, n)
55+
}
2056
}
2157
}
22-

src/stream/double_ended/nth_back.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use std::pin::Pin;
2+
use std::task::{Context, Poll};
3+
use std::future::Future;
4+
5+
use crate::stream::DoubleEndedStream;
6+
7+
pub struct NthBackFuture<'a, S> {
8+
stream: &'a mut S,
9+
n: usize,
10+
}
11+
12+
impl<'a, S> NthBackFuture<'a, S> {
13+
pub(crate) fn new(stream: &'a mut S, n: usize) -> Self {
14+
NthBackFuture { stream, n }
15+
}
16+
}
17+
18+
impl<'a, S> Future for NthBackFuture<'a, S>
19+
where
20+
S: DoubleEndedStream + Sized + Unpin,
21+
{
22+
type Output = Option<S::Item>;
23+
24+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
25+
let next = futures_core::ready!(Pin::new(&mut *self.stream).poll_next_back(cx));
26+
match next {
27+
Some(v) => match self.n {
28+
0 => Poll::Ready(Some(v)),
29+
_ => {
30+
self.n -= 1;
31+
cx.waker().wake_by_ref();
32+
Poll::Pending
33+
}
34+
},
35+
None => Poll::Ready(None),
36+
}
37+
}
38+
}
39+

src/stream/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ mod repeat;
318318
mod repeat_with;
319319

320320
cfg_unstable! {
321-
mod double_ended;
321+
pub mod double_ended;
322322
mod double_ended_stream;
323323
mod exact_size_stream;
324324
mod extend;

0 commit comments

Comments
 (0)