From a639fbb728583684b118562e97a5818d4acf9d0d Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Wed, 5 May 2021 01:51:50 +0900 Subject: [PATCH 01/18] add MultiReader and TeeReader --- chapter3/Cargo.toml | 3 +++ chapter3/src/3_7/main.rs | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 chapter3/src/3_7/main.rs diff --git a/chapter3/Cargo.toml b/chapter3/Cargo.toml index 2506c69..311c7f1 100644 --- a/chapter3/Cargo.toml +++ b/chapter3/Cargo.toml @@ -86,3 +86,6 @@ path = "src/3_6_3/main.rs" [[bin]] name = "3_6_2" path = "src/3_6_2/main.rs" +[[bin]] +name = "3_7" +path = "src/3_7/main.rs" diff --git a/chapter3/src/3_7/main.rs b/chapter3/src/3_7/main.rs new file mode 100644 index 0000000..6a8f426 --- /dev/null +++ b/chapter3/src/3_7/main.rs @@ -0,0 +1,51 @@ +use std::io::{Read, Write}; + +struct MultiReader(Vec>); + +impl MultiReader { + pub fn new(readers: Vec>) -> Self { + Self(readers) + } +} + +impl Read for MultiReader { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + for r in &mut self.0 { + r.read(buf)?; + } + Ok(buf.len()) + } +} + +struct TeeReader +where + R: Read, + W: Write, +{ + reader: R, + writer: W, +} + +impl TeeReader +where + R: Read, + W: Write, +{ + pub fn new(reader: R, writer: W) -> Self { + Self { reader, writer } + } +} + +impl Read for TeeReader +where + R: Read, + W: Write, +{ + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let n = self.reader.read(buf)?; + self.writer.write_all(&buf[..n])?; + Ok(n) + } +} + +fn main() {} From 452abe1d0c1085e2267a695e4915f751e89c8373 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Wed, 5 May 2021 23:09:53 +0900 Subject: [PATCH 02/18] fix MultiReader to run it correctly --- chapter3/src/3_7/main.rs | 58 +++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/chapter3/src/3_7/main.rs b/chapter3/src/3_7/main.rs index 6a8f426..7dff8fe 100644 --- a/chapter3/src/3_7/main.rs +++ b/chapter3/src/3_7/main.rs @@ -1,19 +1,35 @@ -use std::io::{Read, Write}; +//! Rust には MultiReader と TeeReader は存在しないため、それらを自前で実装して用意しています。 -struct MultiReader(Vec>); +use std::{ + io::{copy, stdout, Read, Write}, + usize, +}; -impl MultiReader { - pub fn new(readers: Vec>) -> Self { - Self(readers) +pub struct MultiReader { + readers: Vec, + pos: usize, +} + +impl MultiReader { + fn new(readers: Vec) -> Self { + Self { readers, pos: 0 } } } -impl Read for MultiReader { +impl Read for MultiReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - for r in &mut self.0 { - r.read(buf)?; + loop { + match self.readers.get_mut(self.pos) { + Some(r) => { + let n = r.read(buf)?; + if n > 0 { + return Ok(n); + } + } + None => return Ok(0), + } + self.pos = self.pos + 1; } - Ok(buf.len()) } } @@ -48,4 +64,26 @@ where } } -fn main() {} +fn main() -> std::io::Result<()> { + let header = "---- HEADER ----\n".as_bytes(); + let content = "Example of MultiReader\n".as_bytes(); + let footer = "---- FOOTER ----\n".as_bytes(); + let mut multi_reader = MultiReader::new(vec![header, content, footer]); + copy(&mut multi_reader, &mut stdout())?; + + // TeeReader を使用した場合の例。 + let mut buf = Vec::new(); + let reader = "Example of TeeReader".as_bytes(); + let mut tee_reader = TeeReader::new(reader, &mut buf); + // データを読み捨てる。 + let _ = tee_reader.read_to_end(&mut Vec::new())?; + + println!( + "{}", + // けどバッファには残っている。 + String::from_utf8(buf) + .expect("UTF-8 形式でない文字列の可能性があります。UTF-8 にしてください。") + ); + + Ok(()) +} From 973d0e32a35d8e3ac58956b6ae85364d4c5efbbc Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Wed, 5 May 2021 23:10:39 +0900 Subject: [PATCH 03/18] fix visiblity --- chapter3/src/3_7/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chapter3/src/3_7/main.rs b/chapter3/src/3_7/main.rs index 7dff8fe..258f5e0 100644 --- a/chapter3/src/3_7/main.rs +++ b/chapter3/src/3_7/main.rs @@ -5,7 +5,7 @@ use std::{ usize, }; -pub struct MultiReader { +struct MultiReader { readers: Vec, pos: usize, } @@ -47,7 +47,7 @@ where R: Read, W: Write, { - pub fn new(reader: R, writer: W) -> Self { + fn new(reader: R, writer: W) -> Self { Self { reader, writer } } } From 5e638cfe0c32dc3b364fff48ccd232e72d1c811c Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Wed, 5 May 2021 23:16:28 +0900 Subject: [PATCH 04/18] move MultiReader to lib --- chapter3/src/3_7/main.rs | 28 +--------------------------- lib/src/io.rs | 2 ++ lib/src/io/multi_reader.rs | 29 +++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 lib/src/io/multi_reader.rs diff --git a/chapter3/src/3_7/main.rs b/chapter3/src/3_7/main.rs index 258f5e0..0c71758 100644 --- a/chapter3/src/3_7/main.rs +++ b/chapter3/src/3_7/main.rs @@ -5,33 +5,7 @@ use std::{ usize, }; -struct MultiReader { - readers: Vec, - pos: usize, -} - -impl MultiReader { - fn new(readers: Vec) -> Self { - Self { readers, pos: 0 } - } -} - -impl Read for MultiReader { - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - loop { - match self.readers.get_mut(self.pos) { - Some(r) => { - let n = r.read(buf)?; - if n > 0 { - return Ok(n); - } - } - None => return Ok(0), - } - self.pos = self.pos + 1; - } - } -} +use lib::io::MultiReader; struct TeeReader where diff --git a/lib/src/io.rs b/lib/src/io.rs index 7c9ea0a..97b7d5f 100644 --- a/lib/src/io.rs +++ b/lib/src/io.rs @@ -1,7 +1,9 @@ mod limited_reader; +mod multi_reader; mod multi_writer; mod section_reader; pub use limited_reader::LimitedReader; +pub use multi_reader::MultiReader; pub use multi_writer::MultiWriter; pub use section_reader::SectionReader; diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs new file mode 100644 index 0000000..65dd442 --- /dev/null +++ b/lib/src/io/multi_reader.rs @@ -0,0 +1,29 @@ +use std::io::Read; + +pub struct MultiReader { + readers: Vec, + pos: usize, +} + +impl MultiReader { + pub fn new(readers: Vec) -> Self { + Self { readers, pos: 0 } + } +} + +impl Read for MultiReader { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + loop { + match self.readers.get_mut(self.pos) { + Some(r) => { + let n = r.read(buf)?; + if n > 0 { + return Ok(n); + } + } + None => return Ok(0), + } + self.pos = self.pos + 1; + } + } +} From 83b811b151b9f8a13a3d552f15eceeade7450bbb Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Wed, 5 May 2021 23:27:53 +0900 Subject: [PATCH 05/18] add docs --- lib/src/io/multi_reader.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index 65dd442..ff3b9ab 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -1,11 +1,34 @@ use std::io::Read; +/// Takes multiple `std::io::Read` at once. +/// This is inspired by `io.MultiReader` in Go. +/// +/// # Example +/// +/// ``` +/// use std::{ +/// io::{copy, stdout, Read}, +/// usize, +/// }; +/// use lib::io::MultiReader; +/// +/// fn main() -> std::io::Result<()> { +/// let header = "---- HEADER ----\n".as_bytes(); +/// let content = "Example of MultiReader\n".as_bytes(); +/// let footer = "---- FOOTER ----\n".as_bytes(); +/// let mut multi_reader = MultiReader::new(vec![header, content, footer]); +/// copy(&mut multi_reader, &mut stdout())?; +/// Ok(()) +/// } +/// ``` pub struct MultiReader { readers: Vec, + /// Points to where we read right now. pos: usize, } impl MultiReader { + /// Creates `MultiReader`. `pos` is set to 0 by default. pub fn new(readers: Vec) -> Self { Self { readers, pos: 0 } } From ebfcc5dba6e003f7aa7ea6c2775d383bcf609df3 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Wed, 5 May 2021 23:36:19 +0900 Subject: [PATCH 06/18] divide files --- chapter3/Cargo.toml | 6 ++++++ chapter3/src/3_7/multi_reader.rs | 13 +++++++++++++ chapter3/src/3_7/{main.rs => tee_reader.rs} | 15 +-------------- lib/src/io/multi_reader.rs | 2 +- 4 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 chapter3/src/3_7/multi_reader.rs rename chapter3/src/3_7/{main.rs => tee_reader.rs} (67%) diff --git a/chapter3/Cargo.toml b/chapter3/Cargo.toml index 311c7f1..eac8669 100644 --- a/chapter3/Cargo.toml +++ b/chapter3/Cargo.toml @@ -89,3 +89,9 @@ path = "src/3_6_2/main.rs" [[bin]] name = "3_7" path = "src/3_7/main.rs" +[[bin]] +name = "3_7_multi" +path = "src/3_7/multi_reader.rs" +[[bin]] +name = "3_7_tee" +path = "src/3_7/tee_reader.rs" diff --git a/chapter3/src/3_7/multi_reader.rs b/chapter3/src/3_7/multi_reader.rs new file mode 100644 index 0000000..5143534 --- /dev/null +++ b/chapter3/src/3_7/multi_reader.rs @@ -0,0 +1,13 @@ +use std::io::{copy, stdout}; + +use lib::io::MultiReader; + +fn main() -> std::io::Result<()> { + let header = "---- HEADER ----\n".as_bytes(); + let content = "Example of MultiReader\n".as_bytes(); + let footer = "---- FOOTER ----\n".as_bytes(); + let mut multi_reader = MultiReader::new(vec![header, content, footer]); + copy(&mut multi_reader, &mut stdout())?; + + Ok(()) +} diff --git a/chapter3/src/3_7/main.rs b/chapter3/src/3_7/tee_reader.rs similarity index 67% rename from chapter3/src/3_7/main.rs rename to chapter3/src/3_7/tee_reader.rs index 0c71758..b3dadd5 100644 --- a/chapter3/src/3_7/main.rs +++ b/chapter3/src/3_7/tee_reader.rs @@ -1,11 +1,4 @@ -//! Rust には MultiReader と TeeReader は存在しないため、それらを自前で実装して用意しています。 - -use std::{ - io::{copy, stdout, Read, Write}, - usize, -}; - -use lib::io::MultiReader; +use std::io::{Read, Write}; struct TeeReader where @@ -39,12 +32,6 @@ where } fn main() -> std::io::Result<()> { - let header = "---- HEADER ----\n".as_bytes(); - let content = "Example of MultiReader\n".as_bytes(); - let footer = "---- FOOTER ----\n".as_bytes(); - let mut multi_reader = MultiReader::new(vec![header, content, footer]); - copy(&mut multi_reader, &mut stdout())?; - // TeeReader を使用した場合の例。 let mut buf = Vec::new(); let reader = "Example of TeeReader".as_bytes(); diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index ff3b9ab..0c72cb1 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -46,7 +46,7 @@ impl Read for MultiReader { } None => return Ok(0), } - self.pos = self.pos + 1; + self.pos += 1; } } } From fba2582608555620ae01fb59833370dd4f362247 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Thu, 6 May 2021 09:56:37 +0900 Subject: [PATCH 07/18] add Read constraint --- lib/src/io/multi_reader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index 0c72cb1..446060b 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -21,7 +21,7 @@ use std::io::Read; /// Ok(()) /// } /// ``` -pub struct MultiReader { +pub struct MultiReader { readers: Vec, /// Points to where we read right now. pos: usize, From 2a4cde17bead0848ece98862760c969c8d7c22cc Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Thu, 6 May 2021 09:58:22 +0900 Subject: [PATCH 08/18] move TeeReader to lib --- chapter3/src/3_7/tee_reader.rs | 34 ++-------------------------------- lib/src/io.rs | 2 ++ lib/src/io/tee_reader.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 32 deletions(-) create mode 100644 lib/src/io/tee_reader.rs diff --git a/chapter3/src/3_7/tee_reader.rs b/chapter3/src/3_7/tee_reader.rs index b3dadd5..f2a6fae 100644 --- a/chapter3/src/3_7/tee_reader.rs +++ b/chapter3/src/3_7/tee_reader.rs @@ -1,35 +1,5 @@ -use std::io::{Read, Write}; - -struct TeeReader -where - R: Read, - W: Write, -{ - reader: R, - writer: W, -} - -impl TeeReader -where - R: Read, - W: Write, -{ - fn new(reader: R, writer: W) -> Self { - Self { reader, writer } - } -} - -impl Read for TeeReader -where - R: Read, - W: Write, -{ - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - let n = self.reader.read(buf)?; - self.writer.write_all(&buf[..n])?; - Ok(n) - } -} +use lib::io::TeeReader; +use std::io::Read; fn main() -> std::io::Result<()> { // TeeReader を使用した場合の例。 diff --git a/lib/src/io.rs b/lib/src/io.rs index 97b7d5f..1e53116 100644 --- a/lib/src/io.rs +++ b/lib/src/io.rs @@ -2,8 +2,10 @@ mod limited_reader; mod multi_reader; mod multi_writer; mod section_reader; +mod tee_reader; pub use limited_reader::LimitedReader; pub use multi_reader::MultiReader; pub use multi_writer::MultiWriter; pub use section_reader::SectionReader; +pub use tee_reader::TeeReader; diff --git a/lib/src/io/tee_reader.rs b/lib/src/io/tee_reader.rs new file mode 100644 index 0000000..3341976 --- /dev/null +++ b/lib/src/io/tee_reader.rs @@ -0,0 +1,32 @@ +use std::io::{Read, Write}; + +pub struct TeeReader +where + R: Read, + W: Write, +{ + reader: R, + writer: W, +} + +impl TeeReader +where + R: Read, + W: Write, +{ + pub fn new(reader: R, writer: W) -> Self { + Self { reader, writer } + } +} + +impl Read for TeeReader +where + R: Read, + W: Write, +{ + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let n = self.reader.read(buf)?; + self.writer.write_all(&buf[..n])?; + Ok(n) + } +} From 4bb9178a9ca8b48ba4c1c5f35c1e28ca6135c88f Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Fri, 7 May 2021 07:47:44 +0900 Subject: [PATCH 09/18] replace Vec to VecDeque --- chapter3/src/3_7/multi_reader.rs | 7 +++++-- lib/src/io/multi_reader.rs | 17 +++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/chapter3/src/3_7/multi_reader.rs b/chapter3/src/3_7/multi_reader.rs index 5143534..f7594a2 100644 --- a/chapter3/src/3_7/multi_reader.rs +++ b/chapter3/src/3_7/multi_reader.rs @@ -1,4 +1,7 @@ -use std::io::{copy, stdout}; +use std::{ + collections::VecDeque, + io::{copy, stdout}, +}; use lib::io::MultiReader; @@ -6,7 +9,7 @@ fn main() -> std::io::Result<()> { let header = "---- HEADER ----\n".as_bytes(); let content = "Example of MultiReader\n".as_bytes(); let footer = "---- FOOTER ----\n".as_bytes(); - let mut multi_reader = MultiReader::new(vec![header, content, footer]); + let mut multi_reader = MultiReader::new(VecDeque::from(vec![header, content, footer])); copy(&mut multi_reader, &mut stdout())?; Ok(()) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index 446060b..a9e0252 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -1,4 +1,4 @@ -use std::io::Read; +use std::{collections::VecDeque, io::Read}; /// Takes multiple `std::io::Read` at once. /// This is inspired by `io.MultiReader` in Go. @@ -22,23 +22,24 @@ use std::io::Read; /// } /// ``` pub struct MultiReader { - readers: Vec, + readers: VecDeque, /// Points to where we read right now. - pos: usize, + current: Option, } impl MultiReader { /// Creates `MultiReader`. `pos` is set to 0 by default. - pub fn new(readers: Vec) -> Self { - Self { readers, pos: 0 } + pub fn new(mut readers: VecDeque) -> Self { + let current = readers.pop_front(); + Self { readers, current } } } impl Read for MultiReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { loop { - match self.readers.get_mut(self.pos) { - Some(r) => { + match self.current.take() { + Some(ref mut r) => { let n = r.read(buf)?; if n > 0 { return Ok(n); @@ -46,7 +47,7 @@ impl Read for MultiReader { } None => return Ok(0), } - self.pos += 1; + self.current = self.readers.pop_front(); } } } From 1f2ba898baa18a20b2f6744e0f08ad8960ecd99a Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Fri, 7 May 2021 09:05:34 +0900 Subject: [PATCH 10/18] bug fix (shouldn't use take()) --- lib/src/io/multi_reader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index a9e0252..4c5b296 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -38,7 +38,7 @@ impl MultiReader { impl Read for MultiReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { loop { - match self.current.take() { + match self.current { Some(ref mut r) => { let n = r.read(buf)?; if n > 0 { From ad34ff6fc967d1a3061da0b6baa0402699c14417 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Fri, 7 May 2021 09:10:36 +0900 Subject: [PATCH 11/18] use trait object instead of generics --- lib/src/io/multi_reader.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index 4c5b296..2174753 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -21,21 +21,21 @@ use std::{collections::VecDeque, io::Read}; /// Ok(()) /// } /// ``` -pub struct MultiReader { - readers: VecDeque, +pub struct MultiReader { + readers: VecDeque>, /// Points to where we read right now. - current: Option, + current: Option>, } -impl MultiReader { +impl MultiReader { /// Creates `MultiReader`. `pos` is set to 0 by default. - pub fn new(mut readers: VecDeque) -> Self { + pub fn new(mut readers: VecDeque>) -> Self { let current = readers.pop_front(); Self { readers, current } } } -impl Read for MultiReader { +impl Read for MultiReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { loop { match self.current { From 4cf3fa8f78f83ebed67ba54a22350b423264f3a1 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Fri, 7 May 2021 09:11:35 +0900 Subject: [PATCH 12/18] box --- chapter3/src/3_7/multi_reader.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/chapter3/src/3_7/multi_reader.rs b/chapter3/src/3_7/multi_reader.rs index f7594a2..090a82a 100644 --- a/chapter3/src/3_7/multi_reader.rs +++ b/chapter3/src/3_7/multi_reader.rs @@ -9,7 +9,11 @@ fn main() -> std::io::Result<()> { let header = "---- HEADER ----\n".as_bytes(); let content = "Example of MultiReader\n".as_bytes(); let footer = "---- FOOTER ----\n".as_bytes(); - let mut multi_reader = MultiReader::new(VecDeque::from(vec![header, content, footer])); + let mut multi_reader = MultiReader::new(VecDeque::from(vec![ + Box::new(header), + Box::new(content), + Box::new(footer), + ])); copy(&mut multi_reader, &mut stdout())?; Ok(()) From 0285b146905d16fef8989f429ca1aa61c6f3cb92 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Fri, 7 May 2021 09:13:00 +0900 Subject: [PATCH 13/18] add casting --- chapter3/src/3_7/multi_reader.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chapter3/src/3_7/multi_reader.rs b/chapter3/src/3_7/multi_reader.rs index 090a82a..c290c56 100644 --- a/chapter3/src/3_7/multi_reader.rs +++ b/chapter3/src/3_7/multi_reader.rs @@ -1,6 +1,6 @@ use std::{ collections::VecDeque, - io::{copy, stdout}, + io::{copy, stdout, Read}, }; use lib::io::MultiReader; @@ -10,9 +10,9 @@ fn main() -> std::io::Result<()> { let content = "Example of MultiReader\n".as_bytes(); let footer = "---- FOOTER ----\n".as_bytes(); let mut multi_reader = MultiReader::new(VecDeque::from(vec![ - Box::new(header), - Box::new(content), - Box::new(footer), + Box::new(header) as Box, + Box::new(content) as Box, + Box::new(footer) as Box, ])); copy(&mut multi_reader, &mut stdout())?; From 039e6a90c3610a5c382d9d30e4a28c2dcab190c0 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Fri, 7 May 2021 09:31:19 +0900 Subject: [PATCH 14/18] enable to pass doc test --- lib/src/io/multi_reader.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index 2174753..e526980 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -7,8 +7,8 @@ use std::{collections::VecDeque, io::Read}; /// /// ``` /// use std::{ +/// collections::VecDeque, /// io::{copy, stdout, Read}, -/// usize, /// }; /// use lib::io::MultiReader; /// @@ -16,7 +16,11 @@ use std::{collections::VecDeque, io::Read}; /// let header = "---- HEADER ----\n".as_bytes(); /// let content = "Example of MultiReader\n".as_bytes(); /// let footer = "---- FOOTER ----\n".as_bytes(); -/// let mut multi_reader = MultiReader::new(vec![header, content, footer]); +/// let mut multi_reader = MultiReader::new(VecDeque::from(vec![ +/// Box::new(header) as Box, +/// Box::new(content) as Box, +/// Box::new(footer) as Box, +/// ])); /// copy(&mut multi_reader, &mut stdout())?; /// Ok(()) /// } From 36f6fbedabf590fff102f8779bd7c5a9e4f69b2e Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Fri, 7 May 2021 09:43:31 +0900 Subject: [PATCH 15/18] fix constructor to pass Vec --- chapter3/src/3_7/multi_reader.rs | 12 +++--------- lib/src/io/multi_reader.rs | 26 ++++++++++++-------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/chapter3/src/3_7/multi_reader.rs b/chapter3/src/3_7/multi_reader.rs index c290c56..322883b 100644 --- a/chapter3/src/3_7/multi_reader.rs +++ b/chapter3/src/3_7/multi_reader.rs @@ -1,7 +1,4 @@ -use std::{ - collections::VecDeque, - io::{copy, stdout, Read}, -}; +use std::io::{copy, stdout}; use lib::io::MultiReader; @@ -9,11 +6,8 @@ fn main() -> std::io::Result<()> { let header = "---- HEADER ----\n".as_bytes(); let content = "Example of MultiReader\n".as_bytes(); let footer = "---- FOOTER ----\n".as_bytes(); - let mut multi_reader = MultiReader::new(VecDeque::from(vec![ - Box::new(header) as Box, - Box::new(content) as Box, - Box::new(footer) as Box, - ])); + let mut multi_reader = + MultiReader::new(vec![Box::new(header), Box::new(content), Box::new(footer)]); copy(&mut multi_reader, &mut stdout())?; Ok(()) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index e526980..c0038a7 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -6,36 +6,34 @@ use std::{collections::VecDeque, io::Read}; /// # Example /// /// ``` -/// use std::{ -/// collections::VecDeque, -/// io::{copy, stdout, Read}, -/// }; +/// use std::io::{copy, stdout}; /// use lib::io::MultiReader; /// /// fn main() -> std::io::Result<()> { /// let header = "---- HEADER ----\n".as_bytes(); /// let content = "Example of MultiReader\n".as_bytes(); /// let footer = "---- FOOTER ----\n".as_bytes(); -/// let mut multi_reader = MultiReader::new(VecDeque::from(vec![ -/// Box::new(header) as Box, -/// Box::new(content) as Box, -/// Box::new(footer) as Box, -/// ])); +/// let mut multi_reader = +/// MultiReader::new(vec![Box::new(header), Box::new(content), Box::new(footer)]); /// copy(&mut multi_reader, &mut stdout())?; /// Ok(()) /// } /// ``` pub struct MultiReader { readers: VecDeque>, - /// Points to where we read right now. + /// Points to current element while reading. current: Option>, } impl MultiReader { - /// Creates `MultiReader`. `pos` is set to 0 by default. - pub fn new(mut readers: VecDeque>) -> Self { - let current = readers.pop_front(); - Self { readers, current } + /// Constructs `MultiReader`. `current` is set to the first element that is popped out from `VecDeque`. + pub fn new(readers: Vec>) -> Self { + let mut deque = VecDeque::from(readers); + let current = deque.pop_front(); + Self { + readers: deque, + current, + } } } From 2d773487e2e0167af4d71f5799324e1e48051f44 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Sat, 15 May 2021 01:48:10 +0900 Subject: [PATCH 16/18] use into instread of from --- lib/src/io/multi_reader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index c0038a7..1f9c7e5 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -28,7 +28,7 @@ pub struct MultiReader { impl MultiReader { /// Constructs `MultiReader`. `current` is set to the first element that is popped out from `VecDeque`. pub fn new(readers: Vec>) -> Self { - let mut deque = VecDeque::from(readers); + let mut deque: VecDeque> = readers.into(); let current = deque.pop_front(); Self { readers: deque, From 95840559fec9fec3a6f124dcfb4e7ce122030b59 Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Thu, 20 May 2021 22:46:53 +0900 Subject: [PATCH 17/18] no longer needed --- chapter3/Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/chapter3/Cargo.toml b/chapter3/Cargo.toml index eac8669..62e63c4 100644 --- a/chapter3/Cargo.toml +++ b/chapter3/Cargo.toml @@ -87,9 +87,6 @@ path = "src/3_6_3/main.rs" name = "3_6_2" path = "src/3_6_2/main.rs" [[bin]] -name = "3_7" -path = "src/3_7/main.rs" -[[bin]] name = "3_7_multi" path = "src/3_7/multi_reader.rs" [[bin]] From acdba612dcb1015dd147336043760a177b76d20b Mon Sep 17 00:00:00 2001 From: yuk1ty Date: Thu, 20 May 2021 22:54:27 +0900 Subject: [PATCH 18/18] add comment --- lib/src/io/multi_reader.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/io/multi_reader.rs b/lib/src/io/multi_reader.rs index 1f9c7e5..c355f1b 100644 --- a/lib/src/io/multi_reader.rs +++ b/lib/src/io/multi_reader.rs @@ -39,6 +39,9 @@ impl MultiReader { impl Read for MultiReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + // Doesn't move to the next one until the first one is completely read. + // If the processing ends in the middle of reading the first one, + // it returns the control at that point. loop { match self.current { Some(ref mut r) => {