Skip to content

Commit 1552e8a

Browse files
feat(io): implement Read::by_ref
1 parent 479c1da commit 1552e8a

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

src/io/read/mod.rs

+71
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,42 @@ cfg_if! {
267267
fn take(self, limit: u64) -> Take<Self> where Self: Sized {
268268
unreachable!()
269269
}
270+
271+
/// Creates a "by reference" adaptor for this instance of `Read`.
272+
///
273+
/// The returned adaptor also implements `Read` and will simply borrow this
274+
/// current reader.
275+
///
276+
/// # Examples
277+
///
278+
/// [`File`][file]s implement `Read`:
279+
///
280+
/// [file]: ../fs/struct.File.html
281+
///
282+
/// ```no_run
283+
/// use async_std::io;
284+
/// use async_std::io::Read;
285+
/// use async_std::fs::File;
286+
///
287+
/// fn main() -> io::Result<()> { async_std::task::block_on(async {
288+
/// let mut f = File::open("foo.txt").await?;
289+
/// let mut buffer = Vec::new();
290+
/// let mut other_buffer = Vec::new();
291+
///
292+
/// {
293+
/// let reference = f.by_ref();
294+
///
295+
/// // read at most 5 bytes
296+
/// reference.take(5).read_to_end(&mut buffer).await?;
297+
///
298+
/// } // drop our &mut reference so we can use f again
299+
///
300+
/// // original file still usable, read the rest
301+
/// f.read_to_end(&mut other_buffer).await?;
302+
/// Ok(())
303+
/// }) }
304+
/// ```
305+
fn by_ref(&mut self) -> &mut Self where Self: Sized { unreachable!() }
270306
}
271307

272308
impl<T: Read + Unpin + ?Sized> Read for Box<T> {
@@ -374,6 +410,41 @@ pub trait ReadExt: futures_io::AsyncRead {
374410
{
375411
take::Take { inner: self, limit }
376412
}
413+
414+
fn by_ref(&mut self) -> &mut Self
415+
where
416+
Self: Sized,
417+
{
418+
self
419+
}
377420
}
378421

379422
impl<T: futures_io::AsyncRead + ?Sized> ReadExt for T {}
423+
424+
#[cfg(test)]
425+
mod tests {
426+
use crate::io;
427+
use crate::prelude::*;
428+
429+
#[test]
430+
fn test_read_by_ref() -> io::Result<()> {
431+
crate::task::block_on(async {
432+
let mut f = io::Cursor::new(vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8]);
433+
let mut buffer = Vec::new();
434+
let mut other_buffer = Vec::new();
435+
436+
{
437+
let reference = f.by_ref();
438+
439+
// read at most 5 bytes
440+
assert_eq!(reference.take(5).read_to_end(&mut buffer).await?, 5);
441+
assert_eq!(&buffer, &[0, 1, 2, 3, 4])
442+
} // drop our &mut reference so we can use f again
443+
444+
// original file still usable, read the rest
445+
assert_eq!(f.read_to_end(&mut other_buffer).await?, 4);
446+
assert_eq!(&other_buffer, &[5, 6, 7, 8]);
447+
Ok(())
448+
})
449+
}
450+
}

0 commit comments

Comments
 (0)