Skip to content

Commit 6d15c6c

Browse files
authored
stream: add examples to wrapper types (#7024)
1 parent 79a2afa commit 6d15c6c

File tree

11 files changed

+239
-0
lines changed

11 files changed

+239
-0
lines changed

tokio-stream/src/wrappers/broadcast.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,29 @@ use std::task::{ready, Context, Poll};
1010

1111
/// A wrapper around [`tokio::sync::broadcast::Receiver`] that implements [`Stream`].
1212
///
13+
/// # Example
14+
///
15+
/// ```
16+
/// use tokio::sync::broadcast;
17+
/// use tokio_stream::wrappers::BroadcastStream;
18+
/// use tokio_stream::StreamExt;
19+
///
20+
/// # #[tokio::main(flavor = "current_thread")]
21+
/// # async fn main() -> Result<(), tokio::sync::broadcast::error::SendError<u8>> {
22+
/// let (tx, rx) = broadcast::channel(16);
23+
/// tx.send(10)?;
24+
/// tx.send(20)?;
25+
/// # // prevent the doc test from hanging
26+
/// drop(tx);
27+
///
28+
/// let mut stream = BroadcastStream::new(rx);
29+
/// assert_eq!(stream.next().await, Some(Ok(10)));
30+
/// assert_eq!(stream.next().await, Some(Ok(20)));
31+
/// assert_eq!(stream.next().await, None);
32+
/// # Ok(())
33+
/// # }
34+
/// ```
35+
///
1336
/// [`tokio::sync::broadcast::Receiver`]: struct@tokio::sync::broadcast::Receiver
1437
/// [`Stream`]: trait@futures_core::Stream
1538
#[cfg_attr(docsrs, doc(cfg(feature = "sync")))]

tokio-stream/src/wrappers/interval.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ use tokio::time::{Instant, Interval};
55

66
/// A wrapper around [`Interval`] that implements [`Stream`].
77
///
8+
/// # Example
9+
///
10+
/// ```
11+
/// use tokio::time::{Duration, Instant, interval};
12+
/// use tokio_stream::wrappers::IntervalStream;
13+
/// use tokio_stream::StreamExt;
14+
///
15+
/// # #[tokio::main(flavor = "current_thread")]
16+
/// # async fn main() {
17+
/// let start = Instant::now();
18+
/// let interval = interval(Duration::from_millis(10));
19+
/// let mut stream = IntervalStream::new(interval);
20+
/// for _ in 0..3 {
21+
/// if let Some(instant) = stream.next().await {
22+
/// println!("elapsed: {:.1?}", instant.duration_since(start));
23+
/// }
24+
/// }
25+
/// # }
26+
/// ```
27+
///
828
/// [`Interval`]: struct@tokio::time::Interval
929
/// [`Stream`]: trait@crate::Stream
1030
#[derive(Debug)]

tokio-stream/src/wrappers/lines.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@ use tokio::io::{AsyncBufRead, Lines};
88
pin_project! {
99
/// A wrapper around [`tokio::io::Lines`] that implements [`Stream`].
1010
///
11+
/// # Example
12+
///
13+
/// ```
14+
/// use tokio::io::AsyncBufReadExt;
15+
/// use tokio_stream::wrappers::LinesStream;
16+
/// use tokio_stream::StreamExt;
17+
///
18+
/// # #[tokio::main(flavor = "current_thread")]
19+
/// # async fn main() -> std::io::Result<()> {
20+
/// let input = b"Hello\nWorld\n";
21+
/// let mut stream = LinesStream::new(input.lines());
22+
/// while let Some(line) = stream.next().await {
23+
/// println!("{}", line?);
24+
/// }
25+
/// # Ok(())
26+
/// # }
27+
/// ```
28+
///
1129
/// [`tokio::io::Lines`]: struct@tokio::io::Lines
1230
/// [`Stream`]: trait@crate::Stream
1331
#[derive(Debug)]

tokio-stream/src/wrappers/mpsc_bounded.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,29 @@ use tokio::sync::mpsc::Receiver;
55

66
/// A wrapper around [`tokio::sync::mpsc::Receiver`] that implements [`Stream`].
77
///
8+
/// # Example
9+
///
10+
/// ```
11+
/// use tokio::sync::mpsc;
12+
/// use tokio_stream::wrappers::ReceiverStream;
13+
/// use tokio_stream::StreamExt;
14+
///
15+
/// # #[tokio::main(flavor = "current_thread")]
16+
/// # async fn main() -> Result<(), tokio::sync::mpsc::error::SendError<u8>> {
17+
/// let (tx, rx) = mpsc::channel(2);
18+
/// tx.send(10).await?;
19+
/// tx.send(20).await?;
20+
/// # // prevent the doc test from hanging
21+
/// drop(tx);
22+
///
23+
/// let mut stream = ReceiverStream::new(rx);
24+
/// assert_eq!(stream.next().await, Some(10));
25+
/// assert_eq!(stream.next().await, Some(20));
26+
/// assert_eq!(stream.next().await, None);
27+
/// # Ok(())
28+
/// # }
29+
/// ```
30+
///
831
/// [`tokio::sync::mpsc::Receiver`]: struct@tokio::sync::mpsc::Receiver
932
/// [`Stream`]: trait@crate::Stream
1033
#[derive(Debug)]

tokio-stream/src/wrappers/mpsc_unbounded.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,29 @@ use tokio::sync::mpsc::UnboundedReceiver;
55

66
/// A wrapper around [`tokio::sync::mpsc::UnboundedReceiver`] that implements [`Stream`].
77
///
8+
/// # Example
9+
///
10+
/// ```
11+
/// use tokio::sync::mpsc;
12+
/// use tokio_stream::wrappers::UnboundedReceiverStream;
13+
/// use tokio_stream::StreamExt;
14+
///
15+
/// # #[tokio::main(flavor = "current_thread")]
16+
/// # async fn main() -> Result<(), tokio::sync::mpsc::error::SendError<u8>> {
17+
/// let (tx, rx) = mpsc::unbounded_channel();
18+
/// tx.send(10)?;
19+
/// tx.send(20)?;
20+
/// # // prevent the doc test from hanging
21+
/// drop(tx);
22+
///
23+
/// let mut stream = UnboundedReceiverStream::new(rx);
24+
/// assert_eq!(stream.next().await, Some(10));
25+
/// assert_eq!(stream.next().await, Some(20));
26+
/// assert_eq!(stream.next().await, None);
27+
/// # Ok(())
28+
/// # }
29+
/// ```
30+
///
831
/// [`tokio::sync::mpsc::UnboundedReceiver`]: struct@tokio::sync::mpsc::UnboundedReceiver
932
/// [`Stream`]: trait@crate::Stream
1033
#[derive(Debug)]

tokio-stream/src/wrappers/read_dir.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ use tokio::fs::{DirEntry, ReadDir};
66

77
/// A wrapper around [`tokio::fs::ReadDir`] that implements [`Stream`].
88
///
9+
/// # Example
10+
///
11+
/// ```
12+
/// use tokio::fs::read_dir;
13+
/// use tokio_stream::{StreamExt, wrappers::ReadDirStream};
14+
///
15+
/// # #[tokio::main(flavor = "current_thread")]
16+
/// # async fn main() -> std::io::Result<()> {
17+
/// let dirs = read_dir(".").await?;
18+
/// let mut dirs = ReadDirStream::new(dirs);
19+
/// while let Some(dir) = dirs.next().await {
20+
/// let dir = dir?;
21+
/// println!("{}", dir.path().display());
22+
/// }
23+
/// # Ok(())
24+
/// # }
25+
/// ```
26+
///
927
/// [`tokio::fs::ReadDir`]: struct@tokio::fs::ReadDir
1028
/// [`Stream`]: trait@crate::Stream
1129
#[derive(Debug)]

tokio-stream/src/wrappers/signal_unix.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@ use tokio::signal::unix::Signal;
55

66
/// A wrapper around [`Signal`] that implements [`Stream`].
77
///
8+
/// # Example
9+
///
10+
/// ```no_run
11+
/// use tokio::signal::unix::{signal, SignalKind};
12+
/// use tokio_stream::{StreamExt, wrappers::SignalStream};
13+
///
14+
/// # #[tokio::main(flavor = "current_thread")]
15+
/// # async fn main() -> std::io::Result<()> {
16+
/// let signals = signal(SignalKind::hangup())?;
17+
/// let mut stream = SignalStream::new(signals);
18+
/// while stream.next().await.is_some() {
19+
/// println!("hangup signal received");
20+
/// }
21+
/// # Ok(())
22+
/// # }
23+
/// ```
824
/// [`Signal`]: struct@tokio::signal::unix::Signal
925
/// [`Stream`]: trait@crate::Stream
1026
#[derive(Debug)]

tokio-stream/src/wrappers/signal_windows.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ use tokio::signal::windows::{CtrlBreak, CtrlC};
77
///
88
/// [`CtrlC`]: struct@tokio::signal::windows::CtrlC
99
/// [`Stream`]: trait@crate::Stream
10+
///
11+
/// # Example
12+
///
13+
/// ```no_run
14+
/// use tokio::signal::windows::ctrl_c;
15+
/// use tokio_stream::{StreamExt, wrappers::CtrlCStream};
16+
///
17+
/// # #[tokio::main(flavor = "current_thread")]
18+
/// # async fn main() -> std::io::Result<()> {
19+
/// let signals = ctrl_c()?;
20+
/// let mut stream = CtrlCStream::new(signals);
21+
/// while stream.next().await.is_some() {
22+
/// println!("ctrl-c received");
23+
/// }
24+
/// # Ok(())
25+
/// # }
26+
/// ```
1027
#[derive(Debug)]
1128
#[cfg_attr(docsrs, doc(cfg(all(windows, feature = "signal"))))]
1229
pub struct CtrlCStream {
@@ -47,6 +64,23 @@ impl AsMut<CtrlC> for CtrlCStream {
4764

4865
/// A wrapper around [`CtrlBreak`] that implements [`Stream`].
4966
///
67+
/// # Example
68+
///
69+
/// ```no_run
70+
/// use tokio::signal::windows::ctrl_break;
71+
/// use tokio_stream::{StreamExt, wrappers::CtrlBreakStream};
72+
///
73+
/// # #[tokio::main(flavor = "current_thread")]
74+
/// # async fn main() -> std::io::Result<()> {
75+
/// let signals = ctrl_break()?;
76+
/// let mut stream = CtrlBreakStream::new(signals);
77+
/// while stream.next().await.is_some() {
78+
/// println!("ctrl-break received");
79+
/// }
80+
/// # Ok(())
81+
/// # }
82+
/// ```
83+
///
5084
/// [`CtrlBreak`]: struct@tokio::signal::windows::CtrlBreak
5185
/// [`Stream`]: trait@crate::Stream
5286
#[derive(Debug)]

tokio-stream/src/wrappers/split.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@ use tokio::io::{AsyncBufRead, Split};
88
pin_project! {
99
/// A wrapper around [`tokio::io::Split`] that implements [`Stream`].
1010
///
11+
/// # Example
12+
///
13+
/// ```
14+
/// use tokio::io::AsyncBufReadExt;
15+
/// use tokio_stream::{StreamExt, wrappers::SplitStream};
16+
///
17+
/// # #[tokio::main(flavor = "current_thread")]
18+
/// # async fn main() -> std::io::Result<()> {
19+
/// let input = "Hello\nWorld\n".as_bytes();
20+
/// let lines = AsyncBufReadExt::split(input, b'\n');
21+
///
22+
/// let mut stream = SplitStream::new(lines);
23+
/// while let Some(line) = stream.next().await {
24+
/// println!("length = {}", line?.len())
25+
/// }
26+
/// # Ok(())
27+
/// # }
28+
/// ```
1129
/// [`tokio::io::Split`]: struct@tokio::io::Split
1230
/// [`Stream`]: trait@crate::Stream
1331
#[derive(Debug)]

tokio-stream/src/wrappers/tcp_listener.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ use tokio::net::{TcpListener, TcpStream};
66

77
/// A wrapper around [`TcpListener`] that implements [`Stream`].
88
///
9+
/// # Example
10+
///
11+
/// Accept connections from both IPv4 and IPv6 listeners in the same loop:
12+
///
13+
/// ```no_run
14+
/// use std::net::{Ipv4Addr, Ipv6Addr};
15+
///
16+
/// use tokio::net::TcpListener;
17+
/// use tokio_stream::{StreamExt, wrappers::TcpListenerStream};
18+
///
19+
/// # #[tokio::main(flavor = "current_thread")]
20+
/// # async fn main() -> std::io::Result<()> {
21+
/// let ipv4_listener = TcpListener::bind((Ipv6Addr::LOCALHOST, 8080)).await?;
22+
/// let ipv6_listener = TcpListener::bind((Ipv4Addr::LOCALHOST, 8080)).await?;
23+
/// let ipv4_connections = TcpListenerStream::new(ipv4_listener);
24+
/// let ipv6_connections = TcpListenerStream::new(ipv6_listener);
25+
///
26+
/// let mut connections = ipv4_connections.chain(ipv6_connections);
27+
/// while let Some(tcp_stream) = connections.next().await {
28+
/// let stream = tcp_stream?;
29+
/// let peer_addr = stream.peer_addr()?;
30+
/// println!("accepted connection; peer address = {peer_addr}");
31+
/// }
32+
/// # Ok(())
33+
/// # }
34+
/// ```
35+
///
936
/// [`TcpListener`]: struct@tokio::net::TcpListener
1037
/// [`Stream`]: trait@crate::Stream
1138
#[derive(Debug)]

0 commit comments

Comments
 (0)