diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index 53fc94b..59e9bfb 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -303,6 +303,44 @@ extension_trait! { { take::Take { inner: self, limit } } + + #[doc = r#" + Creates a "by reference" adaptor for this instance of `Read`. + + The returned adaptor also implements `Read` and will simply borrow this + current reader. + + # Examples + + [`File`][file]s implement `Read`: + + [file]: ../fs/struct.File.html + + ```no_run + use async_std::io; + use async_std::prelude::*; + use async_std::fs::File; + + fn main() -> io::Result<()> { async_std::task::block_on(async { + let mut f = File::open("foo.txt").await?; + let mut buffer = Vec::new(); + let mut other_buffer = Vec::new(); + + { + let reference = f.by_ref(); + + // read at most 5 bytes + reference.take(5).read_to_end(&mut buffer).await?; + + } // drop our &mut reference so we can use f again + + // original file still usable, read the rest + f.read_to_end(&mut other_buffer).await?; + Ok(()) + }) } + ``` + "#] + fn by_ref(&mut self) -> &mut Self where Self: Sized { self } } impl Read for Box { @@ -349,3 +387,31 @@ extension_trait! { } } } + +#[cfg(test)] +mod tests { + use crate::io; + use crate::prelude::*; + + #[test] + fn test_read_by_ref() -> io::Result<()> { + crate::task::block_on(async { + let mut f = io::Cursor::new(vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8]); + let mut buffer = Vec::new(); + let mut other_buffer = Vec::new(); + + { + let reference = f.by_ref(); + + // read at most 5 bytes + assert_eq!(reference.take(5).read_to_end(&mut buffer).await?, 5); + assert_eq!(&buffer, &[0, 1, 2, 3, 4]) + } // drop our &mut reference so we can use f again + + // original file still usable, read the rest + assert_eq!(f.read_to_end(&mut other_buffer).await?, 4); + assert_eq!(&other_buffer, &[5, 6, 7, 8]); + Ok(()) + }) + } +}