From e5b66a6464f2c9e6410d7780329abe74b142e3c1 Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Thu, 23 Dec 2021 19:51:38 +0530 Subject: [PATCH 001/972] Made a paragraph easier to read Fixed a grammatical error and removed unnecessary words to make the paragraph easier to read. --- nostarch/chapter02.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nostarch/chapter02.md b/nostarch/chapter02.md index 6381bbe805..30af63402a 100644 --- a/nostarch/chapter02.md +++ b/nostarch/chapter02.md @@ -278,9 +278,9 @@ on which variant an enum value is when the conditional is evaluated. Chapter 6 will cover enums in more detail. The purpose of these `Result` types is to encode error-handling information. -`Result`’s variants are `Ok` or `Err`. The `Ok` variant indicates the -operation was successful, and inside `Ok` is the successfully generated value. -The `Err` variant means the operation failed, and `Err` contains information +`Result`’s variants are `Ok` and `Err`. The `Ok` variant indicates that the +operation was successful, and it contains the successfully generated value. +The `Err` variant means the operation failed, and it contains information about how or why the operation failed. Values of the `Result` type, like values of any type, have methods defined on From 31259f1a56792887d884c7baf1475d7dde3993af Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Fri, 24 Dec 2021 16:31:05 +0530 Subject: [PATCH 002/972] Corrected error message --- nostarch/chapter03.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostarch/chapter03.md b/nostarch/chapter03.md index 2a00baffe4..9292b03e47 100644 --- a/nostarch/chapter03.md +++ b/nostarch/chapter03.md @@ -76,7 +76,7 @@ isn’t safely doing what you want it to do yet; they do *not* mean that you’r not a good programmer! Experienced Rustaceans still get compiler errors. The error message indicates that the cause of the error is that you `` cannot -assign twice to immutable variable `x` ``, because you tried to assign a second +assign twice to immutable variable ``, because you tried to assign a second value to the immutable `x` variable. It’s important that we get compile-time errors when we attempt to change a From 88c84194b995ba3cbb53d3c0a983996fe2700037 Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Sun, 26 Dec 2021 00:57:10 +0530 Subject: [PATCH 003/972] Fixed a grammatical error --- nostarch/chapter04.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostarch/chapter04.md b/nostarch/chapter04.md index 8334bf1202..041f3f1590 100644 --- a/nostarch/chapter04.md +++ b/nostarch/chapter04.md @@ -95,7 +95,7 @@ strings. > data on the heap so you don’t run out of space are all problems that ownership > addresses. Once you understand ownership, you won’t need to think about the > stack and the heap very often, but knowing that the main purpose of ownership -> is to manage heap data can help explain why it works the way it does. +> is to manage heap data and can help explain why it works the way it does. ### Ownership Rules From 704858157597be78a4c00563835a04d3fc20bee7 Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Sun, 26 Dec 2021 01:04:08 +0530 Subject: [PATCH 004/972] Fixed another grammatical error --- nostarch/chapter04.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostarch/chapter04.md b/nostarch/chapter04.md index 041f3f1590..ec8aa0eb2c 100644 --- a/nostarch/chapter04.md +++ b/nostarch/chapter04.md @@ -150,7 +150,7 @@ understanding by introducing the `String` type. To illustrate the rules of ownership, we need a data type that is more complex than those we covered in the “Data Types” section of Chapter 3. The types -covered previously are all a known size, can be stored on the stack and popped +covered previously are all of a known size, can be stored on the stack and popped off the stack when their scope is over, and can be quickly and trivially copied to make a new, independent instance if another part of code needs to use the same value in a different scope. But we want to look at data that is stored on From 7653f1edbafee02d7b753870ba5c96e65bac7f49 Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Mon, 27 Dec 2021 14:02:48 +0530 Subject: [PATCH 005/972] Fixed grammatical error --- nostarch/chapter02.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostarch/chapter02.md b/nostarch/chapter02.md index 30af63402a..09459e94d8 100644 --- a/nostarch/chapter02.md +++ b/nostarch/chapter02.md @@ -278,7 +278,7 @@ on which variant an enum value is when the conditional is evaluated. Chapter 6 will cover enums in more detail. The purpose of these `Result` types is to encode error-handling information. -`Result`’s variants are `Ok` and `Err`. The `Ok` variant indicates that the +`Result`’s variants are `Ok` and `Err`. The `Ok` variant indicates the operation was successful, and it contains the successfully generated value. The `Err` variant means the operation failed, and it contains information about how or why the operation failed. From 15d063198b93c932b1e3b9848b63c993486f2054 Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Mon, 27 Dec 2021 14:03:57 +0530 Subject: [PATCH 006/972] Fixed grammatical error --- nostarch/chapter03.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostarch/chapter03.md b/nostarch/chapter03.md index 9292b03e47..2a00baffe4 100644 --- a/nostarch/chapter03.md +++ b/nostarch/chapter03.md @@ -76,7 +76,7 @@ isn’t safely doing what you want it to do yet; they do *not* mean that you’r not a good programmer! Experienced Rustaceans still get compiler errors. The error message indicates that the cause of the error is that you `` cannot -assign twice to immutable variable ``, because you tried to assign a second +assign twice to immutable variable `x` ``, because you tried to assign a second value to the immutable `x` variable. It’s important that we get compile-time errors when we attempt to change a From 74c9d7159fbcd1437db714cc2572afe67b5df76e Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Mon, 27 Dec 2021 14:04:40 +0530 Subject: [PATCH 007/972] Fixed grammatical error --- nostarch/chapter04.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostarch/chapter04.md b/nostarch/chapter04.md index ec8aa0eb2c..4e429b0971 100644 --- a/nostarch/chapter04.md +++ b/nostarch/chapter04.md @@ -95,7 +95,7 @@ strings. > data on the heap so you don’t run out of space are all problems that ownership > addresses. Once you understand ownership, you won’t need to think about the > stack and the heap very often, but knowing that the main purpose of ownership -> is to manage heap data and can help explain why it works the way it does. +> is to manage heap data can help explain why it works the way it does. ### Ownership Rules From 7226d001712ec48897d1edf9318ad0479e0b0f44 Mon Sep 17 00:00:00 2001 From: Joel Jose Date: Mon, 27 Dec 2021 14:06:03 +0530 Subject: [PATCH 008/972] Fixed grammatical error --- nostarch/chapter04.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nostarch/chapter04.md b/nostarch/chapter04.md index 4e429b0971..8334bf1202 100644 --- a/nostarch/chapter04.md +++ b/nostarch/chapter04.md @@ -150,7 +150,7 @@ understanding by introducing the `String` type. To illustrate the rules of ownership, we need a data type that is more complex than those we covered in the “Data Types” section of Chapter 3. The types -covered previously are all of a known size, can be stored on the stack and popped +covered previously are all a known size, can be stored on the stack and popped off the stack when their scope is over, and can be quickly and trivially copied to make a new, independent instance if another part of code needs to use the same value in a different scope. But we want to look at data that is stored on From d5b9289b4a7839d738a5e866a86e155a5b9f6d96 Mon Sep 17 00:00:00 2001 From: Aadeetya <49238500+0xAtsign@users.noreply.github.com> Date: Thu, 26 May 2022 23:26:08 +0530 Subject: [PATCH 009/972] Fixed grammatical error in the comment on line 22 --- listings/ch04-understanding-ownership/listing-04-08/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/listings/ch04-understanding-ownership/listing-04-08/src/main.rs b/listings/ch04-understanding-ownership/listing-04-08/src/main.rs index b6182fe2b7..4a09bc34ab 100644 --- a/listings/ch04-understanding-ownership/listing-04-08/src/main.rs +++ b/listings/ch04-understanding-ownership/listing-04-08/src/main.rs @@ -19,6 +19,6 @@ fn main() { s.clear(); // this empties the String, making it equal to "" // word still has the value 5 here, but there's no more string that - // we could meaningfully use the value 5 with. word is now totally invalid! + // we could no longer meaningfully use the value 5 as word is now totally invalid! } // ANCHOR_END: here From f173022b702deacbca2c8a5be689c3d248c7ab66 Mon Sep 17 00:00:00 2001 From: Frank Plowman Date: Mon, 13 Jun 2022 18:37:04 +0100 Subject: [PATCH 010/972] make style of listings 9-7 and 9-8 consistent with 9-6 --- listings/ch09-error-handling/listing-09-07/src/main.rs | 3 +-- listings/ch09-error-handling/listing-09-08/src/main.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/listings/ch09-error-handling/listing-09-07/src/main.rs b/listings/ch09-error-handling/listing-09-07/src/main.rs index f4564f670d..0295949d23 100644 --- a/listings/ch09-error-handling/listing-09-07/src/main.rs +++ b/listings/ch09-error-handling/listing-09-07/src/main.rs @@ -1,7 +1,6 @@ // ANCHOR: here use std::fs::File; -use std::io; -use std::io::Read; +use std::io::{self, Read}; fn read_username_from_file() -> Result { let mut username_file = File::open("hello.txt")?; diff --git a/listings/ch09-error-handling/listing-09-08/src/main.rs b/listings/ch09-error-handling/listing-09-08/src/main.rs index c3c6e23efc..ca672caad0 100644 --- a/listings/ch09-error-handling/listing-09-08/src/main.rs +++ b/listings/ch09-error-handling/listing-09-08/src/main.rs @@ -1,7 +1,6 @@ // ANCHOR: here use std::fs::File; -use std::io; -use std::io::Read; +use std::io::{self, Read}; fn read_username_from_file() -> Result { let mut username = String::new(); From 997d10517522e1b8e04b661fff08ec66474bb064 Mon Sep 17 00:00:00 2001 From: Andrei Date: Wed, 29 Jun 2022 00:00:00 +0000 Subject: [PATCH 011/972] Use Vec::drain() to move thread out of the vector --- .../ch20-web-server/listing-20-23/src/lib.rs | 10 +-- .../ch20-web-server/listing-20-24/src/lib.rs | 10 +-- .../ch20-web-server/listing-20-25/src/lib.rs | 10 +-- .../404.html | 11 --- .../Cargo.lock | 6 -- .../Cargo.toml | 6 -- .../hello.html | 11 --- .../output.txt | 24 ------ .../src/lib.rs | 76 ----------------- .../src/main.rs | 43 ---------- .../no-listing-05-fix-worker-new/404.html | 11 --- .../no-listing-05-fix-worker-new/Cargo.lock | 6 -- .../no-listing-05-fix-worker-new/Cargo.toml | 6 -- .../no-listing-05-fix-worker-new/hello.html | 11 --- .../no-listing-05-fix-worker-new/src/lib.rs | 83 ------------------- .../no-listing-05-fix-worker-new/src/main.rs | 43 ---------- .../src/lib.rs | 10 +-- .../no-listing-07-final-code/src/lib.rs | 10 +-- src/ch20-03-graceful-shutdown-and-cleanup.md | 55 +++--------- 19 files changed, 32 insertions(+), 410 deletions(-) delete mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/404.html delete mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock delete mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.toml delete mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/hello.html delete mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt delete mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs delete mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs delete mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/404.html delete mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock delete mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.toml delete mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/hello.html delete mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs delete mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs diff --git a/listings/ch20-web-server/listing-20-23/src/lib.rs b/listings/ch20-web-server/listing-20-23/src/lib.rs index eea339b027..818ff4e4e7 100644 --- a/listings/ch20-web-server/listing-20-23/src/lib.rs +++ b/listings/ch20-web-server/listing-20-23/src/lib.rs @@ -61,12 +61,10 @@ impl Drop for ThreadPool { fn drop(&mut self) { drop(self.sender.take()); - for worker in &mut self.workers { + for worker in self.workers.drain(..) { println!("Shutting down worker {}", worker.id); - if let Some(thread) = worker.thread.take() { - thread.join().unwrap(); - } + worker.thread.join().unwrap(); } } } @@ -74,7 +72,7 @@ impl Drop for ThreadPool { struct Worker { id: usize, - thread: Option>, + thread: thread::JoinHandle<()>, } impl Worker { @@ -89,7 +87,7 @@ impl Worker { Worker { id, - thread: Some(thread), + thread: thread, } } } diff --git a/listings/ch20-web-server/listing-20-24/src/lib.rs b/listings/ch20-web-server/listing-20-24/src/lib.rs index 55e8fef8fb..21ba33b3ff 100644 --- a/listings/ch20-web-server/listing-20-24/src/lib.rs +++ b/listings/ch20-web-server/listing-20-24/src/lib.rs @@ -51,19 +51,17 @@ impl Drop for ThreadPool { fn drop(&mut self) { drop(self.sender.take()); - for worker in &mut self.workers { + for worker in self.workers.drain(..) { println!("Shutting down worker {}", worker.id); - if let Some(thread) = worker.thread.take() { - thread.join().unwrap(); - } + worker.thread.join().unwrap(); } } } struct Worker { id: usize, - thread: Option>, + thread: thread::JoinHandle<()>, } // ANCHOR: here @@ -85,7 +83,7 @@ impl Worker { Worker { id, - thread: Some(thread), + thread: thread, } } } diff --git a/listings/ch20-web-server/listing-20-25/src/lib.rs b/listings/ch20-web-server/listing-20-25/src/lib.rs index 54c0489abf..7092437f52 100644 --- a/listings/ch20-web-server/listing-20-25/src/lib.rs +++ b/listings/ch20-web-server/listing-20-25/src/lib.rs @@ -51,19 +51,17 @@ impl Drop for ThreadPool { fn drop(&mut self) { drop(self.sender.take()); - for worker in &mut self.workers { + for worker in self.workers.drain(..) { println!("Shutting down worker {}", worker.id); - if let Some(thread) = worker.thread.take() { - thread.join().unwrap(); - } + worker.thread.join().unwrap(); } } } struct Worker { id: usize, - thread: Option>, + thread: thread::JoinHandle<()>, } impl Worker { @@ -86,7 +84,7 @@ impl Worker { Worker { id, - thread: Some(thread), + thread: thread, } } } diff --git a/listings/ch20-web-server/no-listing-04-update-worker-definition/404.html b/listings/ch20-web-server/no-listing-04-update-worker-definition/404.html deleted file mode 100644 index 88d8e9152d..0000000000 --- a/listings/ch20-web-server/no-listing-04-update-worker-definition/404.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Hello! - - -

