Skip to content

Commit 6dea985

Browse files
Merge pull request #1108 from Nemo157/futures-util-io-examples
futures-util/io examples
2 parents e91f3a9 + ea11c8d commit 6dea985

File tree

2 files changed

+166
-4
lines changed

2 files changed

+166
-4
lines changed

futures-util/src/io/mod.rs

+165-3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@ pub trait AsyncReadExt: AsyncRead {
5555
/// provided.
5656
///
5757
/// On success the number of bytes is returned.
58+
///
59+
/// # Examples
60+
///
61+
/// ```
62+
/// #![feature(async_await, await_macro, futures_api)]
63+
/// # futures::executor::block_on(async {
64+
/// use futures::io::AsyncReadExt;
65+
/// use std::io::Cursor;
66+
///
67+
/// let mut reader = Cursor::new([1, 2, 3, 4]);
68+
/// let mut output = [0u8; 5];
69+
///
70+
/// let bytes = {
71+
/// let mut writer = Cursor::new(&mut output[..]);
72+
/// await!(reader.copy_into(&mut writer))?
73+
/// };
74+
///
75+
/// assert_eq!(bytes, 4);
76+
/// assert_eq!(output, [1, 2, 3, 4, 0]);
77+
/// # Ok::<(), Box<std::error::Error>>(()) }).unwrap();
78+
/// ```
5879
fn copy_into<'a, W>(
5980
&'a mut self,
6081
writer: &'a mut W,
@@ -69,17 +90,72 @@ pub trait AsyncReadExt: AsyncRead {
6990
///
7091
/// The returned future will resolve to the number of bytes read once the read
7192
/// operation is completed.
93+
///
94+
/// # Examples
95+
///
96+
/// ```
97+
/// #![feature(async_await, await_macro, futures_api)]
98+
/// # futures::executor::block_on(async {
99+
/// use futures::io::AsyncReadExt;
100+
/// use std::io::Cursor;
101+
///
102+
/// let mut reader = Cursor::new([1, 2, 3, 4]);
103+
/// let mut output = [0u8; 5];
104+
///
105+
/// let bytes = await!(reader.read(&mut output[..]))?;
106+
///
107+
/// // This is only guaranteed to be 4 because `&[u8]` is a synchronous
108+
/// // reader. In a real system you could get anywhere from 1 to
109+
/// // `output.len()` bytes in a single read.
110+
/// assert_eq!(bytes, 4);
111+
/// assert_eq!(output, [1, 2, 3, 4, 0]);
112+
/// # Ok::<(), Box<std::error::Error>>(()) }).unwrap();
113+
/// ```
72114
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> {
73115
Read::new(self, buf)
74116
}
75117

76118
/// Creates a future which will read exactly enough bytes to fill `buf`,
77-
/// returning an error if EOF is hit sooner.
119+
/// returning an error if end of file (EOF) is hit sooner.
78120
///
79121
/// The returned future will resolve once the read operation is completed.
80122
///
81123
/// In the case of an error the buffer and the object will be discarded, with
82124
/// the error yielded.
125+
///
126+
/// # Examples
127+
///
128+
/// ```
129+
/// #![feature(async_await, await_macro, futures_api)]
130+
/// # futures::executor::block_on(async {
131+
/// use futures::io::AsyncReadExt;
132+
/// use std::io::Cursor;
133+
///
134+
/// let mut reader = Cursor::new([1, 2, 3, 4]);
135+
/// let mut output = [0u8; 4];
136+
///
137+
/// await!(reader.read_exact(&mut output))?;
138+
///
139+
/// assert_eq!(output, [1, 2, 3, 4]);
140+
/// # Ok::<(), Box<std::error::Error>>(()) }).unwrap();
141+
/// ```
142+
///
143+
/// ## EOF is hit before `buf` is filled
144+
///
145+
/// ```
146+
/// #![feature(async_await, await_macro, futures_api)]
147+
/// # futures::executor::block_on(async {
148+
/// use futures::io::AsyncReadExt;
149+
/// use std::io::{self, Cursor};
150+
///
151+
/// let mut reader = Cursor::new([1, 2, 3, 4]);
152+
/// let mut output = [0u8; 5];
153+
///
154+
/// let result = await!(reader.read_exact(&mut output));
155+
///
156+
/// assert_eq!(result.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
157+
/// # });
158+
/// ```
83159
fn read_exact<'a>(
84160
&'a mut self,
85161
buf: &'a mut [u8],
@@ -88,6 +164,23 @@ pub trait AsyncReadExt: AsyncRead {
88164
}
89165

90166
/// Creates a future which will read all the bytes from this `AsyncRead`.
167+
///
168+
/// # Examples
169+
///
170+
/// ```
171+
/// #![feature(async_await, await_macro, futures_api)]
172+
/// # futures::executor::block_on(async {
173+
/// use futures::io::AsyncReadExt;
174+
/// use std::io::Cursor;
175+
///
176+
/// let mut reader = Cursor::new([1, 2, 3, 4]);
177+
/// let mut output = Vec::with_capacity(4);
178+
///
179+
/// await!(reader.read_to_end(&mut output))?;
180+
///
181+
/// assert_eq!(output, vec![1, 2, 3, 4]);
182+
/// # Ok::<(), Box<std::error::Error>>(()) }).unwrap();
183+
/// ```
91184
fn read_to_end<'a>(
92185
&'a mut self,
93186
buf: &'a mut Vec<u8>,
@@ -97,8 +190,36 @@ pub trait AsyncReadExt: AsyncRead {
97190

98191
/// Helper method for splitting this read/write object into two halves.
99192
///
100-
/// The two halves returned implement the `Read` and `Write` traits,
101-
/// respectively.
193+
/// The two halves returned implement the `AsyncRead` and `AsyncWrite`
194+
/// traits, respectively.
195+
///
196+
/// # Examples
197+
///
198+
/// ```
199+
/// #![feature(async_await, await_macro, futures_api)]
200+
/// # futures::executor::block_on(async {
201+
/// use futures::io::AsyncReadExt;
202+
/// use std::io::Cursor;
203+
///
204+
/// let mut reader = Cursor::new([1, 2, 3, 4]);
205+
/// let mut buffer = [0, 0, 0, 0, 5, 6, 7, 8];
206+
/// let mut output = [0u8; 5];
207+
///
208+
/// {
209+
/// let mut writer = Cursor::new(&mut output[..]);
210+
/// // Note that for `Cursor` the read and write halves share a single
211+
/// // seek position. This may or may not be true for other types that
212+
/// // implement both `AsyncRead` and `AsyncWrite`.
213+
/// let buffer_cursor = Cursor::new(&mut buffer[..]);
214+
/// let (mut buffer_reader, mut buffer_writer) = buffer_cursor.split();
215+
/// await!(reader.copy_into(&mut buffer_writer))?;
216+
/// await!(buffer_reader.copy_into(&mut writer))?;
217+
/// }
218+
///
219+
/// assert_eq!(buffer, [1, 2, 3, 4, 5, 6, 7, 8]);
220+
/// assert_eq!(output, [5, 6, 7, 8, 0]);
221+
/// # Ok::<(), Box<std::error::Error>>(()) }).unwrap();
222+
/// ```
102223
fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>)
103224
where Self: AsyncWrite + Sized,
104225
{
@@ -111,6 +232,28 @@ impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}
111232
/// An extension trait which adds utility methods to `AsyncWrite` types.
112233
pub trait AsyncWriteExt: AsyncWrite {
113234
/// Creates a future which will entirely flush this `AsyncWrite`.
235+
///
236+
/// # Examples
237+
///
238+
/// ```
239+
/// #![feature(async_await, await_macro, futures_api)]
240+
/// # futures::executor::block_on(async {
241+
/// use futures::io::{AllowStdIo, AsyncWriteExt};
242+
/// use std::io::{BufWriter, Cursor};
243+
///
244+
/// let mut output = [0u8; 5];
245+
///
246+
/// {
247+
/// let mut writer = Cursor::new(&mut output[..]);
248+
/// let mut buffered = AllowStdIo::new(BufWriter::new(writer));
249+
/// await!(buffered.write_all(&[1, 2]))?;
250+
/// await!(buffered.write_all(&[3, 4]))?;
251+
/// await!(buffered.flush())?;
252+
/// }
253+
///
254+
/// assert_eq!(output, [1, 2, 3, 4, 0]);
255+
/// # Ok::<(), Box<std::error::Error>>(()) }).unwrap();
256+
/// ```
114257
fn flush<'a>(&'a mut self) -> Flush<'a, Self> {
115258
Flush::new(self)
116259
}
@@ -126,6 +269,25 @@ pub trait AsyncWriteExt: AsyncWrite {
126269
/// this `AsyncWrite`.
127270
///
128271
/// The returned future will not complete until all the data has been written.
272+
///
273+
/// # Examples
274+
///
275+
/// ```
276+
/// #![feature(async_await, await_macro, futures_api)]
277+
/// # futures::executor::block_on(async {
278+
/// use futures::io::AsyncWriteExt;
279+
/// use std::io::Cursor;
280+
///
281+
/// let mut output = [0u8; 5];
282+
///
283+
/// {
284+
/// let mut writer = Cursor::new(&mut output[..]);
285+
/// await!(writer.write_all(&[1, 2, 3, 4]))?;
286+
/// }
287+
///
288+
/// assert_eq!(output, [1, 2, 3, 4, 0]);
289+
/// # Ok::<(), Box<std::error::Error>>(()) }).unwrap();
290+
/// ```
129291
fn write_all<'a>(&'a mut self, buf: &'a [u8]) -> WriteAll<'a, Self> {
130292
WriteAll::new(self, buf)
131293
}

futures-util/src/io/write_all.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ impl<'a, W: AsyncWrite + ?Sized> Future for WriteAll<'a, W> {
3737
while !this.buf.is_empty() {
3838
let n = try_ready!(this.writer.poll_write(cx, this.buf));
3939
{
40-
let (rest, _) = mem::replace(&mut this.buf, &[]).split_at(n);
40+
let (_, rest) = mem::replace(&mut this.buf, &[]).split_at(n);
4141
this.buf = rest;
4242
}
4343
if n == 0 {

0 commit comments

Comments
 (0)