Oops!

-

Sorry, I don't know what you're asking for.

- - diff --git a/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock b/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock deleted file mode 100644 index f2d069f462..0000000000 --- a/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.toml b/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.toml deleted file mode 100644 index fe619478a6..0000000000 --- a/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "hello" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/listings/ch20-web-server/no-listing-04-update-worker-definition/hello.html b/listings/ch20-web-server/no-listing-04-update-worker-definition/hello.html deleted file mode 100644 index fe442d6b9b..0000000000 --- a/listings/ch20-web-server/no-listing-04-update-worker-definition/hello.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Hello! - - -

Hello!

-

Hi from Rust

- - diff --git a/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt b/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt deleted file mode 100644 index 34d30fe05e..0000000000 --- a/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt +++ /dev/null @@ -1,24 +0,0 @@ -$ cargo check - Checking hello v0.1.0 (file:///projects/hello) -error[E0599]: no method named `join` found for enum `Option` in the current scope - --> src/lib.rs:52:27 - | -52 | worker.thread.join().unwrap(); - | ^^^^ method not found in `Option>` - -error[E0308]: mismatched types - --> src/lib.rs:72:22 - | -72 | Worker { id, thread } - | ^^^^^^ expected enum `Option`, found struct `JoinHandle` - | - = note: expected enum `Option>` - found struct `JoinHandle<_>` -help: try wrapping the expression in `Some` - | -72 | Worker { id, thread: Some(thread) } - | +++++++++++++ + - -Some errors have detailed explanations: E0308, E0599. -For more information about an error, try `rustc --explain E0308`. -error: could not compile `hello` due to 2 previous errors diff --git a/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs b/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs deleted file mode 100644 index 6ef710a26b..0000000000 --- a/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - for worker in &mut self.workers { - println!("Shutting down worker {}", worker.id); - - worker.thread.join().unwrap(); - } - } -} - -// ANCHOR: here -struct Worker { - id: usize, - thread: Option>, -} -// ANCHOR_END: here - -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - let thread = thread::spawn(move || loop { - let job = receiver.lock().unwrap().recv().unwrap(); - - println!("Worker {id} got a job; executing."); - - job(); - }); - - Worker { id, thread } - } -} diff --git a/listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs b/listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs deleted file mode 100644 index 79efb28a2a..0000000000 --- a/listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/listings/ch20-web-server/no-listing-05-fix-worker-new/404.html b/listings/ch20-web-server/no-listing-05-fix-worker-new/404.html deleted file mode 100644 index 88d8e9152d..0000000000 --- a/listings/ch20-web-server/no-listing-05-fix-worker-new/404.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Hello! - - -

Oops!

-

Sorry, I don't know what you're asking for.

- - diff --git a/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock b/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock deleted file mode 100644 index f2d069f462..0000000000 --- a/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.toml b/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.toml deleted file mode 100644 index fe619478a6..0000000000 --- a/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "hello" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/listings/ch20-web-server/no-listing-05-fix-worker-new/hello.html b/listings/ch20-web-server/no-listing-05-fix-worker-new/hello.html deleted file mode 100644 index fe442d6b9b..0000000000 --- a/listings/ch20-web-server/no-listing-05-fix-worker-new/hello.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Hello! - - -

Hello!

-

Hi from Rust

- - diff --git a/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs b/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs deleted file mode 100644 index ede3750a17..0000000000 --- a/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - for worker in &mut self.workers { - println!("Shutting down worker {}", worker.id); - - worker.thread.join().unwrap(); - } - } -} - -struct Worker { - id: usize, - thread: Option>, -} - -// ANCHOR: here -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - // --snip-- - - // ANCHOR_END: here - let thread = thread::spawn(move || loop { - let job = receiver.lock().unwrap().recv().unwrap(); - - println!("Worker {id} got a job; executing."); - - job(); - }); - - // ANCHOR: here - Worker { - id, - thread: Some(thread), - } - } -} -// ANCHOR_END: here diff --git a/listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs b/listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs deleted file mode 100644 index 79efb28a2a..0000000000 --- a/listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs index b795ea53b0..61472adbb4 100644 --- a/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs @@ -47,12 +47,10 @@ impl ThreadPool { // ANCHOR: here impl Drop for ThreadPool { fn drop(&mut self) { - for worker in &mut self.workers { + for worker in self.workers.drain(..) { println!("Shutting down worker {}", worker.id); - if let Some(thread) = worker.thread.take() { - thread.join().unwrap(); - } + worker.thread.join().unwrap(); } } } @@ -60,7 +58,7 @@ impl Drop for ThreadPool { struct Worker { id: usize, - thread: Option>, + thread: thread::JoinHandle<()>, } impl Worker { @@ -75,7 +73,7 @@ impl Worker { Worker { id, - thread: Some(thread), + thread: thread, } } } diff --git a/listings/ch20-web-server/no-listing-07-final-code/src/lib.rs b/listings/ch20-web-server/no-listing-07-final-code/src/lib.rs index 54c0489abf..7092437f52 100644 --- a/listings/ch20-web-server/no-listing-07-final-code/src/lib.rs +++ b/listings/ch20-web-server/no-listing-07-final-code/src/lib.rs @@ -51,19 +51,17 @@ impl Drop for ThreadPool { fn drop(&mut self) { drop(self.sender.take()); - for worker in &mut self.workers { + for worker in self.workers.drain(..) { println!("Shutting down worker {}", worker.id); - if let Some(thread) = worker.thread.take() { - thread.join().unwrap(); - } + worker.thread.join().unwrap(); } } } struct Worker { id: usize, - thread: Option>, + thread: thread::JoinHandle<()>, } impl Worker { @@ -86,7 +84,7 @@ impl Worker { Worker { id, - thread: Some(thread), + thread: thread, } } } diff --git a/src/ch20-03-graceful-shutdown-and-cleanup.md b/src/ch20-03-graceful-shutdown-and-cleanup.md index a28c79e5ad..abe8989d27 100644 --- a/src/ch20-03-graceful-shutdown-and-cleanup.md +++ b/src/ch20-03-graceful-shutdown-and-cleanup.md @@ -46,43 +46,7 @@ Here is the error we get when we compile this code: The error tells us we can’t call `join` because we only have a mutable borrow of each `worker` and `join` takes ownership of its argument. To solve this -issue, we need to move the thread out of the `Worker` instance that owns -`thread` so `join` can consume the thread. We did this in Listing 17-15: if -`Worker` holds an `Option>` instead, we can call the -`take` method on the `Option` to move the value out of the `Some` variant and -leave a `None` variant in its place. In other words, a `Worker` that is running -will have a `Some` variant in `thread`, and when we want to clean up a -`Worker`, we’ll replace `Some` with `None` so the `Worker` doesn’t have a -thread to run. - -So we know we want to update the definition of `Worker` like this: - -Filename: src/lib.rs - -```rust,ignore,does_not_compile -{{#rustdoc_include ../listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs:here}} -``` - -Now let’s lean on the compiler to find the other places that need to change. -Checking this code, we get two errors: - -```console -{{#include ../listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt}} -``` - -Let’s address the second error, which points to the code at the end of -`Worker::new`; we need to wrap the `thread` value in `Some` when we create a -new `Worker`. Make the following changes to fix this error: - -Filename: src/lib.rs - -```rust,ignore,does_not_compile -{{#rustdoc_include ../listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs:here}} -``` - -The first error is in our `Drop` implementation. We mentioned earlier that we -intended to call `take` on the `Option` value to move `thread` out of `worker`. -The following changes will do so: +issue, we need to move the thread out of the vector. `drain` method does it. Filename: src/lib.rs @@ -90,12 +54,6 @@ The following changes will do so: {{#rustdoc_include ../listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs:here}} ``` -As discussed in Chapter 17, the `take` method on `Option` takes the `Some` -variant out and leaves `None` in its place. We’re using `if let` to destructure -the `Some` and get the thread; then we call `join` on the thread. If a worker’s -thread is already `None`, we know that worker has already had its thread -cleaned up, so nothing happens in that case. - ### Signaling to the Threads to Stop Listening for Jobs With all the changes we’ve made, our code compiles without any warnings. @@ -115,6 +73,17 @@ changes to `ThreadPool` to explicitly drop `sender`. We use the same `Option` and `take` technique as we did with the thread to be able to move `sender` out of `ThreadPool`: +To solve the +issue, we need to move the `sender` out of the `ThreadPool` instance that owns +`sender` so `drop` can consume the object. We did this in Listing 17-15: if +`ThreadPool` holds an `Option>` instead, we can call the +`take` method on the `Option` to move the value out of the `Some` variant and +leave a `None` variant in its place. In other words, a `ThreadPool` that is running +will have a `Some` variant in `sender`, and when we want to clean up a +`ThreadPool`, we’ll replace `Some` with `None` so the `ThreadPool` doesn’t have a +sender to run. + + Filename: src/lib.rs ```rust,noplayground,not_desired_behavior From b26046998542dc6bb2e04b9c2cba0e833b924509 Mon Sep 17 00:00:00 2001 From: Sanjyoti <78781492+thedumbsloth@users.noreply.github.com> Date: Wed, 27 Jul 2022 20:10:36 +0530 Subject: [PATCH 012/972] Edit on line no. 153. Edit on line no. 153. The adding of pub keyword to mod hosting and fn add_to_waitlist enables us to use the absolute and relative paths in the fn eat_at_restaurant according to the code specified in listing 7-7. --- ...ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md b/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md index c8fb3247ff..83f45e81fe 100644 --- a/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md +++ b/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md @@ -150,7 +150,7 @@ and `fn add_to_waitlist` lets us call the function from `eat_at_restaurant` Now the code will compile! To see why adding the `pub` keyword lets us use -these paths in `add_to_waitlist` with respect to the privacy rules, let’s look +these paths in `eat_at_restaurant` with respect to the privacy rules, let’s look at the absolute and the relative paths. In the absolute path, we start with `crate`, the root of our crate’s module From 0e9980e4295df3462b26f8c42547d6cb906c86ab Mon Sep 17 00:00:00 2001 From: JirCep Date: Sat, 30 Jul 2022 14:38:08 +0200 Subject: [PATCH 013/972] Unnecessary import removal As per my observations crate being subject to integration tests is available for qualified reference without importing it with `use`. --- .../listing-11-13/tests/integration_test.rs | 2 -- src/ch11-03-test-organization.md | 4 ---- 2 files changed, 6 deletions(-) diff --git a/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs b/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs index e26fa71096..336c5ec54b 100644 --- a/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs +++ b/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs @@ -1,5 +1,3 @@ -use adder; - #[test] fn it_adds_two() { assert_eq!(4, adder::add_two(2)); diff --git a/src/ch11-03-test-organization.md b/src/ch11-03-test-organization.md index 9f26546cf4..61eda50c49 100644 --- a/src/ch11-03-test-organization.md +++ b/src/ch11-03-test-organization.md @@ -117,10 +117,6 @@ Enter the code in Listing 11-13 into the *tests/integration_test.rs* file: Listing 11-13: An integration test of a function in the `adder` crate -Each file in the `tests` directory is a separate crate, so we need to bring our -library into each test crate’s scope. For that reason we add `use adder` at the -top of the code, which we didn’t need in the unit tests. - We don’t need to annotate any code in *tests/integration_test.rs* with `#[cfg(test)]`. Cargo treats the `tests` directory specially and compiles files in this directory only when we run `cargo test`. Run `cargo test` now: From 15616bc09bd7ab6e785680a364364e962c57bb21 Mon Sep 17 00:00:00 2001 From: JirCep Date: Wed, 3 Aug 2022 22:14:44 +0200 Subject: [PATCH 014/972] `expect` is not used multitude times by this chapter --- ...2-03-improving-error-handling-and-modularity.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ch12-03-improving-error-handling-and-modularity.md b/src/ch12-03-improving-error-handling-and-modularity.md index 87e525d122..961246be62 100644 --- a/src/ch12-03-improving-error-handling-and-modularity.md +++ b/src/ch12-03-improving-error-handling-and-modularity.md @@ -23,13 +23,13 @@ example, the file could be missing, or we might not have permission to open it. Right now, regardless of the situation, we’d print the same error message for everything, which wouldn’t give the user any information! -Fourth, we use `expect` repeatedly to handle different errors, and if the user -runs our program without specifying enough arguments, they’ll get an `index out -of bounds` error from Rust that doesn’t clearly explain the problem. It would -be best if all the error-handling code were in one place so future maintainers -had only one place to consult the code if the error-handling logic needed to -change. Having all the error-handling code in one place will also ensure that -we’re printing messages that will be meaningful to our end users. +Fourth, if the user runs our program without specifying enough arguments, +they’ll get an `index out of bounds` error from Rust that doesn’t clearly +explain the problem. It would be best if all the error-handling code were +in one place so future maintainers had only one place to consult the code +if the error-handling logic needed to change. Having all the error-handling +code in one place will also ensure that we’re printing messages that +will be meaningful to our end users. Let’s address these four problems by refactoring our project. From 6c63c46817ceccb90aa5e665e56442b8d794e4c8 Mon Sep 17 00:00:00 2001 From: Alex Gotsis Date: Fri, 5 Aug 2022 00:56:52 -0700 Subject: [PATCH 015/972] Improve awkward phrasing around the kinds of closures --- src/ch13-01-closures.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index f1ae324354..646204f689 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -329,13 +329,13 @@ Using `FnOnce` in the trait bound expresses the constraint that `unwrap_or_else` is only going to call `f` at most one time. In the body of `unwrap_or_else`, we can see that if the `Option` is `Some`, `f` won’t be called. If the `Option` is `None`, `f` will be called once. Because all -closures implement `FnOnce`, `unwrap_or_else` accepts the most different kinds -of closures and is as flexible as it can be. +closures implement `FnOnce`, `unwrap_or_else` accepts all closures and is as +flexible as it can be. > Note: Functions can implement all three of the `Fn` traits too. If what we > want to do doesn’t require capturing a value from the environment, we can use > the name of a function rather than a closure where we need something that -> implements one of the `Fn` traits. For example, on an `Option>` value, +> implements one of the `Fn` traits. For example, on an `Option>` value > we could call `unwrap_or_else(Vec::new)` to get a new, empty vector if the > value is `None`. From 3ebc3b285f01c04dcf48ef5a2363f2eaa104c8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Hern=C3=A1ndez?= Date: Thu, 1 Sep 2022 14:22:21 +0200 Subject: [PATCH 016/972] Update ch02-00-guessing-game-tutorial.md The example code converts the input into a whole number. Replace the text "convert the String the program reads as input into a real number type" to "an actual number type" as the word real might be understood as one of the number categories instead as a synonym to "actual". --- src/ch02-00-guessing-game-tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index bffbc05017..c5999daa3f 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -641,8 +641,8 @@ an `i32`, which is the type of `secret_number` unless you add type information elsewhere that would cause Rust to infer a different numerical type. The reason for the error is that Rust cannot compare a string and a number type. -Ultimately, we want to convert the `String` the program reads as input into a -real number type so we can compare it numerically to the secret number. We do so +Ultimately, we want to convert the `String` the program reads as input into an +actual number type so we can compare it numerically to the secret number. We do so by adding this line to the `main` function body: Filename: src/main.rs From 7b109240d2bfdd7caaea8eba849c5b0941ed4f05 Mon Sep 17 00:00:00 2001 From: Amit Weisbord Date: Tue, 27 Sep 2022 10:14:41 +0300 Subject: [PATCH 017/972] Clarified collection in slice definition Noticed the slice definition in the first paragraph relies on the reader recalling: * what collections are * that the reference page ended stating slices are a kind of reference I think the first paragraph should be more clear to someone who lands on it and isn't reading the rest of the documentation ATM. --- src/ch04-03-slices.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ch04-03-slices.md b/src/ch04-03-slices.md index afb6f76b10..1aae43f038 100644 --- a/src/ch04-03-slices.md +++ b/src/ch04-03-slices.md @@ -1,8 +1,9 @@ ## The Slice Type -*Slices* let you reference a contiguous sequence of elements in a collection -rather than the whole collection. A slice is a kind of reference, so it does -not have ownership. +*Slices* are a kind of reference, which lets you access a contiguous sub-sequence +of elements in a sequential [collection](book/src/ch08-00-common-collections.md). +Because slices are a kind of reference, they too can borrow access to memory, but +not own it. Here’s a small programming problem: write a function that takes a string of words separated by spaces and returns the first word it finds in that string. From 3a8ff9bdd272d4a60622f4ef3e2413b4170258ba Mon Sep 17 00:00:00 2001 From: Amit Weisbord Date: Tue, 27 Sep 2022 15:22:13 +0300 Subject: [PATCH 018/972] Fix broken url --- src/ch04-03-slices.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch04-03-slices.md b/src/ch04-03-slices.md index 1aae43f038..3b1b7989c1 100644 --- a/src/ch04-03-slices.md +++ b/src/ch04-03-slices.md @@ -1,7 +1,7 @@ ## The Slice Type *Slices* are a kind of reference, which lets you access a contiguous sub-sequence -of elements in a sequential [collection](book/src/ch08-00-common-collections.md). +of elements in a sequential [collection](ch08-00-common-collections.md). Because slices are a kind of reference, they too can borrow access to memory, but not own it. From d78fe8764aaa76ade6cc1f60f695ec9485474a08 Mon Sep 17 00:00:00 2001 From: JirCep Date: Sat, 8 Oct 2022 22:02:53 +0200 Subject: [PATCH 019/972] Minor corrections Irrefutable pattern receives warning, refutable error, when used unexpectedly. --- src/ch18-02-refutability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch18-02-refutability.md b/src/ch18-02-refutability.md index be3c31765c..29ab7ec48b 100644 --- a/src/ch18-02-refutability.md +++ b/src/ch18-02-refutability.md @@ -61,7 +61,7 @@ the code in the curly brackets, giving it a way to continue validly. Listing patterns instead of `let` We’ve given the code an out! This code is perfectly valid, although it means we -cannot use an irrefutable pattern without receiving an error. If we give `if +cannot use an irrefutable pattern without receiving a warning. If we give `if let` a pattern that will always match, such as `x`, as shown in Listing 18-10, the compiler will give a warning. From 7c9680b2861d4448d4fe82ef4ea74bd2528513f1 Mon Sep 17 00:00:00 2001 From: Marijn <40164828+MarijnRitzen@users.noreply.github.com> Date: Thu, 20 Oct 2022 15:05:57 +0200 Subject: [PATCH 020/972] Update ch20-01-single-threaded.md Listing 20-8 is the html file --- src/ch20-01-single-threaded.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch20-01-single-threaded.md b/src/ch20-01-single-threaded.md index 993239a981..1776f05589 100644 --- a/src/ch20-01-single-threaded.md +++ b/src/ch20-01-single-threaded.md @@ -448,7 +448,7 @@ uses the `status_line` and `filename` variables. This makes it easier to see the difference between the two cases, and it means we have only one place to update the code if we want to change how the file reading and response writing work. The behavior of the code in Listing 20-9 will be the same as that in -Listing 20-8. +Listing 20-6 and 20-7. Awesome! We now have a simple web server in approximately 40 lines of Rust code that responds to one request with a page of content and responds to all other From fdd1d92f8c6147bf8bc09046383da829d183b897 Mon Sep 17 00:00:00 2001 From: JirCep Date: Sat, 1 Oct 2022 21:45:04 +0200 Subject: [PATCH 021/972] Type parameter removal `Vec` denotes generic type. As this chapter kindly describes Rust generics cannot hold 2 or more struct kinds. --- src/ch17-02-trait-objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ch17-02-trait-objects.md b/src/ch17-02-trait-objects.md index 2d3fea24a1..bb43cc6763 100644 --- a/src/ch17-02-trait-objects.md +++ b/src/ch17-02-trait-objects.md @@ -124,7 +124,7 @@ collections, using generics and trait bounds is preferable because the definitions will be monomorphized at compile time to use the concrete types. On the other hand, with the method using trait objects, one `Screen` instance -can hold a `Vec` that contains a `Box