diff --git a/listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.lock b/listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.lock new file mode 100755 index 0000000..5802b7d --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "guessing_game" +version = "0.1.0" + diff --git a/listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.toml b/listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.toml new file mode 100755 index 0000000..78c94fe --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs b/listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs new file mode 100755 index 0000000..b822b89 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs @@ -0,0 +1,31 @@ +// ANCHOR: all +// ANCHOR: io +use std::io; +// ANCHOR_END: io + +// ANCHOR: main +fn main() { + // ANCHOR_END: main + // ANCHOR: print + println!("Guess the number!"); + + println!("Please input your guess."); + // ANCHOR_END: print + + // ANCHOR: string + let mut guess = String::new(); + // ANCHOR_END: string + + // ANCHOR: read + io::stdin() + .read_line(&mut guess) + // ANCHOR_END: read + // ANCHOR: expect + .expect("Failed to read line"); + // ANCHOR_END: expect + + // ANCHOR: print_guess + println!("You guessed: {}", guess); + // ANCHOR_END: print_guess +} +// ANCHOR: all diff --git a/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.lock b/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml b/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs b/listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs new file mode 100755 index 0000000..60fb2a8 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs @@ -0,0 +1,15 @@ +use std::io; + +fn main() { + println!("Guess the number!"); + + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + println!("You guessed: {}", guess); +} diff --git a/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.lock b/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.toml b/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs b/listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs new file mode 100755 index 0000000..de35846 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs @@ -0,0 +1,28 @@ +// ANCHOR: all +use std::io; +// ANCHOR: ch07-04 +use rand::Rng; + +fn main() { + // ANCHOR_END: ch07-04 + println!("Guess the number!"); + + // ANCHOR: ch07-04 + let secret_number = rand::thread_rng().gen_range(1..101); + // ANCHOR_END: ch07-04 + + println!("The secret number is: {}", secret_number); + + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + println!("You guessed: {}", guess); + // ANCHOR: ch07-04 +} +// ANCHOR_END: ch07-04 +// ANCHOR_END: all diff --git a/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.lock b/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.toml b/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt b/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt new file mode 100755 index 0000000..6149472 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt @@ -0,0 +1,45 @@ +$ cargo build + Compiling libc v0.2.86 + Compiling getrandom v0.2.2 + Compiling cfg-if v1.0.0 + Compiling ppv-lite86 v0.2.10 + Compiling rand_core v0.6.2 + Compiling rand_chacha v0.3.0 + Compiling rand v0.8.3 + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) +error[E0308]: mismatched types + --> src/main.rs:22:21 + | +22 | match guess.cmp(&secret_number) { + | ^^^^^^^^^^^^^^ expected struct `String`, found integer + | + = note: expected reference `&String` + found reference `&{integer}` + +error[E0283]: type annotations needed for `{integer}` + --> src/main.rs:8:44 + | +8 | let secret_number = rand::thread_rng().gen_range(1..101); + | ------------- ^^^^^^^^^ cannot infer type for type `{integer}` + | | + | consider giving `secret_number` a type + | + = note: multiple `impl`s satisfying `{integer}: SampleUniform` found in the `rand` crate: + - impl SampleUniform for i128; + - impl SampleUniform for i16; + - impl SampleUniform for i32; + - impl SampleUniform for i64; + and 8 more +note: required by a bound in `gen_range` + --> /Users/carolnichols/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.8.3/src/rng.rs:129:12 + | +129 | T: SampleUniform, + | ^^^^^^^^^^^^^ required by this bound in `gen_range` +help: consider specifying the type arguments in the function call + | +8 | let secret_number = rand::thread_rng().gen_range::(1..101); + | ++++++++ + +Some errors have detailed explanations: E0283, E0308. +For more information about an error, try `rustc --explain E0283`. +error: could not compile `guessing_game` due to 2 previous errors diff --git a/listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs b/listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs new file mode 100755 index 0000000..349bc27 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs @@ -0,0 +1,32 @@ +// ANCHOR: here +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + // --snip-- + // ANCHOR_END: here + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + println!("The secret number is: {}", secret_number); + + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + // ANCHOR: here + + println!("You guessed: {}", guess); + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => println!("You win!"), + } +} +// ANCHOR_END: here diff --git a/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.lock b/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.toml b/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs b/listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs new file mode 100755 index 0000000..41a4cdd --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs @@ -0,0 +1,45 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + println!("The secret number is: {}", secret_number); + + loop { + println!("Please input your guess."); + + let mut guess = String::new(); + + // ANCHOR: here + // --snip-- + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + // ANCHOR: ch19 + let guess: u32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => continue, + }; + // ANCHOR_END: ch19 + + println!("You guessed: {}", guess); + + // --snip-- + // ANCHOR_END: here + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => { + println!("You win!"); + break; + } + } + } +} diff --git a/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.lock b/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.toml b/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs b/listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs new file mode 100755 index 0000000..30859c7 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs @@ -0,0 +1,35 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + loop { + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + let guess: u32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => continue, + }; + + println!("You guessed: {}", guess); + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => { + println!("You win!"); + break; + } + } + } +} diff --git a/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.lock b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.lock new file mode 100755 index 0000000..5802b7d --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "guessing_game" +version = "0.1.0" + diff --git a/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.toml b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.toml new file mode 100755 index 0000000..78c94fe --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt new file mode 100755 index 0000000..2724c14 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) + Finished dev [unoptimized + debuginfo] target(s) in 1.50s + Running `target/debug/guessing_game` +Hello, world! diff --git a/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs new file mode 100755 index 0000000..e7a11a9 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.lock b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.lock new file mode 100755 index 0000000..5802b7d --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "guessing_game" +version = "0.1.0" + diff --git a/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.toml b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.toml new file mode 100755 index 0000000..78c94fe --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt new file mode 100755 index 0000000..8095bbd --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt @@ -0,0 +1,13 @@ +$ cargo build + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) +warning: unused `Result` that must be used + --> src/main.rs:10:5 + | +10 | io::stdin().read_line(&mut guess); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: this `Result` may be an `Err` variant, which should be handled + +warning: `guessing_game` (bin "guessing_game") generated 1 warning + Finished dev [unoptimized + debuginfo] target(s) in 0.59s diff --git a/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs new file mode 100755 index 0000000..aaf90bd --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs @@ -0,0 +1,13 @@ +use std::io; + +fn main() { + println!("Guess the number!"); + + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin().read_line(&mut guess); + + println!("You guessed: {}", guess); +} diff --git a/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.lock b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.toml b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs new file mode 100755 index 0000000..0b21d95 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs @@ -0,0 +1,33 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + println!("The secret number is: {}", secret_number); + + println!("Please input your guess."); + + // ANCHOR: here + // --snip-- + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + let guess: u32 = guess.trim().parse().expect("Please type a number!"); + + println!("You guessed: {}", guess); + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => println!("You win!"), + } + // ANCHOR_END: here +} diff --git a/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.lock b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.toml b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs new file mode 100755 index 0000000..61a5dc0 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs @@ -0,0 +1,40 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + // ANCHOR: here + // --snip-- + + println!("The secret number is: {}", secret_number); + + loop { + println!("Please input your guess."); + + // --snip-- + + // ANCHOR_END: here + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + let guess: u32 = guess.trim().parse().expect("Please type a number!"); + + println!("You guessed: {}", guess); + + // ANCHOR: here + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => println!("You win!"), + } + } +} +// ANCHOR_END: here diff --git a/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.lock b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.toml b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs new file mode 100755 index 0000000..3f8e8b7 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs @@ -0,0 +1,38 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + println!("The secret number is: {}", secret_number); + + loop { + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + let guess: u32 = guess.trim().parse().expect("Please type a number!"); + + println!("You guessed: {}", guess); + + // ANCHOR: here + // --snip-- + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => { + println!("You win!"); + break; + } + } + } +} +// ANCHOR_END: here diff --git a/listings/ch03-common-programming-concepts/listing-03-01/Cargo.lock b/listings/ch03-common-programming-concepts/listing-03-01/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/listing-03-01/Cargo.toml b/listings/ch03-common-programming-concepts/listing-03-01/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/listing-03-01/src/main.rs b/listings/ch03-common-programming-concepts/listing-03-01/src/main.rs new file mode 100755 index 0000000..b492d38 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-01/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + let y = 6; +} diff --git a/listings/ch03-common-programming-concepts/listing-03-02/Cargo.lock b/listings/ch03-common-programming-concepts/listing-03-02/Cargo.lock new file mode 100755 index 0000000..4ca0c2d --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "branches" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/listing-03-02/Cargo.toml b/listings/ch03-common-programming-concepts/listing-03-02/Cargo.toml new file mode 100755 index 0000000..6596455 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/listing-03-02/output.txt b/listings/ch03-common-programming-concepts/listing-03-02/output.txt new file mode 100755 index 0000000..3eb8d10 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-02/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.30s + Running `target/debug/branches` +The value of number is: 5 diff --git a/listings/ch03-common-programming-concepts/listing-03-02/src/main.rs b/listings/ch03-common-programming-concepts/listing-03-02/src/main.rs new file mode 100755 index 0000000..0b8ee95 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-02/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + let condition = true; + let number = if condition { 5 } else { 6 }; + + println!("The value of number is: {}", number); +} diff --git a/listings/ch03-common-programming-concepts/listing-03-03/Cargo.lock b/listings/ch03-common-programming-concepts/listing-03-03/Cargo.lock new file mode 100755 index 0000000..9942b36 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "loops" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/listing-03-03/Cargo.toml b/listings/ch03-common-programming-concepts/listing-03-03/Cargo.toml new file mode 100755 index 0000000..810e8bb --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/listing-03-03/src/main.rs b/listings/ch03-common-programming-concepts/listing-03-03/src/main.rs new file mode 100755 index 0000000..651ed68 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-03/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let mut number = 3; + + while number != 0 { + println!("{}!", number); + + number -= 1; + } + + println!("LIFTOFF!!!"); +} diff --git a/listings/ch03-common-programming-concepts/listing-03-04/Cargo.lock b/listings/ch03-common-programming-concepts/listing-03-04/Cargo.lock new file mode 100755 index 0000000..9942b36 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "loops" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/listing-03-04/Cargo.toml b/listings/ch03-common-programming-concepts/listing-03-04/Cargo.toml new file mode 100755 index 0000000..810e8bb --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/listing-03-04/output.txt b/listings/ch03-common-programming-concepts/listing-03-04/output.txt new file mode 100755 index 0000000..35c0f80 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-04/output.txt @@ -0,0 +1,9 @@ +$ cargo run + Compiling loops v0.1.0 (file:///projects/loops) + Finished dev [unoptimized + debuginfo] target(s) in 0.32s + Running `target/debug/loops` +the value is: 10 +the value is: 20 +the value is: 30 +the value is: 40 +the value is: 50 diff --git a/listings/ch03-common-programming-concepts/listing-03-04/src/main.rs b/listings/ch03-common-programming-concepts/listing-03-04/src/main.rs new file mode 100755 index 0000000..38fd301 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-04/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + let a = [10, 20, 30, 40, 50]; + let mut index = 0; + + while index < 5 { + println!("the value is: {}", a[index]); + + index += 1; + } +} diff --git a/listings/ch03-common-programming-concepts/listing-03-05/Cargo.lock b/listings/ch03-common-programming-concepts/listing-03-05/Cargo.lock new file mode 100755 index 0000000..9942b36 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "loops" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/listing-03-05/Cargo.toml b/listings/ch03-common-programming-concepts/listing-03-05/Cargo.toml new file mode 100755 index 0000000..810e8bb --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/listing-03-05/src/main.rs b/listings/ch03-common-programming-concepts/listing-03-05/src/main.rs new file mode 100755 index 0000000..5eaa7a0 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-05/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let a = [10, 20, 30, 40, 50]; + + for element in a { + println!("the value is: {}", element); + } +} diff --git a/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.lock new file mode 100755 index 0000000..2d62cbe --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "variables" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.toml new file mode 100755 index 0000000..4da3b81 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "variables" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt new file mode 100755 index 0000000..2b7e562 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling variables v0.1.0 (file:///projects/variables) +error[E0384]: cannot assign twice to immutable variable `x` + --> src/main.rs:4:5 + | +2 | let x = 5; + | - + | | + | first assignment to `x` + | help: consider making this binding mutable: `mut x` +3 | println!("The value of x is: {}", x); +4 | x = 6; + | ^^^^^ cannot assign twice to immutable variable + +For more information about this error, try `rustc --explain E0384`. +error: could not compile `variables` due to previous error diff --git a/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs new file mode 100755 index 0000000..a6c7ac0 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + let x = 5; + println!("The value of x is: {}", x); + x = 6; + println!("The value of x is: {}", x); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.lock new file mode 100755 index 0000000..2d62cbe --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "variables" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.toml new file mode 100755 index 0000000..4da3b81 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "variables" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt new file mode 100755 index 0000000..8ed6598 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling variables v0.1.0 (file:///projects/variables) + Finished dev [unoptimized + debuginfo] target(s) in 0.30s + Running `target/debug/variables` +The value of x is: 5 +The value of x is: 6 diff --git a/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs new file mode 100755 index 0000000..c4e4a19 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + let mut x = 5; + println!("The value of x is: {}", x); + x = 6; + println!("The value of x is: {}", x); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.lock new file mode 100755 index 0000000..2d62cbe --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "variables" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.toml new file mode 100755 index 0000000..4da3b81 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "variables" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt new file mode 100755 index 0000000..f310e9f --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling variables v0.1.0 (file:///projects/variables) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + Running `target/debug/variables` +The value of x in the inner scope is: 12 +The value of x is: 6 diff --git a/listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs new file mode 100755 index 0000000..606ee68 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + let x = 5; + + let x = x + 1; + + { + let x = x * 2; + println!("The value of x in the inner scope is: {}", x); + } + + println!("The value of x is: {}", x); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.lock new file mode 100755 index 0000000..2d62cbe --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "variables" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.toml new file mode 100755 index 0000000..4da3b81 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "variables" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/src/main.rs new file mode 100755 index 0000000..42589f5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let spaces = " "; + let spaces = spaces.len(); + // ANCHOR_END: here +} diff --git a/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.lock new file mode 100755 index 0000000..2d62cbe --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "variables" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.toml new file mode 100755 index 0000000..4da3b81 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "variables" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt new file mode 100755 index 0000000..31a07ef --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling variables v0.1.0 (file:///projects/variables) +error[E0308]: mismatched types + --> src/main.rs:3:14 + | +2 | let mut spaces = " "; + | ----- expected due to this value +3 | spaces = spaces.len(); + | ^^^^^^^^^^^^ expected `&str`, found `usize` + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `variables` due to previous error diff --git a/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/src/main.rs new file mode 100755 index 0000000..f52635d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let mut spaces = " "; + spaces = spaces.len(); + // ANCHOR_END: here +} diff --git a/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.lock new file mode 100755 index 0000000..3b40559 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "floating-point" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.toml new file mode 100755 index 0000000..83610e7 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "floating-point" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-06-floating-point/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/src/main.rs new file mode 100755 index 0000000..6f4f0fe --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + let x = 2.0; // f64 + + let y: f32 = 3.0; // f32 +} diff --git a/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.lock new file mode 100755 index 0000000..94a12b2 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "numeric-operations" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.toml new file mode 100755 index 0000000..b4bea55 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "numeric-operations" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs new file mode 100755 index 0000000..9d3b481 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs @@ -0,0 +1,17 @@ +fn main() { + // addition + let sum = 5 + 10; + + // subtraction + let difference = 95.5 - 4.3; + + // multiplication + let product = 4 * 30; + + // division + let quotient = 56.7 / 32.2; + let floored = 2 / 3; // Results in 0 + + // remainder + let remainder = 43 % 5; +} diff --git a/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.lock new file mode 100755 index 0000000..5d5728e --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "boolean" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.toml new file mode 100755 index 0000000..47e42ce --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "boolean" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-08-boolean/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-08-boolean/src/main.rs new file mode 100755 index 0000000..2c56e62 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-08-boolean/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + let t = true; + + let f: bool = false; // with explicit type annotation +} diff --git a/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.lock new file mode 100755 index 0000000..bb58446 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "char" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.toml new file mode 100755 index 0000000..a1ef3b5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "char" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-09-char/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-09-char/src/main.rs new file mode 100755 index 0000000..4b8d9d9 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-09-char/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + let c = 'z'; + let z = 'ℤ'; + let heart_eyed_cat = '😻'; +} diff --git a/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.lock new file mode 100755 index 0000000..f57f076 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tuples" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.toml new file mode 100755 index 0000000..9b0879c --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tuples" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs new file mode 100755 index 0000000..b7b51fb --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + let tup: (i32, f64, u8) = (500, 6.4, 1); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.lock new file mode 100755 index 0000000..f57f076 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tuples" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.toml new file mode 100755 index 0000000..9b0879c --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tuples" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs new file mode 100755 index 0000000..35dcb44 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let tup = (500, 6.4, 1); + + let (x, y, z) = tup; + + println!("The value of y is: {}", y); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.lock new file mode 100755 index 0000000..f57f076 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tuples" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.toml new file mode 100755 index 0000000..9b0879c --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tuples" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs new file mode 100755 index 0000000..1b1e646 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let x: (i32, f64, u8) = (500, 6.4, 1); + + let five_hundred = x.0; + + let six_point_four = x.1; + + let one = x.2; +} diff --git a/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.lock new file mode 100755 index 0000000..68e3c59 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arrays" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.toml new file mode 100755 index 0000000..96be3e2 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "arrays" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-13-arrays/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-13-arrays/src/main.rs new file mode 100755 index 0000000..d475901 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-13-arrays/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + let a = [1, 2, 3, 4, 5]; +} diff --git a/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.lock new file mode 100755 index 0000000..68e3c59 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arrays" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.toml new file mode 100755 index 0000000..96be3e2 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "arrays" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs new file mode 100755 index 0000000..d33e317 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + let a = [1, 2, 3, 4, 5]; + + let first = a[0]; + let second = a[1]; +} diff --git a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.lock new file mode 100755 index 0000000..68e3c59 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "arrays" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.toml new file mode 100755 index 0000000..96be3e2 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "arrays" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs new file mode 100755 index 0000000..5e51216 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs @@ -0,0 +1,25 @@ +use std::io; + +fn main() { + let a = [1, 2, 3, 4, 5]; + + println!("Please enter an array index."); + + let mut index = String::new(); + + io::stdin() + .read_line(&mut index) + .expect("Failed to read line"); + + let index: usize = index + .trim() + .parse() + .expect("Index entered was not a number"); + + let element = a[index]; + + println!( + "The value of the element at index {} is: {}", + index, element + ); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt b/listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt new file mode 100755 index 0000000..723fad3 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.28s + Running `target/debug/functions` +Hello, world! +Another function. diff --git a/listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs new file mode 100755 index 0000000..38be856 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + println!("Hello, world!"); + + another_function(); +} + +fn another_function() { + println!("Another function."); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt new file mode 100755 index 0000000..546bbc0 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 1.21s + Running `target/debug/functions` +The value of x is: 5 diff --git a/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs new file mode 100755 index 0000000..029446c --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + another_function(5); +} + +fn another_function(x: i32) { + println!("The value of x is: {}", x); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt new file mode 100755 index 0000000..6210234 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + Running `target/debug/functions` +The measurement is: 5h diff --git a/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs new file mode 100755 index 0000000..543c2ea --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + print_labeled_measurement(5, 'h'); +} + +fn print_labeled_measurement(value: i32, unit_label: char) { + println!("The measurement is: {}{}", value, unit_label); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.lock new file mode 100755 index 0000000..89a654d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt new file mode 100755 index 0000000..b33f8bd --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt @@ -0,0 +1,35 @@ +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) +error: expected expression, found statement (`let`) + --> src/main.rs:2:14 + | +2 | let x = (let y = 6); + | ^^^^^^^^^ + | + = note: variable declaration using `let` is a statement + +error[E0658]: `let` expressions in this position are experimental + --> src/main.rs:2:14 + | +2 | let x = (let y = 6); + | ^^^^^^^^^ + | + = note: see issue #53667 for more information + = help: you can write `matches!(, )` instead of `let = ` + +warning: unnecessary parentheses around assigned value + --> src/main.rs:2:13 + | +2 | let x = (let y = 6); + | ^ ^ + | + = note: `#[warn(unused_parens)]` on by default +help: remove these parentheses + | +2 - let x = (let y = 6); +2 + let x = let y = 6; + | + +For more information about this error, try `rustc --explain E0658`. +warning: `functions` (bin "functions") generated 1 warning +error: could not compile `functions` due to 2 previous errors; 1 warning emitted diff --git a/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/rustfmt-ignore b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/rustfmt-ignore new file mode 100755 index 0000000..06a976d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/rustfmt-ignore @@ -0,0 +1 @@ +This listing deliberately doesn't parse so rustfmt fails. diff --git a/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/src/main.rs new file mode 100755 index 0000000..988f965 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + let x = (let y = 6); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs new file mode 100755 index 0000000..0be7fcb --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + let y = { + let x = 3; + x + 1 + }; + + println!("The value of y is: {}", y); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt new file mode 100755 index 0000000..a457e33 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.30s + Running `target/debug/functions` +The value of x is: 5 diff --git a/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs new file mode 100755 index 0000000..5303b10 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs @@ -0,0 +1,9 @@ +fn five() -> i32 { + 5 +} + +fn main() { + let x = five(); + + println!("The value of x is: {}", x); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs new file mode 100755 index 0000000..b4c8443 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let x = plus_one(5); + + println!("The value of x is: {}", x); +} + +fn plus_one(x: i32) -> i32 { + x + 1 +} diff --git a/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.lock new file mode 100755 index 0000000..88287d1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.toml new file mode 100755 index 0000000..478b346 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt new file mode 100755 index 0000000..4566ab7 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) +error[E0308]: mismatched types + --> src/main.rs:7:24 + | +7 | fn plus_one(x: i32) -> i32 { + | -------- ^^^ expected `i32`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression +8 | x + 1; + | - help: consider removing this semicolon + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `functions` due to previous error diff --git a/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs new file mode 100755 index 0000000..c9c4edc --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let x = plus_one(5); + + println!("The value of x is: {}", x); +} + +fn plus_one(x: i32) -> i32 { + x + 1; +} diff --git a/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.lock new file mode 100755 index 0000000..a289136 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "comments" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.toml new file mode 100755 index 0000000..e0576b5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "comments" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs new file mode 100755 index 0000000..535f4b9 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + let lucky_number = 7; // I’m feeling lucky today +} diff --git a/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.lock new file mode 100755 index 0000000..a289136 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "comments" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.toml new file mode 100755 index 0000000..e0576b5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "comments" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs new file mode 100755 index 0000000..81cd935 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + // I’m feeling lucky today + let lucky_number = 7; +} diff --git a/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.lock new file mode 100755 index 0000000..4ca0c2d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "branches" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.toml new file mode 100755 index 0000000..6596455 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt b/listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt new file mode 100755 index 0000000..3d8c7dc --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + Running `target/debug/branches` +condition was true diff --git a/listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs new file mode 100755 index 0000000..e64a42a --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let number = 3; + + if number < 5 { + println!("condition was true"); + } else { + println!("condition was false"); + } +} diff --git a/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.lock new file mode 100755 index 0000000..4ca0c2d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "branches" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.toml new file mode 100755 index 0000000..6596455 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt b/listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt new file mode 100755 index 0000000..e40da96 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + Running `target/debug/branches` +condition was false diff --git a/listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs new file mode 100755 index 0000000..f7d76cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let number = 7; + // ANCHOR_END: here + + if number < 5 { + println!("condition was true"); + } else { + println!("condition was false"); + } +} diff --git a/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.lock new file mode 100755 index 0000000..4ca0c2d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "branches" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.toml new file mode 100755 index 0000000..6596455 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt new file mode 100755 index 0000000..735bfe7 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt @@ -0,0 +1,10 @@ +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) +error[E0308]: mismatched types + --> src/main.rs:4:8 + | +4 | if number { + | ^^^^^^ expected `bool`, found integer + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `branches` due to previous error diff --git a/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs new file mode 100755 index 0000000..bc4af76 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let number = 3; + + if number { + println!("number was three"); + } +} diff --git a/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.lock new file mode 100755 index 0000000..4ca0c2d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "branches" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.toml new file mode 100755 index 0000000..6596455 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs new file mode 100755 index 0000000..704650f --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let number = 3; + + if number != 0 { + println!("number was something other than zero"); + } +} diff --git a/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.lock new file mode 100755 index 0000000..4ca0c2d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "branches" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.toml new file mode 100755 index 0000000..6596455 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt b/listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt new file mode 100755 index 0000000..b218941 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + Running `target/debug/branches` +number is divisible by 3 diff --git a/listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs new file mode 100755 index 0000000..d0ef9b2 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + let number = 6; + + if number % 4 == 0 { + println!("number is divisible by 4"); + } else if number % 3 == 0 { + println!("number is divisible by 3"); + } else if number % 2 == 0 { + println!("number is divisible by 2"); + } else { + println!("number is not divisible by 4, 3, or 2"); + } +} diff --git a/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.lock new file mode 100755 index 0000000..4ca0c2d --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "branches" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.toml new file mode 100755 index 0000000..6596455 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "branches" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt new file mode 100755 index 0000000..e922acd --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) +error[E0308]: `if` and `else` have incompatible types + --> src/main.rs:4:44 + | +4 | let number = if condition { 5 } else { "six" }; + | - ^^^^^ expected integer, found `&str` + | | + | expected because of this + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `branches` due to previous error diff --git a/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs new file mode 100755 index 0000000..440b286 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let condition = true; + + let number = if condition { 5 } else { "six" }; + + println!("The value of number is: {}", number); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/Cargo.lock new file mode 100755 index 0000000..f738673 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "loops" +version = "0.1.0" diff --git a/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/Cargo.toml new file mode 100755 index 0000000..810e8bb --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/output.txt b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/output.txt new file mode 100755 index 0000000..d4d322f --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/output.txt @@ -0,0 +1,13 @@ +$ cargo run + Compiling loops v0.1.0 (file:///projects/loops) + Finished dev [unoptimized + debuginfo] target(s) in 0.58s + Running `target/debug/loops` +count = 0 +remaining = 10 +remaining = 9 +count = 1 +remaining = 10 +remaining = 9 +count = 2 +remaining = 10 +End count = 2 diff --git a/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/src/main.rs new file mode 100755 index 0000000..b855d75 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/src/main.rs @@ -0,0 +1,21 @@ +fn main() { + let mut count = 0; + 'counting_up: loop { + println!("count = {}", count); + let mut remaining = 10; + + loop { + println!("remaining = {}", remaining); + if remaining == 9 { + break; + } + if count == 2 { + break 'counting_up; + } + remaining -= 1; + } + + count += 1; + } + println!("End count = {}", count); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.lock new file mode 100755 index 0000000..9942b36 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "loops" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.toml new file mode 100755 index 0000000..810e8bb --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs new file mode 100755 index 0000000..f1692e4 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + loop { + println!("again!"); + } +} diff --git a/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.lock new file mode 100755 index 0000000..9942b36 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "loops" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.toml new file mode 100755 index 0000000..810e8bb --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs new file mode 100755 index 0000000..6ffdab5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + let mut counter = 0; + + let result = loop { + counter += 1; + + if counter == 10 { + break counter * 2; + } + }; + + println!("The result is {}", result); +} diff --git a/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.lock new file mode 100755 index 0000000..9942b36 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "loops" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.toml b/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.toml new file mode 100755 index 0000000..810e8bb --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "loops" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs b/listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs new file mode 100755 index 0000000..e7286a8 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + for number in (1..4).rev() { + println!("{}!", number); + } + println!("LIFTOFF!!!"); +} diff --git a/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.lock b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.lock new file mode 100755 index 0000000..b5664bc --- /dev/null +++ b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "no_type_annotations" +version = "0.1.0" + diff --git a/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.toml b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.toml new file mode 100755 index 0000000..8ad4d5a --- /dev/null +++ b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "no_type_annotations" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt new file mode 100755 index 0000000..d9807ce --- /dev/null +++ b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt @@ -0,0 +1,10 @@ +$ cargo build + Compiling no_type_annotations v0.1.0 (file:///projects/no_type_annotations) +error[E0282]: type annotations needed + --> src/main.rs:2:9 + | +2 | let guess = "42".parse().expect("Not a number!"); + | ^^^^^ consider giving `guess` a type + +For more information about this error, try `rustc --explain E0282`. +error: could not compile `no_type_annotations` due to previous error diff --git a/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/src/main.rs b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/src/main.rs new file mode 100755 index 0000000..f41c558 --- /dev/null +++ b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + let guess = "42".parse().expect("Not a number!"); +} diff --git a/listings/ch04-understanding-ownership/listing-04-01/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-01/Cargo.lock new file mode 100755 index 0000000..9e4e62d --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-01/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-01/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-01/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-01/rustfmt-ignore b/listings/ch04-understanding-ownership/listing-04-01/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-01/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch04-understanding-ownership/listing-04-01/src/main.rs b/listings/ch04-understanding-ownership/listing-04-01/src/main.rs new file mode 100755 index 0000000..148ad84 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-01/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + { // s is not valid here, it’s not yet declared + let s = "hello"; // s is valid from this point forward + + // do stuff with s + } // this scope is now over, and s is no longer valid + // ANCHOR_END: here +} \ No newline at end of file diff --git a/listings/ch04-understanding-ownership/listing-04-02/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-02/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-02/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-02/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-02/src/main.rs b/listings/ch04-understanding-ownership/listing-04-02/src/main.rs new file mode 100755 index 0000000..de0f1b3 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-02/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let x = 5; + let y = x; + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/listing-04-03/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-03/Cargo.lock new file mode 100755 index 0000000..9e4e62d --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-03/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-03/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-03/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-03/rustfmt-ignore b/listings/ch04-understanding-ownership/listing-04-03/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-03/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch04-understanding-ownership/listing-04-03/src/main.rs b/listings/ch04-understanding-ownership/listing-04-03/src/main.rs new file mode 100755 index 0000000..b001cc5 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-03/src/main.rs @@ -0,0 +1,23 @@ +fn main() { + let s = String::from("hello"); // s comes into scope + + takes_ownership(s); // s's value moves into the function... + // ... and so is no longer valid here + + let x = 5; // x comes into scope + + makes_copy(x); // x would move into the function, + // but i32 is Copy, so it's okay to still + // use x afterward + +} // Here, x goes out of scope, then s. But because s's value was moved, nothing + // special happens. + +fn takes_ownership(some_string: String) { // some_string comes into scope + println!("{}", some_string); +} // Here, some_string goes out of scope and `drop` is called. The backing + // memory is freed. + +fn makes_copy(some_integer: i32) { // some_integer comes into scope + println!("{}", some_integer); +} // Here, some_integer goes out of scope. Nothing special happens. diff --git a/listings/ch04-understanding-ownership/listing-04-04/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-04/Cargo.lock new file mode 100755 index 0000000..9e4e62d --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-04/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-04/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-04/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-04/rustfmt-ignore b/listings/ch04-understanding-ownership/listing-04-04/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-04/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch04-understanding-ownership/listing-04-04/src/main.rs b/listings/ch04-understanding-ownership/listing-04-04/src/main.rs new file mode 100755 index 0000000..e206bec --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-04/src/main.rs @@ -0,0 +1,29 @@ +fn main() { + let s1 = gives_ownership(); // gives_ownership moves its return + // value into s1 + + let s2 = String::from("hello"); // s2 comes into scope + + let s3 = takes_and_gives_back(s2); // s2 is moved into + // takes_and_gives_back, which also + // moves its return value into s3 +} // Here, s3 goes out of scope and is dropped. s2 was moved, so nothing + // happens. s1 goes out of scope and is dropped. + +fn gives_ownership() -> String { // gives_ownership will move its + // return value into the function + // that calls it + + let some_string = String::from("yours"); // some_string comes into scope + + some_string // some_string is returned and + // moves out to the calling + // function +} + +// This function takes a String and returns one +fn takes_and_gives_back(a_string: String) -> String { // a_string comes into + // scope + + a_string // a_string is returned and moves out to the calling function +} diff --git a/listings/ch04-understanding-ownership/listing-04-05/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-05/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-05/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-05/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-05/src/main.rs b/listings/ch04-understanding-ownership/listing-04-05/src/main.rs new file mode 100755 index 0000000..22aee14 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-05/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + let s1 = String::from("hello"); + + let (s2, len) = calculate_length(s1); + + println!("The length of '{}' is {}.", s2, len); +} + +fn calculate_length(s: String) -> (String, usize) { + let length = s.len(); // len() returns the length of a String + + (s, length) +} diff --git a/listings/ch04-understanding-ownership/listing-04-06/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-06/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-06/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-06/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-06/output.txt b/listings/ch04-understanding-ownership/listing-04-06/output.txt new file mode 100755 index 0000000..1176f4e --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-06/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling ownership v0.1.0 (file:///projects/ownership) +error[E0596]: cannot borrow `*some_string` as mutable, as it is behind a `&` reference + --> src/main.rs:8:5 + | +7 | fn change(some_string: &String) { + | ------- help: consider changing this to be a mutable reference: `&mut String` +8 | some_string.push_str(", world"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable + +For more information about this error, try `rustc --explain E0596`. +error: could not compile `ownership` due to previous error diff --git a/listings/ch04-understanding-ownership/listing-04-06/src/main.rs b/listings/ch04-understanding-ownership/listing-04-06/src/main.rs new file mode 100755 index 0000000..330ffa6 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-06/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let s = String::from("hello"); + + change(&s); +} + +fn change(some_string: &String) { + some_string.push_str(", world"); +} diff --git a/listings/ch04-understanding-ownership/listing-04-07/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-07/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-07/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-07/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-07/src/main.rs b/listings/ch04-understanding-ownership/listing-04-07/src/main.rs new file mode 100755 index 0000000..3bb3c85 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-07/src/main.rs @@ -0,0 +1,21 @@ +// ANCHOR: here +fn first_word(s: &String) -> usize { + // ANCHOR: as_bytes + let bytes = s.as_bytes(); + // ANCHOR_END: as_bytes + + // ANCHOR: iter + for (i, &item) in bytes.iter().enumerate() { + // ANCHOR_END: iter + // ANCHOR: inside_for + if item == b' ' { + return i; + } + } + + s.len() + // ANCHOR_END: inside_for +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch04-understanding-ownership/listing-04-08/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-08/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-08/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-08/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-08/src/main.rs b/listings/ch04-understanding-ownership/listing-04-08/src/main.rs new file mode 100755 index 0000000..b6182fe --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-08/src/main.rs @@ -0,0 +1,24 @@ +fn first_word(s: &String) -> usize { + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return i; + } + } + + s.len() +} + +// ANCHOR: here +fn main() { + let mut s = String::from("hello world"); + + let word = first_word(&s); // word will get the value 5 + + 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! +} +// ANCHOR_END: here diff --git a/listings/ch04-understanding-ownership/listing-04-09/Cargo.lock b/listings/ch04-understanding-ownership/listing-04-09/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/listing-04-09/Cargo.toml b/listings/ch04-understanding-ownership/listing-04-09/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/listing-04-09/src/main.rs b/listings/ch04-understanding-ownership/listing-04-09/src/main.rs new file mode 100755 index 0000000..5a6ceaa --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-09/src/main.rs @@ -0,0 +1,36 @@ +// ANCHOR: here +fn first_word(s: &str) -> &str { + // ANCHOR_END: here + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return &s[0..i]; + } + } + + &s[..] +} + +// ANCHOR: usage +fn main() { + let my_string = String::from("hello world"); + + // `first_word` works on slices of `String`s, whether partial or whole + let word = first_word(&my_string[0..6]); + let word = first_word(&my_string[..]); + // `first_word` also works on references to `String`s, which are equivalent + // to whole slices of `String`s + let word = first_word(&my_string); + + let my_string_literal = "hello world"; + + // `first_word` works on slices of string literals, whether partial or whole + let word = first_word(&my_string_literal[0..6]); + let word = first_word(&my_string_literal[..]); + + // Because string literals *are* string slices already, + // this works too, without the slice syntax! + let word = first_word(my_string_literal); +} +// ANCHOR_END: usage diff --git a/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs new file mode 100755 index 0000000..b68f0f1 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + let mut s = String::from("hello"); + + s.push_str(", world!"); // push_str() appends a literal to a String + + println!("{}", s); // This will print `hello, world!` + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.lock new file mode 100755 index 0000000..9e4e62d --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-02-string-scope/rustfmt-ignore b/listings/ch04-understanding-ownership/no-listing-02-string-scope/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-02-string-scope/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs b/listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs new file mode 100755 index 0000000..7e6d46f --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + { + let s = String::from("hello"); // s is valid from this point forward + + // do stuff with s + } // this scope is now over, and s is no + // longer valid + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs b/listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs new file mode 100755 index 0000000..a5817e7 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let s1 = String::from("hello"); + let s2 = s1; + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt new file mode 100755 index 0000000..210ed9a --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling ownership v0.1.0 (file:///projects/ownership) +error[E0382]: borrow of moved value: `s1` + --> src/main.rs:5:28 + | +2 | let s1 = String::from("hello"); + | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait +3 | let s2 = s1; + | -- value moved here +4 | +5 | println!("{}, world!", s1); + | ^^ value borrowed here after move + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `ownership` due to previous error diff --git a/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs new file mode 100755 index 0000000..d0b9f18 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let s1 = String::from("hello"); + let s2 = s1; + + println!("{}, world!", s1); + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs b/listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs new file mode 100755 index 0000000..4e61cc1 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let s1 = String::from("hello"); + let s2 = s1.clone(); + + println!("s1 = {}, s2 = {}", s1, s2); + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-06-copy/src/main.rs b/listings/ch04-understanding-ownership/no-listing-06-copy/src/main.rs new file mode 100755 index 0000000..63a1fae --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-06-copy/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let x = 5; + let y = x; + + println!("x = {}, y = {}", x, y); + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs b/listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs new file mode 100755 index 0000000..fd32a5f --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs @@ -0,0 +1,15 @@ +// ANCHOR: all +fn main() { + // ANCHOR: here + let s1 = String::from("hello"); + + let len = calculate_length(&s1); + // ANCHOR_END: here + + println!("The length of '{}' is {}.", s1, len); +} + +fn calculate_length(s: &String) -> usize { + s.len() +} +// ANCHOR_END: all diff --git a/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.lock new file mode 100755 index 0000000..9e4e62d --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/rustfmt-ignore b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs new file mode 100755 index 0000000..6e40b8c --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + let s1 = String::from("hello"); + + let len = calculate_length(&s1); + + println!("The length of '{}' is {}.", s1, len); +} + +// ANCHOR: here +fn calculate_length(s: &String) -> usize { // s is a reference to a String + s.len() +} // Here, s goes out of scope. But because it does not have ownership of what + // it refers to, nothing happens. +// ANCHOR_END: here diff --git a/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs new file mode 100755 index 0000000..fdf7f0a --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let mut s = String::from("hello"); + + change(&mut s); +} + +fn change(some_string: &mut String) { + some_string.push_str(", world"); +} diff --git a/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt new file mode 100755 index 0000000..71c29f6 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling ownership v0.1.0 (file:///projects/ownership) +error[E0499]: cannot borrow `s` as mutable more than once at a time + --> src/main.rs:5:14 + | +4 | let r1 = &mut s; + | ------ first mutable borrow occurs here +5 | let r2 = &mut s; + | ^^^^^^ second mutable borrow occurs here +6 | +7 | println!("{}, {}", r1, r2); + | -- first borrow later used here + +For more information about this error, try `rustc --explain E0499`. +error: could not compile `ownership` due to previous error diff --git a/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs new file mode 100755 index 0000000..ddbf812 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + let mut s = String::from("hello"); + + let r1 = &mut s; + let r2 = &mut s; + + println!("{}, {}", r1, r2); + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs new file mode 100755 index 0000000..4b1a5a3 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let mut s = String::from("hello"); + + { + let r1 = &mut s; + } // r1 goes out of scope here, so we can make a new reference with no problems. + + let r2 = &mut s; + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt new file mode 100755 index 0000000..df94c30 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling ownership v0.1.0 (file:///projects/ownership) +error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable + --> src/main.rs:6:14 + | +4 | let r1 = &s; // no problem + | -- immutable borrow occurs here +5 | let r2 = &s; // no problem +6 | let r3 = &mut s; // BIG PROBLEM + | ^^^^^^ mutable borrow occurs here +7 | +8 | println!("{}, {}, and {}", r1, r2, r3); + | -- immutable borrow later used here + +For more information about this error, try `rustc --explain E0502`. +error: could not compile `ownership` due to previous error diff --git a/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs new file mode 100755 index 0000000..0da04c0 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let mut s = String::from("hello"); + + let r1 = &s; // no problem + let r2 = &s; // no problem + let r3 = &mut s; // BIG PROBLEM + + println!("{}, {}, and {}", r1, r2, r3); + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs new file mode 100755 index 0000000..8619449 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + let mut s = String::from("hello"); + + let r1 = &s; // no problem + let r2 = &s; // no problem + println!("{} and {}", r1, r2); + // variables r1 and r2 will not be used after this point + + let r3 = &mut s; // no problem + println!("{}", r3); + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt new file mode 100755 index 0000000..fddca68 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling ownership v0.1.0 (file:///projects/ownership) +error[E0106]: missing lifetime specifier + --> src/main.rs:5:16 + | +5 | fn dangle() -> &String { + | ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime + | +5 | fn dangle() -> &'static String { + | ~~~~~~~~ + +For more information about this error, try `rustc --explain E0106`. +error: could not compile `ownership` due to previous error diff --git a/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs new file mode 100755 index 0000000..b102697 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let reference_to_nothing = dangle(); +} + +fn dangle() -> &String { + let s = String::from("hello"); + + &s +} diff --git a/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.lock new file mode 100755 index 0000000..9e4e62d --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/rustfmt-ignore b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs new file mode 100755 index 0000000..9fbb372 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + let reference_to_nothing = dangle(); +} + +// ANCHOR: here +fn dangle() -> &String { // dangle returns a reference to a String + + let s = String::from("hello"); // s is a new String + + &s // we return a reference to the String, s +} // Here, s goes out of scope, and is dropped. Its memory goes away. + // Danger! +// ANCHOR_END: here diff --git a/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs new file mode 100755 index 0000000..9c20a3b --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let string = no_dangle(); +} + +// ANCHOR: here +fn no_dangle() -> String { + let s = String::from("hello"); + + s +} +// ANCHOR_END: here diff --git a/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs b/listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs new file mode 100755 index 0000000..44163af --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let s = String::from("hello world"); + + let hello = &s[0..5]; + let world = &s[6..11]; + // ANCHOR_END: here +} diff --git a/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs new file mode 100755 index 0000000..f44a970 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs @@ -0,0 +1,15 @@ +// ANCHOR: here +fn first_word(s: &String) -> &str { + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return &s[0..i]; + } + } + + &s[..] +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.lock b/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.toml b/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt b/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt new file mode 100755 index 0000000..62dc4ad --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling ownership v0.1.0 (file:///projects/ownership) +error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable + --> src/main.rs:18:5 + | +16 | let word = first_word(&s); + | -- immutable borrow occurs here +17 | +18 | s.clear(); // error! + | ^^^^^^^^^ mutable borrow occurs here +19 | +20 | println!("the first word is: {}", word); + | ---- immutable borrow later used here + +For more information about this error, try `rustc --explain E0502`. +error: could not compile `ownership` due to previous error diff --git a/listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs b/listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs new file mode 100755 index 0000000..99e0401 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs @@ -0,0 +1,23 @@ +fn first_word(s: &String) -> &str { + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return &s[0..i]; + } + } + + &s[..] +} + +// ANCHOR: here +fn main() { + let mut s = String::from("hello world"); + + let word = first_word(&s); + + s.clear(); // error! + + println!("the first word is: {}", word); +} +// ANCHOR_END: here diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs new file mode 100755 index 0000000..16dd15b --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs @@ -0,0 +1,10 @@ +// ANCHOR: here +struct User { + active: bool, + username: String, + email: String, + sign_in_count: u64, +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs new file mode 100755 index 0000000..e0f7a6c --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs @@ -0,0 +1,17 @@ +struct User { + active: bool, + username: String, + email: String, + sign_in_count: u64, +} + +// ANCHOR: here +fn main() { + let user1 = User { + email: String::from("someone@example.com"), + username: String::from("someusername123"), + active: true, + sign_in_count: 1, + }; +} +// ANCHOR_END: here diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs new file mode 100755 index 0000000..7a078e7 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs @@ -0,0 +1,19 @@ +struct User { + active: bool, + username: String, + email: String, + sign_in_count: u64, +} + +// ANCHOR: here +fn main() { + let mut user1 = User { + email: String::from("someone@example.com"), + username: String::from("someusername123"), + active: true, + sign_in_count: 1, + }; + + user1.email = String::from("anotheremail@example.com"); +} +// ANCHOR_END: here diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs new file mode 100755 index 0000000..aa7823a --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs @@ -0,0 +1,24 @@ +struct User { + active: bool, + username: String, + email: String, + sign_in_count: u64, +} + +// ANCHOR: here +fn build_user(email: String, username: String) -> User { + User { + email: email, + username: username, + active: true, + sign_in_count: 1, + } +} +// ANCHOR_END: here + +fn main() { + let user1 = build_user( + String::from("someone@example.com"), + String::from("someusername123"), + ); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs new file mode 100755 index 0000000..8d84a30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs @@ -0,0 +1,24 @@ +struct User { + active: bool, + username: String, + email: String, + sign_in_count: u64, +} + +// ANCHOR: here +fn build_user(email: String, username: String) -> User { + User { + email, + username, + active: true, + sign_in_count: 1, + } +} +// ANCHOR_END: here + +fn main() { + let user1 = build_user( + String::from("someone@example.com"), + String::from("someusername123"), + ); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs new file mode 100755 index 0000000..15e7690 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs @@ -0,0 +1,28 @@ +struct User { + active: bool, + username: String, + email: String, + sign_in_count: u64, +} + +// ANCHOR: here +fn main() { + // --snip-- + // ANCHOR_END: here + + let user1 = User { + email: String::from("someone@example.com"), + username: String::from("someusername123"), + active: true, + sign_in_count: 1, + }; + // ANCHOR: here + + let user2 = User { + active: user1.active, + username: user1.username, + email: String::from("another@example.com"), + sign_in_count: user1.sign_in_count, + }; +} +// ANCHOR_END: here diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs new file mode 100755 index 0000000..008ad18 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs @@ -0,0 +1,26 @@ +struct User { + active: bool, + username: String, + email: String, + sign_in_count: u64, +} + +// ANCHOR: here +fn main() { + // --snip-- + // ANCHOR_END: here + + let user1 = User { + email: String::from("someone@example.com"), + username: String::from("someusername123"), + active: true, + sign_in_count: 1, + }; + // ANCHOR: here + + let user2 = User { + email: String::from("another@example.com"), + ..user1 + }; +} +// ANCHOR_END: here diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt new file mode 100755 index 0000000..c44b582 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling rectangles v0.1.0 (file:///projects/rectangles) + Finished dev [unoptimized + debuginfo] target(s) in 0.42s + Running `target/debug/rectangles` +The area of the rectangle is 1500 square pixels. diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs new file mode 100755 index 0000000..f324529 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs @@ -0,0 +1,17 @@ +// ANCHOR: all +fn main() { + let width1 = 30; + let height1 = 50; + + println!( + "The area of the rectangle is {} square pixels.", + area(width1, height1) + ); +} + +// ANCHOR: here +fn area(width: u32, height: u32) -> u32 { + // ANCHOR_END: here + width * height +} +// ANCHOR_END: all diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs new file mode 100755 index 0000000..d4b77ba --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + let rect1 = (30, 50); + + println!( + "The area of the rectangle is {} square pixels.", + area(rect1) + ); +} + +fn area(dimensions: (u32, u32)) -> u32 { + dimensions.0 * dimensions.1 +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs new file mode 100755 index 0000000..62ef9ac --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs @@ -0,0 +1,20 @@ +struct Rectangle { + width: u32, + height: u32, +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + println!( + "The area of the rectangle is {} square pixels.", + area(&rect1) + ); +} + +fn area(rectangle: &Rectangle) -> u32 { + rectangle.width * rectangle.height +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt new file mode 100755 index 0000000..b761fcc --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling rectangles v0.1.0 (file:///projects/rectangles) +error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` + --> src/main.rs:12:29 + | +12 | println!("rect1 is {}", rect1); + | ^^^^^ `Rectangle` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Rectangle` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `rectangles` due to previous error diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs new file mode 100755 index 0000000..0ff8dcc --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs @@ -0,0 +1,13 @@ +struct Rectangle { + width: u32, + height: u32, +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + println!("rect1 is {}", rect1); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt new file mode 100755 index 0000000..c37be6b --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling rectangles v0.1.0 (file:///projects/rectangles) + Finished dev [unoptimized + debuginfo] target(s) in 0.48s + Running `target/debug/rectangles` +rect1 is Rectangle { width: 30, height: 50 } diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs new file mode 100755 index 0000000..2ffc4b8 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs @@ -0,0 +1,14 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + println!("rect1 is {:?}", rect1); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs new file mode 100755 index 0000000..e4f45e8 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs @@ -0,0 +1,23 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +impl Rectangle { + fn area(&self) -> u32 { + self.width * self.height + } +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + println!( + "The area of the rectangle is {} square pixels.", + rect1.area() + ); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs new file mode 100755 index 0000000..843dab4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs @@ -0,0 +1,17 @@ +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + let rect2 = Rectangle { + width: 10, + height: 40, + }; + let rect3 = Rectangle { + width: 60, + height: 45, + }; + + println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); + println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs new file mode 100755 index 0000000..e6a3272 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs @@ -0,0 +1,35 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +// ANCHOR: here +impl Rectangle { + fn area(&self) -> u32 { + self.width * self.height + } + + fn can_hold(&self, other: &Rectangle) -> bool { + self.width > other.width && self.height > other.height + } +} +// ANCHOR_END: here + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + let rect2 = Rectangle { + width: 10, + height: 40, + }; + let rect3 = Rectangle { + width: 60, + height: 45, + }; + + println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); + println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs new file mode 100755 index 0000000..a5d3f77 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs @@ -0,0 +1,37 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +// ANCHOR: here +impl Rectangle { + fn area(&self) -> u32 { + self.width * self.height + } +} + +impl Rectangle { + fn can_hold(&self, other: &Rectangle) -> bool { + self.width > other.width && self.height > other.height + } +} +// ANCHOR_END: here + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + let rect2 = Rectangle { + width: 10, + height: 40, + }; + let rect3 = Rectangle { + width: 60, + height: 45, + }; + + println!("Can rect1 hold rect2? {}", rect1.can_hold(&rect2)); + println!("Can rect1 hold rect3? {}", rect1.can_hold(&rect3)); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs new file mode 100755 index 0000000..0d99316 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs @@ -0,0 +1,7 @@ +struct Color(i32, i32, i32); +struct Point(i32, i32, i32); + +fn main() { + let black = Color(0, 0, 0); + let origin = Point(0, 0, 0); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.lock new file mode 100755 index 0000000..bede081 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "structs" +version = "0.1.0" + diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.toml new file mode 100755 index 0000000..d36dbc1 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt new file mode 100755 index 0000000..e28da59 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt @@ -0,0 +1,31 @@ +$ cargo run + Compiling structs v0.1.0 (file:///projects/structs) +error[E0106]: missing lifetime specifier + --> src/main.rs:3:15 + | +3 | username: &str, + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +1 ~ struct User<'a> { +2 | active: bool, +3 ~ username: &'a str, + | + +error[E0106]: missing lifetime specifier + --> src/main.rs:4:12 + | +4 | email: &str, + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +1 ~ struct User<'a> { +2 | active: bool, +3 | username: &str, +4 ~ email: &'a str, + | + +For more information about this error, try `rustc --explain E0106`. +error: could not compile `structs` due to 2 previous errors diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/src/main.rs new file mode 100755 index 0000000..96092d0 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/src/main.rs @@ -0,0 +1,15 @@ +struct User { + active: bool, + username: &str, + email: &str, + sign_in_count: u64, +} + +fn main() { + let user1 = User { + email: "someone@example.com", + username: "someusername123", + active: true, + sign_in_count: 1, + }; +} diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs new file mode 100755 index 0000000..d5b1692 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs @@ -0,0 +1,20 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +// ANCHOR: here +impl Rectangle { + fn square(size: u32) -> Rectangle { + Rectangle { + width: size, + height: size, + } + } +} +// ANCHOR_END: here + +fn main() { + let sq = Rectangle::square(3); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/Cargo.lock new file mode 100755 index 0000000..fb30ed9 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "structs" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/Cargo.toml new file mode 100755 index 0000000..3232b60 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "structs" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/src/main.rs new file mode 100755 index 0000000..d48c94e --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/src/main.rs @@ -0,0 +1,5 @@ +struct AlwaysEqual; + +fn main() { + let subject = AlwaysEqual; +} diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt new file mode 100755 index 0000000..2685859 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt @@ -0,0 +1,9 @@ +$ cargo run + Compiling rectangles v0.1.0 (file:///projects/rectangles) + Finished dev [unoptimized + debuginfo] target(s) in 0.61s + Running `target/debug/rectangles` +[src/main.rs:10] 30 * scale = 60 +[src/main.rs:14] &rect1 = Rectangle { + width: 60, + height: 50, +} diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/src/main.rs new file mode 100755 index 0000000..dd03429 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/src/main.rs @@ -0,0 +1,15 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +fn main() { + let scale = 2; + let rect1 = Rectangle { + width: dbg!(30 * scale), + height: 50, + }; + + dbg!(&rect1); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/src/main.rs new file mode 100755 index 0000000..00e1de8 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/src/main.rs @@ -0,0 +1,24 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +// ANCHOR: here +impl Rectangle { + fn width(&self) -> bool { + self.width > 0 + } +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + if rect1.width() { + println!("The rectangle has a nonzero width; it is {}", rect1.width); + } +} +// ANCHOR_END: here diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt new file mode 100755 index 0000000..8b9c2ab --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling rectangles v0.1.0 (file:///projects/rectangles) +error[E0277]: `Rectangle` doesn't implement `Debug` + --> src/main.rs:12:31 + | +12 | println!("rect1 is {:?}", rect1); + | ^^^^^ `Rectangle` cannot be formatted using `{:?}` + | + = help: the trait `Debug` is not implemented for `Rectangle` + = note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle` + = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `rectangles` due to previous error diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs new file mode 100755 index 0000000..019a357 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs @@ -0,0 +1,13 @@ +struct Rectangle { + width: u32, + height: u32, +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + println!("rect1 is {:?}", rect1); +} diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.lock b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.lock new file mode 100755 index 0000000..4aabe7d --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangles" +version = "0.1.0" diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.toml b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.toml new file mode 100755 index 0000000..4a279a4 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangles" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt new file mode 100755 index 0000000..db6deed --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt @@ -0,0 +1,8 @@ +$ cargo run + Compiling rectangles v0.1.0 (file:///projects/rectangles) + Finished dev [unoptimized + debuginfo] target(s) in 0.48s + Running `target/debug/rectangles` +rect1 is Rectangle { + width: 30, + height: 50, +} diff --git a/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs new file mode 100755 index 0000000..84e32ae --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs @@ -0,0 +1,14 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +fn main() { + let rect1 = Rectangle { + width: 30, + height: 50, + }; + + println!("rect1 is {:#?}", rect1); +} diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.lock b/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.toml b/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs b/listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs new file mode 100755 index 0000000..5b688e0 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs @@ -0,0 +1,23 @@ +fn main() { + // ANCHOR: here + enum IpAddrKind { + V4, + V6, + } + + struct IpAddr { + kind: IpAddrKind, + address: String, + } + + let home = IpAddr { + kind: IpAddrKind::V4, + address: String::from("127.0.0.1"), + }; + + let loopback = IpAddr { + kind: IpAddrKind::V6, + address: String::from("::1"), + }; + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.lock b/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.toml b/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs b/listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs new file mode 100755 index 0000000..3ba7497 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs @@ -0,0 +1,10 @@ +// ANCHOR: here +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(i32, i32, i32), +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.lock b/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.toml b/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs b/listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs new file mode 100755 index 0000000..93dce48 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs @@ -0,0 +1,19 @@ +// ANCHOR: here +enum Coin { + Penny, + Nickel, + Dime, + Quarter, +} + +fn value_in_cents(coin: Coin) -> u8 { + match coin { + Coin::Penny => 1, + Coin::Nickel => 5, + Coin::Dime => 10, + Coin::Quarter => 25, + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.lock b/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.toml b/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs b/listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs new file mode 100755 index 0000000..3ba384f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +#[derive(Debug)] // so we can inspect the state in a minute +enum UsState { + Alabama, + Alaska, + // --snip-- +} + +enum Coin { + Penny, + Nickel, + Dime, + Quarter(UsState), +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.lock b/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.toml b/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs b/listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs new file mode 100755 index 0000000..c86190a --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs @@ -0,0 +1,18 @@ +fn main() { + // ANCHOR: here + fn plus_one(x: Option) -> Option { + match x { + // ANCHOR: first_arm + None => None, + // ANCHOR_END: first_arm + // ANCHOR: second_arm + Some(i) => Some(i + 1), + // ANCHOR_END: second_arm + } + } + + let five = Some(5); + let six = plus_one(five); + let none = plus_one(None); + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.lock b/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.toml b/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs b/listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs new file mode 100755 index 0000000..dc2bffb --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + let config_max = Some(3u8); + match config_max { + Some(max) => println!("The maximum is configured to be {}", max), + _ => (), + } + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs new file mode 100755 index 0000000..c631e56 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs @@ -0,0 +1,22 @@ +// ANCHOR: def +enum IpAddrKind { + V4, + V6, +} +// ANCHOR_END: def + +fn main() { + // ANCHOR: instance + let four = IpAddrKind::V4; + let six = IpAddrKind::V6; + // ANCHOR_END: instance + + // ANCHOR: fn_call + route(IpAddrKind::V4); + route(IpAddrKind::V6); + // ANCHOR_END: fn_call +} + +// ANCHOR: fn +fn route(ip_kind: IpAddrKind) {} +// ANCHOR_END: fn diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs new file mode 100755 index 0000000..7d59b81 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: here + enum IpAddr { + V4(String), + V6(String), + } + + let home = IpAddr::V4(String::from("127.0.0.1")); + + let loopback = IpAddr::V6(String::from("::1")); + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs new file mode 100755 index 0000000..844a140 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: here + enum IpAddr { + V4(u8, u8, u8, u8), + V6(String), + } + + let home = IpAddr::V4(127, 0, 0, 1); + + let loopback = IpAddr::V6(String::from("::1")); + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs new file mode 100755 index 0000000..df451be --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +struct QuitMessage; // unit struct +struct MoveMessage { + x: i32, + y: i32, +} +struct WriteMessage(String); // tuple struct +struct ChangeColorMessage(i32, i32, i32); // tuple struct + // ANCHOR_END: here + +fn main() {} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs new file mode 100755 index 0000000..66e0b6d --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs @@ -0,0 +1,19 @@ +fn main() { + enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(i32, i32, i32), + } + + // ANCHOR: here + impl Message { + fn call(&self) { + // method body would be defined here + } + } + + let m = Message::Write(String::from("hello")); + m.call(); + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs new file mode 100755 index 0000000..9de5791 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let some_number = Some(5); + let some_string = Some("a string"); + + let absent_number: Option = None; + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt new file mode 100755 index 0000000..343b9d2 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling enums v0.1.0 (file:///projects/enums) +error[E0277]: cannot add `Option` to `i8` + --> src/main.rs:5:17 + | +5 | let sum = x + y; + | ^ no implementation for `i8 + Option` + | + = help: the trait `Add>` is not implemented for `i8` + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `enums` due to previous error diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs new file mode 100755 index 0000000..ec65565 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let x: i8 = 5; + let y: Option = Some(5); + + let sum = x + y; + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs new file mode 100755 index 0000000..3f909dc --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs @@ -0,0 +1,22 @@ +enum Coin { + Penny, + Nickel, + Dime, + Quarter, +} + +// ANCHOR: here +fn value_in_cents(coin: Coin) -> u8 { + match coin { + Coin::Penny => { + println!("Lucky penny!"); + 1 + } + Coin::Nickel => 5, + Coin::Dime => 10, + Coin::Quarter => 25, + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs new file mode 100755 index 0000000..a4d500c --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs @@ -0,0 +1,31 @@ +#[derive(Debug)] +enum UsState { + Alabama, + Alaska, + // --snip-- +} + +enum Coin { + Penny, + Nickel, + Dime, + Quarter(UsState), +} + +// ANCHOR: here +fn value_in_cents(coin: Coin) -> u8 { + match coin { + Coin::Penny => 1, + Coin::Nickel => 5, + Coin::Dime => 10, + Coin::Quarter(state) => { + println!("State quarter from {:?}!", state); + 25 + } + } +} +// ANCHOR_END: here + +fn main() { + value_in_cents(Coin::Quarter(UsState::Alaska)); +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt new file mode 100755 index 0000000..8054e7d --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt @@ -0,0 +1,13 @@ +$ cargo run + Compiling enums v0.1.0 (file:///projects/enums) +error[E0004]: non-exhaustive patterns: `None` not covered + --> src/main.rs:3:15 + | +3 | match x { + | ^ pattern `None` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `Option` + +For more information about this error, try `rustc --explain E0004`. +error: could not compile `enums` due to previous error diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs new file mode 100755 index 0000000..f1963d0 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + fn plus_one(x: Option) -> Option { + match x { + Some(i) => Some(i + 1), + } + } + // ANCHOR_END: here + + let five = Some(5); + let six = plus_one(five); + let none = plus_one(None); +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/src/main.rs new file mode 100755 index 0000000..735086d --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let config_max = Some(3u8); + if let Some(max) = config_max { + println!("The maximum is configured to be {}", max); + } + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs new file mode 100755 index 0000000..12c4c0f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs @@ -0,0 +1,24 @@ +#[derive(Debug)] +enum UsState { + Alabama, + Alaska, + // --snip-- +} + +enum Coin { + Penny, + Nickel, + Dime, + Quarter(UsState), +} + +fn main() { + let coin = Coin::Penny; + // ANCHOR: here + let mut count = 0; + match coin { + Coin::Quarter(state) => println!("State quarter from {:?}!", state), + _ => count += 1, + } + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs new file mode 100755 index 0000000..ba7eda2 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs @@ -0,0 +1,25 @@ +#[derive(Debug)] +enum UsState { + Alabama, + Alaska, + // --snip-- +} + +enum Coin { + Penny, + Nickel, + Dime, + Quarter(UsState), +} + +fn main() { + let coin = Coin::Penny; + // ANCHOR: here + let mut count = 0; + if let Coin::Quarter(state) = coin { + println!("State quarter from {:?}!", state); + } else { + count += 1; + } + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs new file mode 100755 index 0000000..6ce0b59 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + // ANCHOR: here + let dice_roll = 9; + match dice_roll { + 3 => add_fancy_hat(), + 7 => remove_fancy_hat(), + other => move_player(other), + } + + fn add_fancy_hat() {} + fn remove_fancy_hat() {} + fn move_player(num_spaces: u8) {} + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/src/main.rs new file mode 100755 index 0000000..586e237 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + // ANCHOR: here + let dice_roll = 9; + match dice_roll { + 3 => add_fancy_hat(), + 7 => remove_fancy_hat(), + _ => reroll(), + } + + fn add_fancy_hat() {} + fn remove_fancy_hat() {} + fn reroll() {} + // ANCHOR_END: here +} diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/Cargo.lock new file mode 100755 index 0000000..f62e8ac --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/Cargo.toml new file mode 100755 index 0000000..e959295 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "enums" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/src/main.rs new file mode 100755 index 0000000..e791742 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + let dice_roll = 9; + match dice_roll { + 3 => add_fancy_hat(), + 7 => remove_fancy_hat(), + _ => (), + } + + fn add_fancy_hat() {} + fn remove_fancy_hat() {} + // ANCHOR_END: here +} diff --git a/listings/ch07-managing-growing-projects/listing-07-01/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-01/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-01/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-01/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs new file mode 100755 index 0000000..591e245 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs @@ -0,0 +1,15 @@ +mod front_of_house { + mod hosting { + fn add_to_waitlist() {} + + fn seat_at_table() {} + } + + mod serving { + fn take_order() {} + + fn serve_order() {} + + fn take_payment() {} + } +} diff --git a/listings/ch07-managing-growing-projects/listing-07-03/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-03/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-03/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-03/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-03/output.txt b/listings/ch07-managing-growing-projects/listing-07-03/output.txt new file mode 100755 index 0000000..481dcb3 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-03/output.txt @@ -0,0 +1,28 @@ +$ cargo build + Compiling restaurant v0.1.0 (file:///projects/restaurant) +error[E0603]: module `hosting` is private + --> src/lib.rs:9:28 + | +9 | crate::front_of_house::hosting::add_to_waitlist(); + | ^^^^^^^ private module + | +note: the module `hosting` is defined here + --> src/lib.rs:2:5 + | +2 | mod hosting { + | ^^^^^^^^^^^ + +error[E0603]: module `hosting` is private + --> src/lib.rs:12:21 + | +12 | front_of_house::hosting::add_to_waitlist(); + | ^^^^^^^ private module + | +note: the module `hosting` is defined here + --> src/lib.rs:2:5 + | +2 | mod hosting { + | ^^^^^^^^^^^ + +For more information about this error, try `rustc --explain E0603`. +error: could not compile `restaurant` due to 2 previous errors diff --git a/listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs new file mode 100755 index 0000000..0b8a43c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs @@ -0,0 +1,13 @@ +mod front_of_house { + mod hosting { + fn add_to_waitlist() {} + } +} + +pub fn eat_at_restaurant() { + // Absolute path + crate::front_of_house::hosting::add_to_waitlist(); + + // Relative path + front_of_house::hosting::add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-05/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-05/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-05/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-05/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-05/output.txt b/listings/ch07-managing-growing-projects/listing-07-05/output.txt new file mode 100755 index 0000000..63eb89a --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-05/output.txt @@ -0,0 +1,28 @@ +$ cargo build + Compiling restaurant v0.1.0 (file:///projects/restaurant) +error[E0603]: function `add_to_waitlist` is private + --> src/lib.rs:9:37 + | +9 | crate::front_of_house::hosting::add_to_waitlist(); + | ^^^^^^^^^^^^^^^ private function + | +note: the function `add_to_waitlist` is defined here + --> src/lib.rs:3:9 + | +3 | fn add_to_waitlist() {} + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0603]: function `add_to_waitlist` is private + --> src/lib.rs:12:30 + | +12 | front_of_house::hosting::add_to_waitlist(); + | ^^^^^^^^^^^^^^^ private function + | +note: the function `add_to_waitlist` is defined here + --> src/lib.rs:3:9 + | +3 | fn add_to_waitlist() {} + | ^^^^^^^^^^^^^^^^^^^^ + +For more information about this error, try `rustc --explain E0603`. +error: could not compile `restaurant` due to 2 previous errors diff --git a/listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs new file mode 100755 index 0000000..05372db --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs @@ -0,0 +1,13 @@ +mod front_of_house { + pub mod hosting { + fn add_to_waitlist() {} + } +} + +pub fn eat_at_restaurant() { + // Absolute path + crate::front_of_house::hosting::add_to_waitlist(); + + // Relative path + front_of_house::hosting::add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-07/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-07/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-07/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-07/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs new file mode 100755 index 0000000..7b89ee7 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs @@ -0,0 +1,13 @@ +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +pub fn eat_at_restaurant() { + // Absolute path + crate::front_of_house::hosting::add_to_waitlist(); + + // Relative path + front_of_house::hosting::add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-08/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-08/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-08/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-08/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs new file mode 100755 index 0000000..7d4b597 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs @@ -0,0 +1,10 @@ +fn serve_order() {} + +mod back_of_house { + fn fix_incorrect_order() { + cook_order(); + super::serve_order(); + } + + fn cook_order() {} +} diff --git a/listings/ch07-managing-growing-projects/listing-07-09/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-09/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-09/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-09/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs new file mode 100755 index 0000000..92c4695 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs @@ -0,0 +1,27 @@ +mod back_of_house { + pub struct Breakfast { + pub toast: String, + seasonal_fruit: String, + } + + impl Breakfast { + pub fn summer(toast: &str) -> Breakfast { + Breakfast { + toast: String::from(toast), + seasonal_fruit: String::from("peaches"), + } + } + } +} + +pub fn eat_at_restaurant() { + // Order a breakfast in the summer with Rye toast + let mut meal = back_of_house::Breakfast::summer("Rye"); + // Change our mind about what bread we'd like + meal.toast = String::from("Wheat"); + println!("I'd like {} toast please", meal.toast); + + // The next line won't compile if we uncomment it; we're not allowed + // to see or modify the seasonal fruit that comes with the meal + // meal.seasonal_fruit = String::from("blueberries"); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-10/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-10/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-10/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-10/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs new file mode 100755 index 0000000..908f1df --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs @@ -0,0 +1,11 @@ +mod back_of_house { + pub enum Appetizer { + Soup, + Salad, + } +} + +pub fn eat_at_restaurant() { + let order1 = back_of_house::Appetizer::Soup; + let order2 = back_of_house::Appetizer::Salad; +} diff --git a/listings/ch07-managing-growing-projects/listing-07-11/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-11/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-11/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-11/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs new file mode 100755 index 0000000..44defd0 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs @@ -0,0 +1,13 @@ +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +use crate::front_of_house::hosting; + +pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-12/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-12/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-12/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-12/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs new file mode 100755 index 0000000..671bc10 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs @@ -0,0 +1,13 @@ +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +use self::front_of_house::hosting; + +pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-13/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-13/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-13/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-13/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs new file mode 100755 index 0000000..e886c24 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs @@ -0,0 +1,13 @@ +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +use crate::front_of_house::hosting::add_to_waitlist; + +pub fn eat_at_restaurant() { + add_to_waitlist(); + add_to_waitlist(); + add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-14/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-14/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-14/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-14/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-14/src/main.rs b/listings/ch07-managing-growing-projects/listing-07-14/src/main.rs new file mode 100755 index 0000000..4379e7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-14/src/main.rs @@ -0,0 +1,6 @@ +use std::collections::HashMap; + +fn main() { + let mut map = HashMap::new(); + map.insert(1, 2); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-15/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-15/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-15/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-15/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-15/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-15/src/lib.rs new file mode 100755 index 0000000..bfac3a0 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-15/src/lib.rs @@ -0,0 +1,18 @@ +// ANCHOR: here +use std::fmt; +use std::io; + +fn function1() -> fmt::Result { + // --snip-- + // ANCHOR_END: here + Ok(()) + // ANCHOR: here +} + +fn function2() -> io::Result<()> { + // --snip-- + // ANCHOR_END: here + Ok(()) + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch07-managing-growing-projects/listing-07-16/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-16/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-16/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-16/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-16/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-16/src/lib.rs new file mode 100755 index 0000000..843490b --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-16/src/lib.rs @@ -0,0 +1,18 @@ +// ANCHOR: here +use std::fmt::Result; +use std::io::Result as IoResult; + +fn function1() -> Result { + // --snip-- + // ANCHOR_END: here + Ok(()) + // ANCHOR: here +} + +fn function2() -> IoResult<()> { + // --snip-- + // ANCHOR_END: here + Ok(()) + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch07-managing-growing-projects/listing-07-17/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-17/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-17/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-17/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs new file mode 100755 index 0000000..835e571 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs @@ -0,0 +1,13 @@ +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +pub use crate::front_of_house::hosting; + +pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/listing-07-18/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-18/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-18/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch07-managing-growing-projects/listing-07-18/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-18/Cargo.toml new file mode 100755 index 0000000..15b3fff --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch07-managing-growing-projects/listing-07-18/src/main.rs b/listings/ch07-managing-growing-projects/listing-07-18/src/main.rs new file mode 100755 index 0000000..6c88bc4 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-18/src/main.rs @@ -0,0 +1,32 @@ +use rand::Rng; +// ANCHOR: here +// --snip-- +use std::{cmp::Ordering, io}; +// --snip-- +// ANCHOR_END: here + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + println!("The secret number is: {}", secret_number); + + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + let guess: u32 = guess.trim().parse().expect("Please type a number!"); + + println!("You guessed: {}", guess); + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => println!("You win!"), + } +} diff --git a/listings/ch07-managing-growing-projects/listing-07-19/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-19/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-19/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-19/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-19/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-19/src/lib.rs new file mode 100755 index 0000000..3fee46c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-19/src/lib.rs @@ -0,0 +1,2 @@ +use std::io; +use std::io::Write; diff --git a/listings/ch07-managing-growing-projects/listing-07-20/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-20/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-20/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-20/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-20/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-20/src/lib.rs new file mode 100755 index 0000000..341f40a --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-20/src/lib.rs @@ -0,0 +1 @@ +use std::io::{self, Write}; diff --git a/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.toml b/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs b/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs new file mode 100755 index 0000000..6875dfd --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs @@ -0,0 +1,3 @@ +pub mod hosting { + pub fn add_to_waitlist() {} +} diff --git a/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs b/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs new file mode 100755 index 0000000..065b1b8 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs @@ -0,0 +1,9 @@ +mod front_of_house; + +pub use crate::front_of_house::hosting; + +pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); +} diff --git a/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.lock b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.toml b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.toml new file mode 100755 index 0000000..cc63f6f --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs new file mode 100755 index 0000000..af1b2b4 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs @@ -0,0 +1,31 @@ +use rand::Rng; +// ANCHOR: here +// --snip-- +use std::cmp::Ordering; +use std::io; +// --snip-- +// ANCHOR_END: here + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + println!("The secret number is: {}", secret_number); + + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + println!("You guessed: {}", guess); + + match guess.cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => println!("You win!"), + } +} diff --git a/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.lock b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.lock new file mode 100755 index 0000000..f25ab35 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "restaurant" +version = "0.1.0" + diff --git a/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.toml b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.toml new file mode 100755 index 0000000..60cec7c --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "restaurant" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house.rs b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house.rs new file mode 100755 index 0000000..d0a8154 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house.rs @@ -0,0 +1 @@ +pub mod hosting; diff --git a/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs new file mode 100755 index 0000000..d65f3af --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs @@ -0,0 +1 @@ +pub fn add_to_waitlist() {} diff --git a/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/lib.rs b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/lib.rs new file mode 100755 index 0000000..065b1b8 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/lib.rs @@ -0,0 +1,9 @@ +mod front_of_house; + +pub use crate::front_of_house::hosting; + +pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); + hosting::add_to_waitlist(); +} diff --git a/listings/ch08-common-collections/listing-08-01/Cargo.lock b/listings/ch08-common-collections/listing-08-01/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-01/Cargo.toml b/listings/ch08-common-collections/listing-08-01/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-01/src/main.rs b/listings/ch08-common-collections/listing-08-01/src/main.rs new file mode 100755 index 0000000..45e4558 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-01/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + // ANCHOR: here + let v: Vec = Vec::new(); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-02/Cargo.lock b/listings/ch08-common-collections/listing-08-02/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-02/Cargo.toml b/listings/ch08-common-collections/listing-08-02/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-02/src/main.rs b/listings/ch08-common-collections/listing-08-02/src/main.rs new file mode 100755 index 0000000..3b10a53 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-02/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + // ANCHOR: here + let v = vec![1, 2, 3]; + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-03/Cargo.lock b/listings/ch08-common-collections/listing-08-03/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-03/Cargo.toml b/listings/ch08-common-collections/listing-08-03/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-03/src/main.rs b/listings/ch08-common-collections/listing-08-03/src/main.rs new file mode 100755 index 0000000..147223f --- /dev/null +++ b/listings/ch08-common-collections/listing-08-03/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + let mut v = Vec::new(); + + v.push(5); + v.push(6); + v.push(7); + v.push(8); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-04/Cargo.lock b/listings/ch08-common-collections/listing-08-04/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-04/Cargo.toml b/listings/ch08-common-collections/listing-08-04/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-04/src/main.rs b/listings/ch08-common-collections/listing-08-04/src/main.rs new file mode 100755 index 0000000..abda2db --- /dev/null +++ b/listings/ch08-common-collections/listing-08-04/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + { + let v = vec![1, 2, 3, 4]; + + // do stuff with v + } // <- v goes out of scope and is freed here + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-05/Cargo.lock b/listings/ch08-common-collections/listing-08-05/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-05/Cargo.toml b/listings/ch08-common-collections/listing-08-05/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-05/src/main.rs b/listings/ch08-common-collections/listing-08-05/src/main.rs new file mode 100755 index 0000000..9bfa37a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-05/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + let v = vec![1, 2, 3, 4, 5]; + + let third: &i32 = &v[2]; + println!("The third element is {}", third); + + match v.get(2) { + Some(third) => println!("The third element is {}", third), + None => println!("There is no third element."), + } + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-06/Cargo.lock b/listings/ch08-common-collections/listing-08-06/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-06/Cargo.toml b/listings/ch08-common-collections/listing-08-06/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-06/src/main.rs b/listings/ch08-common-collections/listing-08-06/src/main.rs new file mode 100755 index 0000000..783d9b1 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-06/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let v = vec![1, 2, 3, 4, 5]; + + let does_not_exist = &v[100]; + let does_not_exist = v.get(100); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-07/Cargo.lock b/listings/ch08-common-collections/listing-08-07/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-07/Cargo.toml b/listings/ch08-common-collections/listing-08-07/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-07/output.txt b/listings/ch08-common-collections/listing-08-07/output.txt new file mode 100755 index 0000000..ab512a9 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-07/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling collections v0.1.0 (file:///projects/collections) +error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable + --> src/main.rs:6:5 + | +4 | let first = &v[0]; + | - immutable borrow occurs here +5 | +6 | v.push(6); + | ^^^^^^^^^ mutable borrow occurs here +7 | +8 | println!("The first element is: {}", first); + | ----- immutable borrow later used here + +For more information about this error, try `rustc --explain E0502`. +error: could not compile `collections` due to previous error diff --git a/listings/ch08-common-collections/listing-08-07/src/main.rs b/listings/ch08-common-collections/listing-08-07/src/main.rs new file mode 100755 index 0000000..1b42274 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-07/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let mut v = vec![1, 2, 3, 4, 5]; + + let first = &v[0]; + + v.push(6); + + println!("The first element is: {}", first); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-08/Cargo.lock b/listings/ch08-common-collections/listing-08-08/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-08/Cargo.toml b/listings/ch08-common-collections/listing-08-08/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-08/src/main.rs b/listings/ch08-common-collections/listing-08-08/src/main.rs new file mode 100755 index 0000000..38b9778 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-08/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let v = vec![100, 32, 57]; + for i in &v { + println!("{}", i); + } + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-09/Cargo.lock b/listings/ch08-common-collections/listing-08-09/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-09/Cargo.toml b/listings/ch08-common-collections/listing-08-09/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-09/src/main.rs b/listings/ch08-common-collections/listing-08-09/src/main.rs new file mode 100755 index 0000000..c62ba21 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-09/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let mut v = vec![100, 32, 57]; + for i in &mut v { + *i += 50; + } + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-10/Cargo.lock b/listings/ch08-common-collections/listing-08-10/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-10/Cargo.toml b/listings/ch08-common-collections/listing-08-10/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-10/src/main.rs b/listings/ch08-common-collections/listing-08-10/src/main.rs new file mode 100755 index 0000000..c219888 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-10/src/main.rs @@ -0,0 +1,15 @@ +fn main() { + // ANCHOR: here + enum SpreadsheetCell { + Int(i32), + Float(f64), + Text(String), + } + + let row = vec![ + SpreadsheetCell::Int(3), + SpreadsheetCell::Text(String::from("blue")), + SpreadsheetCell::Float(10.12), + ]; + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-11/Cargo.lock b/listings/ch08-common-collections/listing-08-11/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-11/Cargo.toml b/listings/ch08-common-collections/listing-08-11/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-11/src/main.rs b/listings/ch08-common-collections/listing-08-11/src/main.rs new file mode 100755 index 0000000..4cf4c81 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-11/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + // ANCHOR: here + let mut s = String::new(); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-12/Cargo.lock b/listings/ch08-common-collections/listing-08-12/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-12/Cargo.toml b/listings/ch08-common-collections/listing-08-12/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-12/src/main.rs b/listings/ch08-common-collections/listing-08-12/src/main.rs new file mode 100755 index 0000000..d9e5e76 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-12/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + let data = "initial contents"; + + let s = data.to_string(); + + // the method also works on a literal directly: + let s = "initial contents".to_string(); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-13/Cargo.lock b/listings/ch08-common-collections/listing-08-13/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-13/Cargo.toml b/listings/ch08-common-collections/listing-08-13/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-13/src/main.rs b/listings/ch08-common-collections/listing-08-13/src/main.rs new file mode 100755 index 0000000..b81e374 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-13/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + // ANCHOR: here + let s = String::from("initial contents"); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-14/Cargo.lock b/listings/ch08-common-collections/listing-08-14/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-14/Cargo.toml b/listings/ch08-common-collections/listing-08-14/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-14/src/main.rs b/listings/ch08-common-collections/listing-08-14/src/main.rs new file mode 100755 index 0000000..f701fd5 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-14/src/main.rs @@ -0,0 +1,19 @@ +fn main() { + // ANCHOR: here + let hello = String::from("السلام عليكم"); + let hello = String::from("Dobrý den"); + let hello = String::from("Hello"); + let hello = String::from("שָׁלוֹם"); + let hello = String::from("नमस्ते"); + let hello = String::from("こんにちは"); + let hello = String::from("안녕하세요"); + let hello = String::from("你好"); + let hello = String::from("Olá"); + // ANCHOR: russian + let hello = String::from("Здравствуйте"); + // ANCHOR_END: russian + // ANCHOR: spanish + let hello = String::from("Hola"); + // ANCHOR_END: spanish + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-15/Cargo.lock b/listings/ch08-common-collections/listing-08-15/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-15/Cargo.toml b/listings/ch08-common-collections/listing-08-15/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-15/src/main.rs b/listings/ch08-common-collections/listing-08-15/src/main.rs new file mode 100755 index 0000000..7dec657 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-15/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let mut s = String::from("foo"); + s.push_str("bar"); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-16/Cargo.lock b/listings/ch08-common-collections/listing-08-16/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-16/Cargo.toml b/listings/ch08-common-collections/listing-08-16/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-16/src/main.rs b/listings/ch08-common-collections/listing-08-16/src/main.rs new file mode 100755 index 0000000..8938dc1 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-16/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let mut s1 = String::from("foo"); + let s2 = "bar"; + s1.push_str(s2); + println!("s2 is {}", s2); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-17/Cargo.lock b/listings/ch08-common-collections/listing-08-17/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-17/Cargo.toml b/listings/ch08-common-collections/listing-08-17/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-17/src/main.rs b/listings/ch08-common-collections/listing-08-17/src/main.rs new file mode 100755 index 0000000..0a9e8cc --- /dev/null +++ b/listings/ch08-common-collections/listing-08-17/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let mut s = String::from("lo"); + s.push('l'); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-18/Cargo.lock b/listings/ch08-common-collections/listing-08-18/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-18/Cargo.toml b/listings/ch08-common-collections/listing-08-18/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-18/src/main.rs b/listings/ch08-common-collections/listing-08-18/src/main.rs new file mode 100755 index 0000000..93939a6 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-18/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + let s1 = String::from("Hello, "); + let s2 = String::from("world!"); + let s3 = s1 + &s2; // note s1 has been moved here and can no longer be used + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-19/Cargo.lock b/listings/ch08-common-collections/listing-08-19/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-19/Cargo.toml b/listings/ch08-common-collections/listing-08-19/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-19/output.txt b/listings/ch08-common-collections/listing-08-19/output.txt new file mode 100755 index 0000000..2e5ad54 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-19/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling collections v0.1.0 (file:///projects/collections) +error[E0277]: the type `String` cannot be indexed by `{integer}` + --> src/main.rs:3:13 + | +3 | let h = s1[0]; + | ^^^^^ `String` cannot be indexed by `{integer}` + | + = help: the trait `Index<{integer}>` is not implemented for `String` + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `collections` due to previous error diff --git a/listings/ch08-common-collections/listing-08-19/src/main.rs b/listings/ch08-common-collections/listing-08-19/src/main.rs new file mode 100755 index 0000000..fc08e9c --- /dev/null +++ b/listings/ch08-common-collections/listing-08-19/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let s1 = String::from("hello"); + let h = s1[0]; + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-20/Cargo.lock b/listings/ch08-common-collections/listing-08-20/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-20/Cargo.toml b/listings/ch08-common-collections/listing-08-20/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-20/src/main.rs b/listings/ch08-common-collections/listing-08-20/src/main.rs new file mode 100755 index 0000000..54c2010 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-20/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + scores.insert(String::from("Yellow"), 50); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-21/Cargo.lock b/listings/ch08-common-collections/listing-08-21/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-21/Cargo.toml b/listings/ch08-common-collections/listing-08-21/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-21/src/main.rs b/listings/ch08-common-collections/listing-08-21/src/main.rs new file mode 100755 index 0000000..0ebd20d --- /dev/null +++ b/listings/ch08-common-collections/listing-08-21/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let teams = vec![String::from("Blue"), String::from("Yellow")]; + let initial_scores = vec![10, 50]; + + let mut scores: HashMap<_, _> = + teams.into_iter().zip(initial_scores.into_iter()).collect(); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-22/Cargo.lock b/listings/ch08-common-collections/listing-08-22/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-22/Cargo.toml b/listings/ch08-common-collections/listing-08-22/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-22/src/main.rs b/listings/ch08-common-collections/listing-08-22/src/main.rs new file mode 100755 index 0000000..2b2a73f --- /dev/null +++ b/listings/ch08-common-collections/listing-08-22/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let field_name = String::from("Favorite color"); + let field_value = String::from("Blue"); + + let mut map = HashMap::new(); + map.insert(field_name, field_value); + // field_name and field_value are invalid at this point, try using them and + // see what compiler error you get! + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-23/Cargo.lock b/listings/ch08-common-collections/listing-08-23/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-23/Cargo.toml b/listings/ch08-common-collections/listing-08-23/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-23/src/main.rs b/listings/ch08-common-collections/listing-08-23/src/main.rs new file mode 100755 index 0000000..508e33c --- /dev/null +++ b/listings/ch08-common-collections/listing-08-23/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + scores.insert(String::from("Yellow"), 50); + + let team_name = String::from("Blue"); + let score = scores.get(&team_name); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-24/Cargo.lock b/listings/ch08-common-collections/listing-08-24/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-24/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-24/Cargo.toml b/listings/ch08-common-collections/listing-08-24/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-24/src/main.rs b/listings/ch08-common-collections/listing-08-24/src/main.rs new file mode 100755 index 0000000..e8684cf --- /dev/null +++ b/listings/ch08-common-collections/listing-08-24/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + scores.insert(String::from("Blue"), 25); + + println!("{:?}", scores); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-25/Cargo.lock b/listings/ch08-common-collections/listing-08-25/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-25/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-25/Cargo.toml b/listings/ch08-common-collections/listing-08-25/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-25/src/main.rs b/listings/ch08-common-collections/listing-08-25/src/main.rs new file mode 100755 index 0000000..3ad97b5 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-25/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let mut scores = HashMap::new(); + scores.insert(String::from("Blue"), 10); + + scores.entry(String::from("Yellow")).or_insert(50); + scores.entry(String::from("Blue")).or_insert(50); + + println!("{:?}", scores); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/listing-08-26/Cargo.lock b/listings/ch08-common-collections/listing-08-26/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/listing-08-26/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/listing-08-26/Cargo.toml b/listings/ch08-common-collections/listing-08-26/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-26/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/listing-08-26/src/main.rs b/listings/ch08-common-collections/listing-08-26/src/main.rs new file mode 100755 index 0000000..f3f6aa1 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-26/src/main.rs @@ -0,0 +1,16 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let text = "hello world wonderful world"; + + let mut map = HashMap::new(); + + for word in text.split_whitespace() { + let count = map.entry(word).or_insert(0); + *count += 1; + } + + println!("{:?}", map); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.lock b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.toml b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/src/main.rs b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/src/main.rs new file mode 100755 index 0000000..4995650 --- /dev/null +++ b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + let s1 = String::from("tic"); + let s2 = String::from("tac"); + let s3 = String::from("toe"); + + let s = s1 + "-" + &s2 + "-" + &s3; + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/no-listing-02-format/Cargo.lock b/listings/ch08-common-collections/no-listing-02-format/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/no-listing-02-format/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/no-listing-02-format/Cargo.toml b/listings/ch08-common-collections/no-listing-02-format/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/no-listing-02-format/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/no-listing-02-format/src/main.rs b/listings/ch08-common-collections/no-listing-02-format/src/main.rs new file mode 100755 index 0000000..4a38e63 --- /dev/null +++ b/listings/ch08-common-collections/no-listing-02-format/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + let s1 = String::from("tic"); + let s2 = String::from("tac"); + let s3 = String::from("toe"); + + let s = format!("{}-{}-{}", s1, s2, s3); + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.lock b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.toml b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs new file mode 100755 index 0000000..2e7dc02 --- /dev/null +++ b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + scores.insert(String::from("Yellow"), 50); + + for (key, value) in &scores { + println!("{}: {}", key, value); + } + // ANCHOR_END: here +} diff --git a/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.lock b/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.lock new file mode 100755 index 0000000..d3daeff --- /dev/null +++ b/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "collections" +version = "0.1.0" + diff --git a/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.toml b/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.toml new file mode 100755 index 0000000..fe49598 --- /dev/null +++ b/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "collections" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt b/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt new file mode 100755 index 0000000..35db879 --- /dev/null +++ b/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling collections v0.1.0 (file:///projects/collections) + Finished dev [unoptimized + debuginfo] target(s) in 0.43s + Running `target/debug/collections` +thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of `Здравствуйте`', src/main.rs:4:14 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/listings/ch08-common-collections/output-only-01-not-char-boundary/src/main.rs b/listings/ch08-common-collections/output-only-01-not-char-boundary/src/main.rs new file mode 100755 index 0000000..9283ff5 --- /dev/null +++ b/listings/ch08-common-collections/output-only-01-not-char-boundary/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + let hello = "Здравствуйте"; + + let s = &hello[0..1]; +} diff --git a/listings/ch09-error-handling/listing-09-01/Cargo.lock b/listings/ch09-error-handling/listing-09-01/Cargo.lock new file mode 100755 index 0000000..4fe030f --- /dev/null +++ b/listings/ch09-error-handling/listing-09-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "panic" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-01/Cargo.toml b/listings/ch09-error-handling/listing-09-01/Cargo.toml new file mode 100755 index 0000000..660e2c8 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "panic" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-01/output.txt b/listings/ch09-error-handling/listing-09-01/output.txt new file mode 100755 index 0000000..89aebb9 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-01/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling panic v0.1.0 (file:///projects/panic) + Finished dev [unoptimized + debuginfo] target(s) in 0.27s + Running `target/debug/panic` +thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:4:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/listings/ch09-error-handling/listing-09-01/src/main.rs b/listings/ch09-error-handling/listing-09-01/src/main.rs new file mode 100755 index 0000000..70194ab --- /dev/null +++ b/listings/ch09-error-handling/listing-09-01/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + let v = vec![1, 2, 3]; + + v[99]; +} diff --git a/listings/ch09-error-handling/listing-09-03/Cargo.lock b/listings/ch09-error-handling/listing-09-03/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-03/Cargo.toml b/listings/ch09-error-handling/listing-09-03/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-03/src/main.rs b/listings/ch09-error-handling/listing-09-03/src/main.rs new file mode 100755 index 0000000..0dfd10b --- /dev/null +++ b/listings/ch09-error-handling/listing-09-03/src/main.rs @@ -0,0 +1,5 @@ +use std::fs::File; + +fn main() { + let f = File::open("hello.txt"); +} diff --git a/listings/ch09-error-handling/listing-09-04/Cargo.lock b/listings/ch09-error-handling/listing-09-04/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-04/Cargo.toml b/listings/ch09-error-handling/listing-09-04/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-04/output.txt b/listings/ch09-error-handling/listing-09-04/output.txt new file mode 100755 index 0000000..f776a59 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-04/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling error-handling v0.1.0 (file:///projects/error-handling) + Finished dev [unoptimized + debuginfo] target(s) in 0.73s + Running `target/debug/error-handling` +thread 'main' panicked at 'Problem opening the file: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/main.rs:8:23 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/listings/ch09-error-handling/listing-09-04/src/main.rs b/listings/ch09-error-handling/listing-09-04/src/main.rs new file mode 100755 index 0000000..070fc33 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-04/src/main.rs @@ -0,0 +1,10 @@ +use std::fs::File; + +fn main() { + let f = File::open("hello.txt"); + + let f = match f { + Ok(file) => file, + Err(error) => panic!("Problem opening the file: {:?}", error), + }; +} diff --git a/listings/ch09-error-handling/listing-09-05/Cargo.lock b/listings/ch09-error-handling/listing-09-05/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-05/Cargo.toml b/listings/ch09-error-handling/listing-09-05/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-05/src/main.rs b/listings/ch09-error-handling/listing-09-05/src/main.rs new file mode 100755 index 0000000..8c4f773 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-05/src/main.rs @@ -0,0 +1,19 @@ +use std::fs::File; +use std::io::ErrorKind; + +fn main() { + let f = File::open("hello.txt"); + + let f = match f { + Ok(file) => file, + Err(error) => match error.kind() { + ErrorKind::NotFound => match File::create("hello.txt") { + Ok(fc) => fc, + Err(e) => panic!("Problem creating the file: {:?}", e), + }, + other_error => { + panic!("Problem opening the file: {:?}", other_error) + } + }, + }; +} diff --git a/listings/ch09-error-handling/listing-09-06/Cargo.lock b/listings/ch09-error-handling/listing-09-06/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-06/Cargo.toml b/listings/ch09-error-handling/listing-09-06/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-06/src/main.rs b/listings/ch09-error-handling/listing-09-06/src/main.rs new file mode 100755 index 0000000..4f0a521 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-06/src/main.rs @@ -0,0 +1,24 @@ +// ANCHOR: here +use std::fs::File; +use std::io::{self, Read}; + +fn read_username_from_file() -> Result { + let f = File::open("hello.txt"); + + let mut f = match f { + Ok(file) => file, + Err(e) => return Err(e), + }; + + let mut s = String::new(); + + match f.read_to_string(&mut s) { + Ok(_) => Ok(s), + Err(e) => Err(e), + } +} +// ANCHOR_END: here + +fn main() { + let username = read_username_from_file().expect("Unable to get username"); +} diff --git a/listings/ch09-error-handling/listing-09-07/Cargo.lock b/listings/ch09-error-handling/listing-09-07/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-07/Cargo.toml b/listings/ch09-error-handling/listing-09-07/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-07/src/main.rs b/listings/ch09-error-handling/listing-09-07/src/main.rs new file mode 100755 index 0000000..b9f6172 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-07/src/main.rs @@ -0,0 +1,16 @@ +// ANCHOR: here +use std::fs::File; +use std::io; +use std::io::Read; + +fn read_username_from_file() -> Result { + let mut f = File::open("hello.txt")?; + let mut s = String::new(); + f.read_to_string(&mut s)?; + Ok(s) +} +// ANCHOR_END: here + +fn main() { + let username = read_username_from_file().expect("Unable to get username"); +} diff --git a/listings/ch09-error-handling/listing-09-08/Cargo.lock b/listings/ch09-error-handling/listing-09-08/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-08/Cargo.toml b/listings/ch09-error-handling/listing-09-08/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-08/src/main.rs b/listings/ch09-error-handling/listing-09-08/src/main.rs new file mode 100755 index 0000000..f36e4d0 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-08/src/main.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +use std::fs::File; +use std::io; +use std::io::Read; + +fn read_username_from_file() -> Result { + let mut s = String::new(); + + File::open("hello.txt")?.read_to_string(&mut s)?; + + Ok(s) +} +// ANCHOR_END: here + +fn main() { + let username = read_username_from_file().expect("Unable to get username"); +} diff --git a/listings/ch09-error-handling/listing-09-09/Cargo.lock b/listings/ch09-error-handling/listing-09-09/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-09/Cargo.toml b/listings/ch09-error-handling/listing-09-09/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-09/src/main.rs b/listings/ch09-error-handling/listing-09-09/src/main.rs new file mode 100755 index 0000000..4597dc2 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-09/src/main.rs @@ -0,0 +1,12 @@ +// ANCHOR: here +use std::fs; +use std::io; + +fn read_username_from_file() -> Result { + fs::read_to_string("hello.txt") +} +// ANCHOR_END: here + +fn main() { + let username = read_username_from_file().expect("Unable to get username"); +} diff --git a/listings/ch09-error-handling/listing-09-10/Cargo.lock b/listings/ch09-error-handling/listing-09-10/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-10/Cargo.toml b/listings/ch09-error-handling/listing-09-10/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-10/output.txt b/listings/ch09-error-handling/listing-09-10/output.txt new file mode 100755 index 0000000..6a8b1a4 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-10/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling error-handling v0.1.0 (file:///projects/error-handling) +error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) + --> src/main.rs:4:36 + | +3 | / fn main() { +4 | | let f = File::open("hello.txt")?; + | | ^ cannot use the `?` operator in a function that returns `()` +5 | | } + | |_- this function should return `Result` or `Option` to accept `?` + | + = help: the trait `FromResidual>` is not implemented for `()` + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `error-handling` due to previous error diff --git a/listings/ch09-error-handling/listing-09-10/src/main.rs b/listings/ch09-error-handling/listing-09-10/src/main.rs new file mode 100755 index 0000000..8608dc1 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-10/src/main.rs @@ -0,0 +1,5 @@ +use std::fs::File; + +fn main() { + let f = File::open("hello.txt")?; +} diff --git a/listings/ch09-error-handling/listing-09-11/Cargo.lock b/listings/ch09-error-handling/listing-09-11/Cargo.lock new file mode 100755 index 0000000..7320ae6 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-11/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "error-handling" +version = "0.1.0" diff --git a/listings/ch09-error-handling/listing-09-11/Cargo.toml b/listings/ch09-error-handling/listing-09-11/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-11/src/main.rs b/listings/ch09-error-handling/listing-09-11/src/main.rs new file mode 100755 index 0000000..bd53227 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-11/src/main.rs @@ -0,0 +1,15 @@ +// ANCHOR: here +fn last_char_of_first_line(text: &str) -> Option { + text.lines().next()?.chars().last() +} +// ANCHOR_END: here + +fn main() { + assert_eq!( + last_char_of_first_line("Hello, world\nHow are you today?"), + Some('d') + ); + + assert_eq!(last_char_of_first_line(""), None); + assert_eq!(last_char_of_first_line("\nhi"), None); +} diff --git a/listings/ch09-error-handling/listing-09-12/Cargo.lock b/listings/ch09-error-handling/listing-09-12/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/listing-09-12/Cargo.toml b/listings/ch09-error-handling/listing-09-12/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/listing-09-12/src/main.rs b/listings/ch09-error-handling/listing-09-12/src/main.rs new file mode 100755 index 0000000..7f16b8e --- /dev/null +++ b/listings/ch09-error-handling/listing-09-12/src/main.rs @@ -0,0 +1,8 @@ +use std::error::Error; +use std::fs::File; + +fn main() -> Result<(), Box> { + let f = File::open("hello.txt")?; + + Ok(()) +} diff --git a/listings/ch09-error-handling/listing-09-13/Cargo.lock b/listings/ch09-error-handling/listing-09-13/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-13/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch09-error-handling/listing-09-13/Cargo.toml b/listings/ch09-error-handling/listing-09-13/Cargo.toml new file mode 100755 index 0000000..15b3fff --- /dev/null +++ b/listings/ch09-error-handling/listing-09-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch09-error-handling/listing-09-13/src/main.rs b/listings/ch09-error-handling/listing-09-13/src/main.rs new file mode 100755 index 0000000..3375279 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-13/src/main.rs @@ -0,0 +1,55 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +// ANCHOR: here +pub struct Guess { + value: i32, +} + +impl Guess { + pub fn new(value: i32) -> Guess { + if value < 1 || value > 100 { + panic!("Guess value must be between 1 and 100, got {}.", value); + } + + Guess { value } + } + + pub fn value(&self) -> i32 { + self.value + } +} +// ANCHOR_END: here + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + loop { + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + let guess: i32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => continue, + }; + + let guess = Guess::new(guess); + + match guess.value().cmp(&secret_number) { + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => { + println!("You win!"); + break; + } + } + } +} diff --git a/listings/ch09-error-handling/no-listing-01-panic/Cargo.lock b/listings/ch09-error-handling/no-listing-01-panic/Cargo.lock new file mode 100755 index 0000000..4fe030f --- /dev/null +++ b/listings/ch09-error-handling/no-listing-01-panic/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "panic" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-01-panic/Cargo.toml b/listings/ch09-error-handling/no-listing-01-panic/Cargo.toml new file mode 100755 index 0000000..660e2c8 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-01-panic/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "panic" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-01-panic/output.txt b/listings/ch09-error-handling/no-listing-01-panic/output.txt new file mode 100755 index 0000000..b25ed85 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-01-panic/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling panic v0.1.0 (file:///projects/panic) + Finished dev [unoptimized + debuginfo] target(s) in 0.25s + Running `target/debug/panic` +thread 'main' panicked at 'crash and burn', src/main.rs:2:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/listings/ch09-error-handling/no-listing-01-panic/src/main.rs b/listings/ch09-error-handling/no-listing-01-panic/src/main.rs new file mode 100755 index 0000000..32a4c24 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-01-panic/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + panic!("crash and burn"); +} diff --git a/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.lock b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.toml b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/output.txt b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/output.txt new file mode 100755 index 0000000..aa95afa --- /dev/null +++ b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling error-handling v0.1.0 (file:///projects/error-handling) +error[E0308]: mismatched types + --> src/main.rs:4:18 + | +4 | let f: u32 = File::open("hello.txt"); + | --- ^^^^^^^^^^^^^^^^^^^^^^^ expected `u32`, found enum `Result` + | | + | expected due to this + | + = note: expected type `u32` + found enum `Result` + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `error-handling` due to previous error diff --git a/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/src/main.rs b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/src/main.rs new file mode 100755 index 0000000..a637f5f --- /dev/null +++ b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/src/main.rs @@ -0,0 +1,7 @@ +use std::fs::File; + +fn main() { + // ANCHOR: here + let f: u32 = File::open("hello.txt"); + // ANCHOR_END: here +} diff --git a/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.lock b/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.toml b/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs b/listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs new file mode 100755 index 0000000..7b6b13a --- /dev/null +++ b/listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs @@ -0,0 +1,5 @@ +use std::fs::File; + +fn main() { + let f = File::open("hello.txt").unwrap(); +} diff --git a/listings/ch09-error-handling/no-listing-05-expect/Cargo.lock b/listings/ch09-error-handling/no-listing-05-expect/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-05-expect/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-05-expect/Cargo.toml b/listings/ch09-error-handling/no-listing-05-expect/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-05-expect/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-05-expect/src/main.rs b/listings/ch09-error-handling/no-listing-05-expect/src/main.rs new file mode 100755 index 0000000..cab643b --- /dev/null +++ b/listings/ch09-error-handling/no-listing-05-expect/src/main.rs @@ -0,0 +1,5 @@ +use std::fs::File; + +fn main() { + let f = File::open("hello.txt").expect("Failed to open hello.txt"); +} diff --git a/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.lock b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.lock new file mode 100755 index 0000000..1fa96b7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.toml b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.toml new file mode 100755 index 0000000..c496db7 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "error-handling" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs new file mode 100755 index 0000000..e829724 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + use std::net::IpAddr; + + let home: IpAddr = "127.0.0.1".parse().unwrap(); + // ANCHOR_END: here +} diff --git a/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.lock b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.lock new file mode 100755 index 0000000..0a2f222 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.lock @@ -0,0 +1,83 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.toml b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.toml new file mode 100755 index 0000000..15b3fff --- /dev/null +++ b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs new file mode 100755 index 0000000..cbe8fbc --- /dev/null +++ b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs @@ -0,0 +1,47 @@ +use rand::Rng; +use std::cmp::Ordering; +use std::io; + +fn main() { + println!("Guess the number!"); + + let secret_number = rand::thread_rng().gen_range(1..101); + + // ANCHOR: here + loop { + // --snip-- + + // ANCHOR_END: here + println!("Please input your guess."); + + let mut guess = String::new(); + + io::stdin() + .read_line(&mut guess) + .expect("Failed to read line"); + + // ANCHOR: here + let guess: i32 = match guess.trim().parse() { + Ok(num) => num, + Err(_) => continue, + }; + + if guess < 1 || guess > 100 { + println!("The secret number will be between 1 and 100."); + continue; + } + + match guess.cmp(&secret_number) { + // --snip-- + // ANCHOR_END: here + Ordering::Less => println!("Too small!"), + Ordering::Greater => println!("Too big!"), + Ordering::Equal => { + println!("You win!"); + break; + } + } + // ANCHOR: here + } + // ANCHOR_END: here +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs new file mode 100755 index 0000000..d2ba23b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs @@ -0,0 +1,18 @@ +// ANCHOR: here +fn main() { + let number_list = vec![34, 50, 25, 100, 65]; + + let mut largest = number_list[0]; + + for number in number_list { + if number > largest { + largest = number; + } + } + + println!("The largest number is {}", largest); + // ANCHOR_END: here + assert_eq!(largest, 100); + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs new file mode 100755 index 0000000..9138dfc --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs @@ -0,0 +1,25 @@ +fn main() { + let number_list = vec![34, 50, 25, 100, 65]; + + let mut largest = number_list[0]; + + for number in number_list { + if number > largest { + largest = number; + } + } + + println!("The largest number is {}", largest); + + let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8]; + + let mut largest = number_list[0]; + + for number in number_list { + if number > largest { + largest = number; + } + } + + println!("The largest number is {}", largest); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs new file mode 100755 index 0000000..7704ff3 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs @@ -0,0 +1,31 @@ +// ANCHOR: here +fn largest(list: &[i32]) -> i32 { + let mut largest = list[0]; + + for &item in list { + if item > largest { + largest = item; + } + } + + largest +} + +fn main() { + let number_list = vec![34, 50, 25, 100, 65]; + + let result = largest(&number_list); + println!("The largest number is {}", result); + // ANCHOR_END: here + assert_eq!(result, 100); + // ANCHOR: here + + let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8]; + + let result = largest(&number_list); + println!("The largest number is {}", result); + // ANCHOR_END: here + assert_eq!(result, 6000); + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs new file mode 100755 index 0000000..6b483ec --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs @@ -0,0 +1,43 @@ +// ANCHOR: here +fn largest_i32(list: &[i32]) -> i32 { + let mut largest = list[0]; + + for &item in list { + if item > largest { + largest = item; + } + } + + largest +} + +fn largest_char(list: &[char]) -> char { + let mut largest = list[0]; + + for &item in list { + if item > largest { + largest = item; + } + } + + largest +} + +fn main() { + let number_list = vec![34, 50, 25, 100, 65]; + + let result = largest_i32(&number_list); + println!("The largest number is {}", result); + // ANCHOR_END: here + assert_eq!(result, 100); + // ANCHOR: here + + let char_list = vec!['y', 'm', 'a', 'q']; + + let result = largest_char(&char_list); + println!("The largest char is {}", result); + // ANCHOR_END: here + assert_eq!(result, 'y'); + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt new file mode 100755 index 0000000..0530f54 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt @@ -0,0 +1,17 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0369]: binary operation `>` cannot be applied to type `T` + --> src/main.rs:5:17 + | +5 | if item > largest { + | ---- ^ ------- T + | | + | T + | +help: consider restricting type parameter `T` + | +1 | fn largest(list: &[T]) -> T { + | ++++++++++++++++++++++ + +For more information about this error, try `rustc --explain E0369`. +error: could not compile `chapter10` due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs new file mode 100755 index 0000000..e731157 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs @@ -0,0 +1,23 @@ +fn largest(list: &[T]) -> T { + let mut largest = list[0]; + + for &item in list { + if item > largest { + largest = item; + } + } + + largest +} + +fn main() { + let number_list = vec![34, 50, 25, 100, 65]; + + let result = largest(&number_list); + println!("The largest number is {}", result); + + let char_list = vec!['y', 'm', 'a', 'q']; + + let result = largest(&char_list); + println!("The largest char is {}", result); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/src/main.rs new file mode 100755 index 0000000..4252593 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/src/main.rs @@ -0,0 +1,9 @@ +struct Point { + x: T, + y: T, +} + +fn main() { + let integer = Point { x: 5, y: 10 }; + let float = Point { x: 1.0, y: 4.0 }; +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt new file mode 100755 index 0000000..2482c38 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt @@ -0,0 +1,10 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0308]: mismatched types + --> src/main.rs:7:38 + | +7 | let wont_work = Point { x: 5, y: 4.0 }; + | ^^^ expected integer, found floating-point number + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `chapter10` due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs new file mode 100755 index 0000000..7883db1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs @@ -0,0 +1,8 @@ +struct Point { + x: T, + y: T, +} + +fn main() { + let wont_work = Point { x: 5, y: 4.0 }; +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs new file mode 100755 index 0000000..615b78c --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs @@ -0,0 +1,10 @@ +struct Point { + x: T, + y: U, +} + +fn main() { + let both_integer = Point { x: 5, y: 10 }; + let both_float = Point { x: 1.0, y: 4.0 }; + let integer_and_float = Point { x: 5, y: 4.0 }; +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/src/main.rs new file mode 100755 index 0000000..288b64e --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/src/main.rs @@ -0,0 +1,16 @@ +struct Point { + x: T, + y: T, +} + +impl Point { + fn x(&self) -> &T { + &self.x + } +} + +fn main() { + let p = Point { x: 5, y: 10 }; + + println!("p.x = {}", p.x()); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs new file mode 100755 index 0000000..4c5b01b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs @@ -0,0 +1,24 @@ +struct Point { + x: T, + y: T, +} + +impl Point { + fn x(&self) -> &T { + &self.x + } +} + +// ANCHOR: here +impl Point { + fn distance_from_origin(&self) -> f32 { + (self.x.powi(2) + self.y.powi(2)).sqrt() + } +} +// ANCHOR_END: here + +fn main() { + let p = Point { x: 5, y: 10 }; + + println!("p.x = {}", p.x()); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs new file mode 100755 index 0000000..86b0281 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs @@ -0,0 +1,22 @@ +struct Point { + x: X1, + y: Y1, +} + +impl Point { + fn mixup(self, other: Point) -> Point { + Point { + x: self.x, + y: other.y, + } + } +} + +fn main() { + let p1 = Point { x: 5, y: 10.4 }; + let p2 = Point { x: "Hello", y: 'c' }; + + let p3 = p1.mixup(p2); + + println!("p3.x = {}, p3.y = {}", p3.x, p3.y); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs new file mode 100755 index 0000000..cfaedb0 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs @@ -0,0 +1,3 @@ +pub trait Summary { + fn summarize(&self) -> String; +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs new file mode 100755 index 0000000..c4c8332 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs @@ -0,0 +1,31 @@ +pub trait Summary { + fn summarize(&self) -> String; +} + +// ANCHOR: here +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle { + fn summarize(&self) -> String { + format!("{}, by {} ({})", self.headline, self.author, self.location) + } +} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs new file mode 100755 index 0000000..fb59b84 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs @@ -0,0 +1,29 @@ +// ANCHOR: here +pub trait Summary { + fn summarize(&self) -> String { + String::from("(Read more...)") + } +} +// ANCHOR_END: here + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle {} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/main.rs new file mode 100755 index 0000000..7aa6a3b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/main.rs @@ -0,0 +1,23 @@ +fn largest(list: &[T]) -> T { + let mut largest = list[0]; + + for &item in list { + if item > largest { + largest = item; + } + } + + largest +} + +fn main() { + let number_list = vec![34, 50, 25, 100, 65]; + + let result = largest(&number_list); + println!("The largest number is {}", result); + + let char_list = vec!['y', 'm', 'a', 'q']; + + let result = largest(&char_list); + println!("The largest char is {}", result); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/lib.rs new file mode 100755 index 0000000..669cc5f --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/lib.rs @@ -0,0 +1,22 @@ +use std::fmt::Display; + +struct Pair { + x: T, + y: T, +} + +impl Pair { + fn new(x: T, y: T) -> Self { + Self { x, y } + } +} + +impl Pair { + fn cmp_display(&self) { + if self.x >= self.y { + println!("The largest member is x = {}", self.x); + } else { + println!("The largest member is y = {}", self.y); + } + } +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt new file mode 100755 index 0000000..8b239e4 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0597]: `x` does not live long enough + --> src/main.rs:7:17 + | +7 | r = &x; + | ^^ borrowed value does not live long enough +8 | } + | - `x` dropped here while still borrowed +9 | +10 | println!("r: {}", r); + | - borrow later used here + +For more information about this error, try `rustc --explain E0597`. +error: could not compile `chapter10` due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/src/main.rs new file mode 100755 index 0000000..16adb6a --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + // ANCHOR: here + { + let r; + + { + let x = 5; + r = &x; + } + + println!("r: {}", r); + } + // ANCHOR_END: here +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.lock new file mode 100755 index 0000000..6388bb2 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/rustfmt-ignore b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs new file mode 100755 index 0000000..65dbf37 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + // ANCHOR: here + { + let r; // ---------+-- 'a + // | + { // | + let x = 5; // -+-- 'b | + r = &x; // | | + } // -+ | + // | + println!("r: {}", r); // | + } // ---------+ + // ANCHOR_END: here +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.lock new file mode 100755 index 0000000..6388bb2 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/rustfmt-ignore b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/rustfmt-ignore new file mode 100755 index 0000000..9a53c71 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/rustfmt-ignore @@ -0,0 +1,3 @@ +We have some weird comments pointing out borrowing scopes that we don't want to change; +unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to +manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs new file mode 100755 index 0000000..94e70f0 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: here + { + let x = 5; // ----------+-- 'b + // | + let r = &x; // --+-- 'a | + // | | + println!("r: {}", r); // | | + // --+ | + } // ----------+ + // ANCHOR_END: here +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs new file mode 100755 index 0000000..0f076a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let string1 = String::from("abcd"); + let string2 = "xyz"; + + let result = longest(string1.as_str(), string2); + println!("The longest string is {}", result); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt new file mode 100755 index 0000000..534a984 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0106]: missing lifetime specifier + --> src/main.rs:9:33 + | +9 | fn longest(x: &str, y: &str) -> &str { + | ---- ---- ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: consider introducing a named lifetime parameter + | +9 | fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { + | ++++ ++ ++ ++ + +For more information about this error, try `rustc --explain E0106`. +error: could not compile `chapter10` due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs new file mode 100755 index 0000000..6af8c9f --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs @@ -0,0 +1,17 @@ +fn main() { + let string1 = String::from("abcd"); + let string2 = "xyz"; + + let result = longest(string1.as_str(), string2); + println!("The longest string is {}", result); +} + +// ANCHOR: here +fn longest(x: &str, y: &str) -> &str { + if x.len() > y.len() { + x + } else { + y + } +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs new file mode 100755 index 0000000..09c3a0d --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs @@ -0,0 +1,17 @@ +fn main() { + let string1 = String::from("abcd"); + let string2 = "xyz"; + + let result = longest(string1.as_str(), string2); + println!("The longest string is {}", result); +} + +// ANCHOR: here +fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { + if x.len() > y.len() { + x + } else { + y + } +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs new file mode 100755 index 0000000..836ec72 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs @@ -0,0 +1,19 @@ +// ANCHOR: here +fn main() { + let string1 = String::from("long string is long"); + + { + let string2 = String::from("xyz"); + let result = longest(string1.as_str(), string2.as_str()); + println!("The longest string is {}", result); + } +} +// ANCHOR_END: here + +fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { + if x.len() > y.len() { + x + } else { + y + } +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt new file mode 100755 index 0000000..7f31ce0 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0597]: `string2` does not live long enough + --> src/main.rs:6:44 + | +6 | result = longest(string1.as_str(), string2.as_str()); + | ^^^^^^^^^^^^^^^^ borrowed value does not live long enough +7 | } + | - `string2` dropped here while still borrowed +8 | println!("The longest string is {}", result); + | ------ borrow later used here + +For more information about this error, try `rustc --explain E0597`. +error: could not compile `chapter10` due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs new file mode 100755 index 0000000..2a6fa58 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs @@ -0,0 +1,19 @@ +// ANCHOR: here +fn main() { + let string1 = String::from("long string is long"); + let result; + { + let string2 = String::from("xyz"); + result = longest(string1.as_str(), string2.as_str()); + } + println!("The longest string is {}", result); +} +// ANCHOR_END: here + +fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { + if x.len() > y.len() { + x + } else { + y + } +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs new file mode 100755 index 0000000..2937b19 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs @@ -0,0 +1,11 @@ +struct ImportantExcerpt<'a> { + part: &'a str, +} + +fn main() { + let novel = String::from("Call me Ishmael. Some years ago..."); + let first_sentence = novel.split('.').next().expect("Could not find a '.'"); + let i = ImportantExcerpt { + part: first_sentence, + }; +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.lock new file mode 100755 index 0000000..2aa4918 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ownership" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.toml new file mode 100755 index 0000000..e884752 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "ownership" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/src/main.rs new file mode 100755 index 0000000..431a261 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/src/main.rs @@ -0,0 +1,29 @@ +// ANCHOR: here +fn first_word(s: &str) -> &str { + let bytes = s.as_bytes(); + + for (i, &item) in bytes.iter().enumerate() { + if item == b' ' { + return &s[0..i]; + } + } + + &s[..] +} +// ANCHOR_END: here + +fn main() { + let my_string = String::from("hello world"); + + // first_word works on slices of `String`s + let word = first_word(&my_string[..]); + + let my_string_literal = "hello world"; + + // first_word works on slices of string literals + let word = first_word(&my_string_literal[..]); + + // Because string literals *are* string slices already, + // this works too, without the slice syntax! + let word = first_word(my_string_literal); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/lib.rs new file mode 100755 index 0000000..fa644ca --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/lib.rs @@ -0,0 +1,29 @@ +pub trait Summary { + fn summarize(&self) -> String; +} + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle { + fn summarize(&self) -> String { + format!("{}, by {} ({})", self.headline, self.author, self.location) + } +} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs new file mode 100755 index 0000000..0b51121 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs @@ -0,0 +1,14 @@ +use aggregator::{Summary, Tweet}; + +fn main() { + let tweet = Tweet { + username: String::from("horse_ebooks"), + content: String::from( + "of course, as you probably already know, people", + ), + reply: false, + retweet: false, + }; + + println!("1 new tweet: {}", tweet.summarize()); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/lib.rs new file mode 100755 index 0000000..b6f93a6 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/lib.rs @@ -0,0 +1,27 @@ +pub trait Summary { + fn summarize(&self) -> String { + String::from("(Read more...)") + } +} + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle {} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs new file mode 100755 index 0000000..44c9c64 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs @@ -0,0 +1,17 @@ +use chapter10::{self, NewsArticle, Summary}; + +fn main() { + // ANCHOR: here + let article = NewsArticle { + headline: String::from("Penguins win the Stanley Cup Championship!"), + location: String::from("Pittsburgh, PA, USA"), + author: String::from("Iceburgh"), + content: String::from( + "The Pittsburgh Penguins once again are the best \ + hockey team in the NHL.", + ), + }; + + println!("New article available! {}", article.summarize()); + // ANCHOR_END: here +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs new file mode 100755 index 0000000..643906f --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs @@ -0,0 +1,24 @@ +// ANCHOR: here +pub trait Summary { + fn summarize_author(&self) -> String; + + fn summarize(&self) -> String { + format!("(Read more from {}...)", self.summarize_author()) + } +} +// ANCHOR_END: here + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +// ANCHOR: impl +impl Summary for Tweet { + fn summarize_author(&self) -> String { + format!("@{}", self.username) + } +} +// ANCHOR_END: impl diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs new file mode 100755 index 0000000..466dc4d --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs @@ -0,0 +1,16 @@ +use chapter10::{self, Summary, Tweet}; + +fn main() { + // ANCHOR: here + let tweet = Tweet { + username: String::from("horse_ebooks"), + content: String::from( + "of course, as you probably already know, people", + ), + reply: false, + retweet: false, + }; + + println!("1 new tweet: {}", tweet.summarize()); + // ANCHOR_END: here +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs new file mode 100755 index 0000000..2619943 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs @@ -0,0 +1,35 @@ +pub trait Summary { + fn summarize(&self) -> String; +} + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle { + fn summarize(&self) -> String { + format!("{}, by {} ({})", self.headline, self.author, self.location) + } +} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} + +// ANCHOR: here +pub fn notify(item: &impl Summary) { + println!("Breaking news! {}", item.summarize()); +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs new file mode 100755 index 0000000..a611fce --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs @@ -0,0 +1,42 @@ +pub trait Summary { + fn summarize(&self) -> String; +} + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle { + fn summarize(&self) -> String { + format!("{}, by {} ({})", self.headline, self.author, self.location) + } +} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} + +// ANCHOR: here +fn returns_summarizable() -> impl Summary { + Tweet { + username: String::from("horse_ebooks"), + content: String::from( + "of course, as you probably already know, people", + ), + reply: false, + retweet: false, + } +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.lock new file mode 100755 index 0000000..2835471 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aggregator" +version = "0.1.0" diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.toml new file mode 100755 index 0000000..46f46a7 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "aggregator" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs new file mode 100755 index 0000000..7cd81d4 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs @@ -0,0 +1,56 @@ +pub trait Summary { + fn summarize(&self) -> String; +} + +pub struct NewsArticle { + pub headline: String, + pub location: String, + pub author: String, + pub content: String, +} + +impl Summary for NewsArticle { + fn summarize(&self) -> String { + format!("{}, by {} ({})", self.headline, self.author, self.location) + } +} + +pub struct Tweet { + pub username: String, + pub content: String, + pub reply: bool, + pub retweet: bool, +} + +impl Summary for Tweet { + fn summarize(&self) -> String { + format!("{}: {}", self.username, self.content) + } +} + +// ANCHOR: here +fn returns_summarizable(switch: bool) -> impl Summary { + if switch { + NewsArticle { + headline: String::from( + "Penguins win the Stanley Cup Championship!", + ), + location: String::from("Pittsburgh, PA, USA"), + author: String::from("Iceburgh"), + content: String::from( + "The Pittsburgh Penguins once again are the best \ + hockey team in the NHL.", + ), + } + } else { + Tweet { + username: String::from("horse_ebooks"), + content: String::from( + "of course, as you probably already know, people", + ), + reply: false, + retweet: false, + } + } +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/output.txt new file mode 100755 index 0000000..eca02c2 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/output.txt @@ -0,0 +1,25 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0508]: cannot move out of type `[T]`, a non-copy slice + --> src/main.rs:2:23 + | +2 | let mut largest = list[0]; + | ^^^^^^^ + | | + | cannot move out of here + | move occurs because `list[_]` has type `T`, which does not implement the `Copy` trait + | help: consider borrowing here: `&list[0]` + +error[E0507]: cannot move out of a shared reference + --> src/main.rs:4:18 + | +4 | for &item in list { + | ----- ^^^^ + | || + | |data moved here + | |move occurs because `item` has type `T`, which does not implement the `Copy` trait + | help: consider removing the `&`: `item` + +Some errors have detailed explanations: E0507, E0508. +For more information about an error, try `rustc --explain E0507`. +error: could not compile `chapter10` due to 2 previous errors diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/src/main.rs new file mode 100755 index 0000000..525ce81 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/src/main.rs @@ -0,0 +1,25 @@ +// ANCHOR: here +fn largest(list: &[T]) -> T { + // ANCHOR_END: here + let mut largest = list[0]; + + for &item in list { + if item > largest { + largest = item; + } + } + + largest +} + +fn main() { + let number_list = vec![34, 50, 25, 100, 65]; + + let result = largest(&number_list); + println!("The largest number is {}", result); + + let char_list = vec!['y', 'm', 'a', 'q']; + + let result = largest(&char_list); + println!("The largest char is {}", result); +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs new file mode 100755 index 0000000..d144305 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + let string1 = String::from("abcd"); + let string2 = "efghijklmnopqrstuvwxyz"; + + let result = longest(string1.as_str(), string2); + println!("The longest string is {}", result); +} + +// ANCHOR: here +fn longest<'a>(x: &'a str, y: &str) -> &'a str { + x +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt new file mode 100755 index 0000000..0c628b6 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt @@ -0,0 +1,10 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0515]: cannot return reference to local variable `result` + --> src/main.rs:11:5 + | +11 | result.as_str() + | ^^^^^^^^^^^^^^^ returns a reference to data owned by the current function + +For more information about this error, try `rustc --explain E0515`. +error: could not compile `chapter10` due to previous error diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs new file mode 100755 index 0000000..aca4be0 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + let string1 = String::from("abcd"); + let string2 = "xyz"; + + let result = longest(string1.as_str(), string2); + println!("The longest string is {}", result); +} + +// ANCHOR: here +fn longest<'a>(x: &str, y: &str) -> &'a str { + let result = String::from("really long string"); + result.as_str() +} +// ANCHOR_END: here diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs new file mode 100755 index 0000000..32ad530 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs @@ -0,0 +1,28 @@ +struct ImportantExcerpt<'a> { + part: &'a str, +} + +// ANCHOR: 1st +impl<'a> ImportantExcerpt<'a> { + fn level(&self) -> i32 { + 3 + } +} +// ANCHOR_END: 1st + +// ANCHOR: 3rd +impl<'a> ImportantExcerpt<'a> { + fn announce_and_return_part(&self, announcement: &str) -> &str { + println!("Attention please: {}", announcement); + self.part + } +} +// ANCHOR_END: 3rd + +fn main() { + let novel = String::from("Call me Ishmael. Some years ago..."); + let first_sentence = novel.split('.').next().expect("Could not find a '.'"); + let i = ImportantExcerpt { + part: first_sentence, + }; +} diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.lock b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.lock new file mode 100755 index 0000000..e8007a1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "chapter10" +version = "0.1.0" + diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.toml new file mode 100755 index 0000000..489f809 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "chapter10" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs new file mode 100755 index 0000000..cfafa9a --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs @@ -0,0 +1,31 @@ +fn main() { + let string1 = String::from("abcd"); + let string2 = "xyz"; + + let result = longest_with_an_announcement( + string1.as_str(), + string2, + "Today is someone's birthday!", + ); + println!("The longest string is {}", result); +} + +// ANCHOR: here +use std::fmt::Display; + +fn longest_with_an_announcement<'a, T>( + x: &'a str, + y: &'a str, + ann: T, +) -> &'a str +where + T: Display, +{ + println!("Announcement! {}", ann); + if x.len() > y.len() { + x + } else { + y + } +} +// ANCHOR_END: here diff --git a/listings/ch11-writing-automated-tests/listing-11-01/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-01/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-01/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-01/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-01/output.txt b/listings/ch11-writing-automated-tests/listing-11-01/output.txt new file mode 100755 index 0000000..c07ffd2 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-01/output.txt @@ -0,0 +1,16 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.57s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 1 test +test tests::it_works ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs new file mode 100755 index 0000000..31e1bb2 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} diff --git a/listings/ch11-writing-automated-tests/listing-11-03/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-03/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-03/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-03/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-03/output.txt b/listings/ch11-writing-automated-tests/listing-11-03/output.txt new file mode 100755 index 0000000..9680e7c --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-03/output.txt @@ -0,0 +1,22 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.72s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 2 tests +test tests::another ... FAILED +test tests::exploration ... ok + +failures: + +---- tests::another stdout ---- +thread 'main' panicked at 'Make this test fail', src/lib.rs:10:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::another + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs new file mode 100755 index 0000000..a9ec008 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs @@ -0,0 +1,14 @@ +// ANCHOR: here +#[cfg(test)] +mod tests { + #[test] + fn exploration() { + assert_eq!(2 + 2, 4); + } + + #[test] + fn another() { + panic!("Make this test fail"); + } +} +// ANCHOR_END: here diff --git a/listings/ch11-writing-automated-tests/listing-11-05/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-05/Cargo.lock new file mode 100755 index 0000000..9dcd543 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangle" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-05/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-05/Cargo.toml new file mode 100755 index 0000000..2447c67 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangle" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs new file mode 100755 index 0000000..0f1bc4e --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs @@ -0,0 +1,13 @@ +// ANCHOR: here +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +impl Rectangle { + fn can_hold(&self, other: &Rectangle) -> bool { + self.width > other.width && self.height > other.height + } +} +// ANCHOR_END: here diff --git a/listings/ch11-writing-automated-tests/listing-11-06/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-06/Cargo.lock new file mode 100755 index 0000000..9dcd543 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangle" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-06/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-06/Cargo.toml new file mode 100755 index 0000000..2447c67 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangle" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-06/output.txt b/listings/ch11-writing-automated-tests/listing-11-06/output.txt new file mode 100755 index 0000000..820c75b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-06/output.txt @@ -0,0 +1,16 @@ +$ cargo test + Compiling rectangle v0.1.0 (file:///projects/rectangle) + Finished test [unoptimized + debuginfo] target(s) in 0.66s + Running unittests (target/debug/deps/rectangle-6584c4561e48942e) + +running 1 test +test tests::larger_can_hold_smaller ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests rectangle + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs new file mode 100755 index 0000000..6ad1512 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs @@ -0,0 +1,32 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +impl Rectangle { + fn can_hold(&self, other: &Rectangle) -> bool { + self.width > other.width && self.height > other.height + } +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn larger_can_hold_smaller() { + let larger = Rectangle { + width: 8, + height: 7, + }; + let smaller = Rectangle { + width: 5, + height: 1, + }; + + assert!(larger.can_hold(&smaller)); + } +} +// ANCHOR_END: here diff --git a/listings/ch11-writing-automated-tests/listing-11-07/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-07/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-07/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-07/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-07/output.txt b/listings/ch11-writing-automated-tests/listing-11-07/output.txt new file mode 100755 index 0000000..aa30cdb --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-07/output.txt @@ -0,0 +1,16 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.58s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 1 test +test tests::it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs new file mode 100755 index 0000000..3e5d66b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs @@ -0,0 +1,13 @@ +pub fn add_two(a: i32) -> i32 { + a + 2 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_adds_two() { + assert_eq!(4, add_two(2)); + } +} diff --git a/listings/ch11-writing-automated-tests/listing-11-08/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-08/Cargo.lock new file mode 100755 index 0000000..5802b7d --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "guessing_game" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-08/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-08/Cargo.toml new file mode 100755 index 0000000..4e348c8 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-08/output.txt b/listings/ch11-writing-automated-tests/listing-11-08/output.txt new file mode 100755 index 0000000..6c17acf --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-08/output.txt @@ -0,0 +1,16 @@ +$ cargo test + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) + Finished test [unoptimized + debuginfo] target(s) in 0.58s + Running unittests (target/debug/deps/guessing_game-57d70c3acb738f4d) + +running 1 test +test tests::greater_than_100 - should panic ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests guessing_game + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs new file mode 100755 index 0000000..9391be5 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs @@ -0,0 +1,24 @@ +pub struct Guess { + value: i32, +} + +impl Guess { + pub fn new(value: i32) -> Guess { + if value < 1 || value > 100 { + panic!("Guess value must be between 1 and 100, got {}.", value); + } + + Guess { value } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic] + fn greater_than_100() { + Guess::new(200); + } +} diff --git a/listings/ch11-writing-automated-tests/listing-11-09/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-09/Cargo.lock new file mode 100755 index 0000000..5802b7d --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "guessing_game" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-09/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-09/Cargo.toml new file mode 100755 index 0000000..4e348c8 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs new file mode 100755 index 0000000..475d4b9 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs @@ -0,0 +1,35 @@ +pub struct Guess { + value: i32, +} + +// ANCHOR: here +// --snip-- +impl Guess { + pub fn new(value: i32) -> Guess { + if value < 1 { + panic!( + "Guess value must be greater than or equal to 1, got {}.", + value + ); + } else if value > 100 { + panic!( + "Guess value must be less than or equal to 100, got {}.", + value + ); + } + + Guess { value } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic(expected = "Guess value must be less than or equal to 100")] + fn greater_than_100() { + Guess::new(200); + } +} +// ANCHOR_END: here diff --git a/listings/ch11-writing-automated-tests/listing-11-10/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-10/Cargo.lock new file mode 100755 index 0000000..a6d35e3 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "silly-function" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-10/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-10/Cargo.toml new file mode 100755 index 0000000..f751864 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "silly-function" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-10/output.txt b/listings/ch11-writing-automated-tests/listing-11-10/output.txt new file mode 100755 index 0000000..ce98316 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-10/output.txt @@ -0,0 +1,25 @@ +$ cargo test + Compiling silly-function v0.1.0 (file:///projects/silly-function) + Finished test [unoptimized + debuginfo] target(s) in 0.58s + Running unittests (target/debug/deps/silly_function-160869f38cff9166) + +running 2 tests +test tests::this_test_will_fail ... FAILED +test tests::this_test_will_pass ... ok + +failures: + +---- tests::this_test_will_fail stdout ---- +I got the value 8 +thread 'main' panicked at 'assertion failed: `(left == right)` + left: `5`, + right: `10`', src/lib.rs:19:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::this_test_will_fail + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs new file mode 100755 index 0000000..6fd76ce --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs @@ -0,0 +1,21 @@ +fn prints_and_returns_10(a: i32) -> i32 { + println!("I got the value {}", a); + 10 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn this_test_will_pass() { + let value = prints_and_returns_10(4); + assert_eq!(10, value); + } + + #[test] + fn this_test_will_fail() { + let value = prints_and_returns_10(8); + assert_eq!(5, value); + } +} diff --git a/listings/ch11-writing-automated-tests/listing-11-11/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-11/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-11/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-11/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-11/output.txt b/listings/ch11-writing-automated-tests/listing-11-11/output.txt new file mode 100755 index 0000000..9be5abe --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-11/output.txt @@ -0,0 +1,18 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.62s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 3 tests +test tests::add_three_and_two ... ok +test tests::add_two_and_two ... ok +test tests::one_hundred ... ok + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs new file mode 100755 index 0000000..f567152 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs @@ -0,0 +1,23 @@ +pub fn add_two(a: i32) -> i32 { + a + 2 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn add_two_and_two() { + assert_eq!(4, add_two(2)); + } + + #[test] + fn add_three_and_two() { + assert_eq!(5, add_two(3)); + } + + #[test] + fn one_hundred() { + assert_eq!(102, add_two(100)); + } +} diff --git a/listings/ch11-writing-automated-tests/listing-11-12/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-12/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-12/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-12/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs new file mode 100755 index 0000000..c3961b1 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs @@ -0,0 +1,17 @@ +pub fn add_two(a: i32) -> i32 { + internal_adder(a, 2) +} + +fn internal_adder(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn internal() { + assert_eq!(4, internal_adder(2, 2)); + } +} diff --git a/listings/ch11-writing-automated-tests/listing-11-13/Cargo.lock b/listings/ch11-writing-automated-tests/listing-11-13/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/listing-11-13/Cargo.toml b/listings/ch11-writing-automated-tests/listing-11-13/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/listing-11-13/output.txt b/listings/ch11-writing-automated-tests/listing-11-13/output.txt new file mode 100755 index 0000000..12e231c --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-13/output.txt @@ -0,0 +1,23 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 1.31s + Running unittests (target/debug/deps/adder-1082c4b063a8fbe6) + +running 1 test +test tests::internal ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/integration_test.rs (target/debug/deps/integration_test-1082c4b063a8fbe6) + +running 1 test +test it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs b/listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs new file mode 100755 index 0000000..c3961b1 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs @@ -0,0 +1,17 @@ +pub fn add_two(a: i32) -> i32 { + internal_adder(a, 2) +} + +fn internal_adder(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn internal() { + assert_eq!(4, internal_adder(2, 2)); + } +} 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 new file mode 100755 index 0000000..e26fa71 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs @@ -0,0 +1,6 @@ +use adder; + +#[test] +fn it_adds_two() { + assert_eq!(4, adder::add_two(2)); +} diff --git a/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt new file mode 100755 index 0000000..5de1386 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt @@ -0,0 +1,16 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.59s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 1 test +test tests::exploration ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs new file mode 100755 index 0000000..330bddf --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { + #[test] + fn exploration() { + assert_eq!(2 + 2, 4); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.lock new file mode 100755 index 0000000..9dcd543 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangle" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.toml new file mode 100755 index 0000000..2447c67 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangle" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt new file mode 100755 index 0000000..29320be --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt @@ -0,0 +1,17 @@ +$ cargo test + Compiling rectangle v0.1.0 (file:///projects/rectangle) + Finished test [unoptimized + debuginfo] target(s) in 0.66s + Running unittests (target/debug/deps/rectangle-6584c4561e48942e) + +running 2 tests +test tests::larger_can_hold_smaller ... ok +test tests::smaller_cannot_hold_larger ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests rectangle + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs new file mode 100755 index 0000000..ee4fc45 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs @@ -0,0 +1,49 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +impl Rectangle { + fn can_hold(&self, other: &Rectangle) -> bool { + self.width > other.width && self.height > other.height + } +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn larger_can_hold_smaller() { + // --snip-- + // ANCHOR_END: here + let larger = Rectangle { + width: 8, + height: 7, + }; + let smaller = Rectangle { + width: 5, + height: 1, + }; + + assert!(larger.can_hold(&smaller)); + // ANCHOR: here + } + + #[test] + fn smaller_cannot_hold_larger() { + let larger = Rectangle { + width: 8, + height: 7, + }; + let smaller = Rectangle { + width: 5, + height: 1, + }; + + assert!(!smaller.can_hold(&larger)); + } +} +// ANCHOR_END: here diff --git a/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.lock new file mode 100755 index 0000000..9dcd543 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "rectangle" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.toml new file mode 100755 index 0000000..2447c67 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rectangle" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt new file mode 100755 index 0000000..6629b53 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt @@ -0,0 +1,22 @@ +$ cargo test + Compiling rectangle v0.1.0 (file:///projects/rectangle) + Finished test [unoptimized + debuginfo] target(s) in 0.66s + Running unittests (target/debug/deps/rectangle-6584c4561e48942e) + +running 2 tests +test tests::larger_can_hold_smaller ... FAILED +test tests::smaller_cannot_hold_larger ... ok + +failures: + +---- tests::larger_can_hold_smaller stdout ---- +thread 'main' panicked at 'assertion failed: larger.can_hold(&smaller)', src/lib.rs:28:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::larger_can_hold_smaller + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs new file mode 100755 index 0000000..f5968fc --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs @@ -0,0 +1,47 @@ +#[derive(Debug)] +struct Rectangle { + width: u32, + height: u32, +} + +// ANCHOR: here +// --snip-- +impl Rectangle { + fn can_hold(&self, other: &Rectangle) -> bool { + self.width < other.width && self.height > other.height + } +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn larger_can_hold_smaller() { + let larger = Rectangle { + width: 8, + height: 7, + }; + let smaller = Rectangle { + width: 5, + height: 1, + }; + + assert!(larger.can_hold(&smaller)); + } + + #[test] + fn smaller_cannot_hold_larger() { + let larger = Rectangle { + width: 8, + height: 7, + }; + let smaller = Rectangle { + width: 5, + height: 1, + }; + + assert!(!smaller.can_hold(&larger)); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt new file mode 100755 index 0000000..2c0ffe8 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt @@ -0,0 +1,23 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.61s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 1 test +test tests::it_adds_two ... FAILED + +failures: + +---- tests::it_adds_two stdout ---- +thread 'main' panicked at 'assertion failed: `(left == right)` + left: `4`, + right: `5`', src/lib.rs:11:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::it_adds_two + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs new file mode 100755 index 0000000..f186625 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs @@ -0,0 +1,15 @@ +// ANCHOR: here +pub fn add_two(a: i32) -> i32 { + a + 3 +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_adds_two() { + assert_eq!(4, add_two(2)); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.lock new file mode 100755 index 0000000..9a7ecdd --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "greeter" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.toml new file mode 100755 index 0000000..90a826c --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "greeter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs new file mode 100755 index 0000000..3ba3d88 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs @@ -0,0 +1,14 @@ +pub fn greeting(name: &str) -> String { + format!("Hello {}!", name) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn greeting_contains_name() { + let result = greeting("Carol"); + assert!(result.contains("Carol")); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.lock new file mode 100755 index 0000000..9a7ecdd --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "greeter" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.toml new file mode 100755 index 0000000..90a826c --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "greeter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt new file mode 100755 index 0000000..d54451f --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt @@ -0,0 +1,21 @@ +$ cargo test + Compiling greeter v0.1.0 (file:///projects/greeter) + Finished test [unoptimized + debuginfo] target(s) in 0.91s + Running unittests (target/debug/deps/greeter-170b942eb5bf5e3a) + +running 1 test +test tests::greeting_contains_name ... FAILED + +failures: + +---- tests::greeting_contains_name stdout ---- +thread 'main' panicked at 'assertion failed: result.contains(\"Carol\")', src/lib.rs:12:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::greeting_contains_name + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs new file mode 100755 index 0000000..6f28fc5 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs @@ -0,0 +1,16 @@ +// ANCHOR: here +pub fn greeting(name: &str) -> String { + String::from("Hello!") +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn greeting_contains_name() { + let result = greeting("Carol"); + assert!(result.contains("Carol")); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.lock new file mode 100755 index 0000000..9a7ecdd --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "greeter" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.toml new file mode 100755 index 0000000..90a826c --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "greeter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt new file mode 100755 index 0000000..2ecf804 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt @@ -0,0 +1,21 @@ +$ cargo test + Compiling greeter v0.1.0 (file:///projects/greeter) + Finished test [unoptimized + debuginfo] target(s) in 0.93s + Running unittests (target/debug/deps/greeter-170b942eb5bf5e3a) + +running 1 test +test tests::greeting_contains_name ... FAILED + +failures: + +---- tests::greeting_contains_name stdout ---- +thread 'main' panicked at 'Greeting did not contain name, value was `Hello!`', src/lib.rs:12:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::greeting_contains_name + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs new file mode 100755 index 0000000..519c7a4 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs @@ -0,0 +1,20 @@ +pub fn greeting(name: &str) -> String { + String::from("Hello!") +} + +#[cfg(test)] +mod tests { + use super::*; + + // ANCHOR: here + #[test] + fn greeting_contains_name() { + let result = greeting("Carol"); + assert!( + result.contains("Carol"), + "Greeting did not contain name, value was `{}`", + result + ); + } + // ANCHOR_END: here +} diff --git a/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.lock new file mode 100755 index 0000000..5802b7d --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "guessing_game" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.toml new file mode 100755 index 0000000..4e348c8 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt new file mode 100755 index 0000000..9d64476 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt @@ -0,0 +1,19 @@ +$ cargo test + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) + Finished test [unoptimized + debuginfo] target(s) in 0.62s + Running unittests (target/debug/deps/guessing_game-57d70c3acb738f4d) + +running 1 test +test tests::greater_than_100 - should panic ... FAILED + +failures: + +---- tests::greater_than_100 stdout ---- +note: test did not panic as expected + +failures: + tests::greater_than_100 + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs new file mode 100755 index 0000000..32540ba --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs @@ -0,0 +1,27 @@ +pub struct Guess { + value: i32, +} + +// ANCHOR: here +// --snip-- +impl Guess { + pub fn new(value: i32) -> Guess { + if value < 1 { + panic!("Guess value must be between 1 and 100, got {}.", value); + } + + Guess { value } + } +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic] + fn greater_than_100() { + Guess::new(200); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.lock new file mode 100755 index 0000000..5802b7d --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "guessing_game" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.toml new file mode 100755 index 0000000..4e348c8 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "guessing_game" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt new file mode 100755 index 0000000..ca13feb --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt @@ -0,0 +1,23 @@ +$ cargo test + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) + Finished test [unoptimized + debuginfo] target(s) in 0.66s + Running unittests (target/debug/deps/guessing_game-57d70c3acb738f4d) + +running 1 test +test tests::greater_than_100 - should panic ... FAILED + +failures: + +---- tests::greater_than_100 stdout ---- +thread 'main' panicked at 'Guess value must be greater than or equal to 1, got 200.', src/lib.rs:13:13 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +note: panic did not contain expected string + panic message: `"Guess value must be greater than or equal to 1, got 200."`, + expected substring: `"Guess value must be less than or equal to 100"` + +failures: + tests::greater_than_100 + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs new file mode 100755 index 0000000..2165004 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs @@ -0,0 +1,34 @@ +pub struct Guess { + value: i32, +} + +impl Guess { + pub fn new(value: i32) -> Guess { + // ANCHOR: here + if value < 1 { + panic!( + "Guess value must be less than or equal to 100, got {}.", + value + ); + } else if value > 100 { + panic!( + "Guess value must be greater than or equal to 1, got {}.", + value + ); + } + // ANCHOR_END: here + + Guess { value } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic(expected = "Guess value must be less than or equal to 100")] + fn greater_than_100() { + Guess::new(200); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs new file mode 100755 index 0000000..6284f4f --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs @@ -0,0 +1,11 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() -> Result<(), String> { + if 2 + 2 == 4 { + Ok(()) + } else { + Err(String::from("two plus two does not equal four")) + } + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt new file mode 100755 index 0000000..fcdff25 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt @@ -0,0 +1,17 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.60s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 2 tests +test expensive_test ... ignored +test it_works ... ok + +test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs new file mode 100755 index 0000000..d54a609 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs @@ -0,0 +1,10 @@ +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} + +#[test] +#[ignore] +fn expensive_test() { + // code that takes an hour to run +} diff --git a/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt new file mode 100755 index 0000000..0afdb52 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt @@ -0,0 +1,29 @@ +$ cargo test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.89s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 1 test +test tests::internal ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/common.rs (target/debug/deps/common-92948b65e88960b4) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/integration_test.rs (target/debug/deps/integration_test-92948b65e88960b4) + +running 1 test +test it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs new file mode 100755 index 0000000..c3961b1 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs @@ -0,0 +1,17 @@ +pub fn add_two(a: i32) -> i32 { + internal_adder(a, 2) +} + +fn internal_adder(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn internal() { + assert_eq!(4, internal_adder(2, 2)); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/common.rs b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/common.rs new file mode 100755 index 0000000..5fb7a39 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/common.rs @@ -0,0 +1,3 @@ +pub fn setup() { + // setup code specific to your library's tests would go here +} diff --git a/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs new file mode 100755 index 0000000..e26fa71 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs @@ -0,0 +1,6 @@ +use adder; + +#[test] +fn it_adds_two() { + assert_eq!(4, adder::add_two(2)); +} diff --git a/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.lock b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.toml b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs new file mode 100755 index 0000000..c3961b1 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs @@ -0,0 +1,17 @@ +pub fn add_two(a: i32) -> i32 { + internal_adder(a, 2) +} + +fn internal_adder(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn internal() { + assert_eq!(4, internal_adder(2, 2)); + } +} diff --git a/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/common/mod.rs b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/common/mod.rs new file mode 100755 index 0000000..5fb7a39 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/common/mod.rs @@ -0,0 +1,3 @@ +pub fn setup() { + // setup code specific to your library's tests would go here +} diff --git a/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs new file mode 100755 index 0000000..58b8b7b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs @@ -0,0 +1,9 @@ +use adder; + +mod common; + +#[test] +fn it_adds_two() { + common::setup(); + assert_eq!(4, adder::add_two(2)); +} diff --git a/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.lock b/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.lock new file mode 100755 index 0000000..a6d35e3 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "silly-function" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.toml b/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.toml new file mode 100755 index 0000000..f751864 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "silly-function" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt b/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt new file mode 100755 index 0000000..94b0b4b --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt @@ -0,0 +1,34 @@ +$ cargo test -- --show-output + Compiling silly-function v0.1.0 (file:///projects/silly-function) + Finished test [unoptimized + debuginfo] target(s) in 0.60s + Running unittests (target/debug/deps/silly_function-160869f38cff9166) + +running 2 tests +test tests::this_test_will_fail ... FAILED +test tests::this_test_will_pass ... ok + +successes: + +---- tests::this_test_will_pass stdout ---- +I got the value 4 + + +successes: + tests::this_test_will_pass + +failures: + +---- tests::this_test_will_fail stdout ---- +I got the value 8 +thread 'main' panicked at 'assertion failed: `(left == right)` + left: `5`, + right: `10`', src/lib.rs:19:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::this_test_will_fail + +test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch11-writing-automated-tests/output-only-01-show-output/src/lib.rs b/listings/ch11-writing-automated-tests/output-only-01-show-output/src/lib.rs new file mode 100755 index 0000000..43c4c92 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-01-show-output/src/lib.rs @@ -0,0 +1,21 @@ +pub fn prints_and_returns_10(a: i32) -> i32 { + println!("I got the value {}", a); + 10 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn this_test_will_pass() { + let value = prints_and_returns_10(4); + assert_eq!(10, value); + } + + #[test] + fn this_test_will_fail() { + let value = prints_and_returns_10(8); + assert_eq!(5, value); + } +} diff --git a/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.lock b/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.toml b/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt b/listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt new file mode 100755 index 0000000..e5e9ffd --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt @@ -0,0 +1,10 @@ +$ cargo test one_hundred + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.69s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 1 test +test tests::one_hundred ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/output-only-02-single-test/src/lib.rs b/listings/ch11-writing-automated-tests/output-only-02-single-test/src/lib.rs new file mode 100755 index 0000000..f567152 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-02-single-test/src/lib.rs @@ -0,0 +1,23 @@ +pub fn add_two(a: i32) -> i32 { + a + 2 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn add_two_and_two() { + assert_eq!(4, add_two(2)); + } + + #[test] + fn add_three_and_two() { + assert_eq!(5, add_two(3)); + } + + #[test] + fn one_hundred() { + assert_eq!(102, add_two(100)); + } +} diff --git a/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.lock b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.toml b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt new file mode 100755 index 0000000..822cbb5 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt @@ -0,0 +1,11 @@ +$ cargo test add + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.61s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 2 tests +test tests::add_three_and_two ... ok +test tests::add_two_and_two ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/src/lib.rs b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/src/lib.rs new file mode 100755 index 0000000..f567152 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/src/lib.rs @@ -0,0 +1,23 @@ +pub fn add_two(a: i32) -> i32 { + a + 2 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn add_two_and_two() { + assert_eq!(4, add_two(2)); + } + + #[test] + fn add_three_and_two() { + assert_eq!(5, add_two(3)); + } + + #[test] + fn one_hundred() { + assert_eq!(102, add_two(100)); + } +} diff --git a/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.lock b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.toml b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt new file mode 100755 index 0000000..009ac4a --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt @@ -0,0 +1,16 @@ +$ cargo test -- --ignored + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.61s + Running unittests (target/debug/deps/adder-92948b65e88960b4) + +running 1 test +test expensive_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs new file mode 100755 index 0000000..2290c69 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs @@ -0,0 +1,12 @@ +// ANCHOR: here +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} + +#[test] +#[ignore] +fn expensive_test() { + // code that takes an hour to run +} +// ANCHOR_END: here diff --git a/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.lock b/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.toml b/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt b/listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt new file mode 100755 index 0000000..260beaa --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt @@ -0,0 +1,10 @@ +$ cargo test --test integration_test + Compiling adder v0.1.0 (file:///projects/adder) + Finished test [unoptimized + debuginfo] target(s) in 0.64s + Running tests/integration_test.rs (target/debug/deps/integration_test-82e7799c1bc62298) + +running 1 test +test it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs b/listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs new file mode 100755 index 0000000..c3961b1 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs @@ -0,0 +1,17 @@ +pub fn add_two(a: i32) -> i32 { + internal_adder(a, 2) +} + +fn internal_adder(a: i32, b: i32) -> i32 { + a + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn internal() { + assert_eq!(4, internal_adder(2, 2)); + } +} diff --git a/listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs b/listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs new file mode 100755 index 0000000..e26fa71 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs @@ -0,0 +1,6 @@ +use adder; + +#[test] +fn it_adds_two() { + assert_eq!(4, adder::add_two(2)); +} diff --git a/listings/ch12-an-io-project/listing-12-01/Cargo.lock b/listings/ch12-an-io-project/listing-12-01/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-01/Cargo.toml b/listings/ch12-an-io-project/listing-12-01/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-01/output.txt b/listings/ch12-an-io-project/listing-12-01/output.txt new file mode 100755 index 0000000..d0ef998 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-01/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.61s + Running `target/debug/minigrep` +["target/debug/minigrep"] diff --git a/listings/ch12-an-io-project/listing-12-01/src/main.rs b/listings/ch12-an-io-project/listing-12-01/src/main.rs new file mode 100755 index 0000000..aa3056d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-01/src/main.rs @@ -0,0 +1,6 @@ +use std::env; + +fn main() { + let args: Vec = env::args().collect(); + println!("{:?}", args); +} diff --git a/listings/ch12-an-io-project/listing-12-02/Cargo.lock b/listings/ch12-an-io-project/listing-12-02/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-02/Cargo.toml b/listings/ch12-an-io-project/listing-12-02/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-02/output.txt b/listings/ch12-an-io-project/listing-12-02/output.txt new file mode 100755 index 0000000..f759eea --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-02/output.txt @@ -0,0 +1,6 @@ +$ cargo run test sample.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.0s + Running `target/debug/minigrep test sample.txt` +Searching for test +In file sample.txt diff --git a/listings/ch12-an-io-project/listing-12-02/src/main.rs b/listings/ch12-an-io-project/listing-12-02/src/main.rs new file mode 100755 index 0000000..8daf125 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-02/src/main.rs @@ -0,0 +1,11 @@ +use std::env; + +fn main() { + let args: Vec = env::args().collect(); + + let query = &args[1]; + let filename = &args[2]; + + println!("Searching for {}", query); + println!("In file {}", filename); +} diff --git a/listings/ch12-an-io-project/listing-12-03/Cargo.lock b/listings/ch12-an-io-project/listing-12-03/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-03/Cargo.toml b/listings/ch12-an-io-project/listing-12-03/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-03/poem.txt b/listings/ch12-an-io-project/listing-12-03/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-03/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-03/src/main.rs b/listings/ch12-an-io-project/listing-12-03/src/main.rs new file mode 100755 index 0000000..8daf125 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-03/src/main.rs @@ -0,0 +1,11 @@ +use std::env; + +fn main() { + let args: Vec = env::args().collect(); + + let query = &args[1]; + let filename = &args[2]; + + println!("Searching for {}", query); + println!("In file {}", filename); +} diff --git a/listings/ch12-an-io-project/listing-12-04/Cargo.lock b/listings/ch12-an-io-project/listing-12-04/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-04/Cargo.toml b/listings/ch12-an-io-project/listing-12-04/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-04/output.txt b/listings/ch12-an-io-project/listing-12-04/output.txt new file mode 100755 index 0000000..5f31c8c --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-04/output.txt @@ -0,0 +1,17 @@ +$ cargo run the poem.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.0s + Running `target/debug/minigrep the poem.txt` +Searching for the +In file poem.txt +With text: +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! + diff --git a/listings/ch12-an-io-project/listing-12-04/poem.txt b/listings/ch12-an-io-project/listing-12-04/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-04/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-04/src/main.rs b/listings/ch12-an-io-project/listing-12-04/src/main.rs new file mode 100755 index 0000000..9a0eade --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-04/src/main.rs @@ -0,0 +1,22 @@ +// ANCHOR: here +use std::env; +use std::fs; + +fn main() { + // --snip-- + // ANCHOR_END: here + let args: Vec = env::args().collect(); + + let query = &args[1]; + let filename = &args[2]; + + println!("Searching for {}", query); + // ANCHOR: here + println!("In file {}", filename); + + let contents = fs::read_to_string(filename) + .expect("Something went wrong reading the file"); + + println!("With text:\n{}", contents); +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-05/Cargo.lock b/listings/ch12-an-io-project/listing-12-05/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-05/Cargo.toml b/listings/ch12-an-io-project/listing-12-05/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-05/poem.txt b/listings/ch12-an-io-project/listing-12-05/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-05/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-05/src/main.rs b/listings/ch12-an-io-project/listing-12-05/src/main.rs new file mode 100755 index 0000000..fb88056 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-05/src/main.rs @@ -0,0 +1,29 @@ +use std::env; +use std::fs; + +// ANCHOR: here +fn main() { + let args: Vec = env::args().collect(); + + let (query, filename) = parse_config(&args); + + // --snip-- + // ANCHOR_END: here + + println!("Searching for {}", query); + println!("In file {}", filename); + + let contents = fs::read_to_string(filename) + .expect("Something went wrong reading the file"); + + println!("With text:\n{}", contents); + // ANCHOR: here +} + +fn parse_config(args: &[String]) -> (&str, &str) { + let query = &args[1]; + let filename = &args[2]; + + (query, filename) +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-06/Cargo.lock b/listings/ch12-an-io-project/listing-12-06/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-06/Cargo.toml b/listings/ch12-an-io-project/listing-12-06/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-06/poem.txt b/listings/ch12-an-io-project/listing-12-06/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-06/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-06/src/main.rs b/listings/ch12-an-io-project/listing-12-06/src/main.rs new file mode 100755 index 0000000..b5d89bc --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-06/src/main.rs @@ -0,0 +1,34 @@ +use std::env; +use std::fs; + +// ANCHOR: here +fn main() { + let args: Vec = env::args().collect(); + + let config = parse_config(&args); + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + let contents = fs::read_to_string(config.filename) + .expect("Something went wrong reading the file"); + + // --snip-- + // ANCHOR_END: here + + println!("With text:\n{}", contents); + // ANCHOR: here +} + +struct Config { + query: String, + filename: String, +} + +fn parse_config(args: &[String]) -> Config { + let query = args[1].clone(); + let filename = args[2].clone(); + + Config { query, filename } +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-07/Cargo.lock b/listings/ch12-an-io-project/listing-12-07/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-07/Cargo.toml b/listings/ch12-an-io-project/listing-12-07/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-07/output.txt b/listings/ch12-an-io-project/listing-12-07/output.txt new file mode 100755 index 0000000..d3fa777 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-07/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.0s + Running `target/debug/minigrep` +thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', src/main.rs:27:21 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/listings/ch12-an-io-project/listing-12-07/poem.txt b/listings/ch12-an-io-project/listing-12-07/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-07/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-07/src/main.rs b/listings/ch12-an-io-project/listing-12-07/src/main.rs new file mode 100755 index 0000000..36d35ce --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-07/src/main.rs @@ -0,0 +1,40 @@ +use std::env; +use std::fs; + +// ANCHOR: here +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args); + // ANCHOR_END: here + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + let contents = fs::read_to_string(config.filename) + .expect("Something went wrong reading the file"); + + println!("With text:\n{}", contents); + // ANCHOR: here + + // --snip-- +} + +// --snip-- + +// ANCHOR_END: here +struct Config { + query: String, + filename: String, +} + +// ANCHOR: here +impl Config { + fn new(args: &[String]) -> Config { + let query = args[1].clone(); + let filename = args[2].clone(); + + Config { query, filename } + } +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-08/Cargo.lock b/listings/ch12-an-io-project/listing-12-08/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-08/Cargo.toml b/listings/ch12-an-io-project/listing-12-08/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-08/output.txt b/listings/ch12-an-io-project/listing-12-08/output.txt new file mode 100755 index 0000000..de2abd1 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-08/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.0s + Running `target/debug/minigrep` +thread 'main' panicked at 'not enough arguments', src/main.rs:26:13 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/listings/ch12-an-io-project/listing-12-08/poem.txt b/listings/ch12-an-io-project/listing-12-08/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-08/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-08/src/main.rs b/listings/ch12-an-io-project/listing-12-08/src/main.rs new file mode 100755 index 0000000..dddf10b --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-08/src/main.rs @@ -0,0 +1,38 @@ +use std::env; +use std::fs; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args); + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + let contents = fs::read_to_string(config.filename) + .expect("Something went wrong reading the file"); + + println!("With text:\n{}", contents); +} + +struct Config { + query: String, + filename: String, +} + +impl Config { + // ANCHOR: here + // --snip-- + fn new(args: &[String]) -> Config { + if args.len() < 3 { + panic!("not enough arguments"); + } + // --snip-- + // ANCHOR_END: here + + let query = args[1].clone(); + let filename = args[2].clone(); + + Config { query, filename } + } +} diff --git a/listings/ch12-an-io-project/listing-12-09/Cargo.lock b/listings/ch12-an-io-project/listing-12-09/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-09/Cargo.toml b/listings/ch12-an-io-project/listing-12-09/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-09/poem.txt b/listings/ch12-an-io-project/listing-12-09/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-09/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-09/src/main.rs b/listings/ch12-an-io-project/listing-12-09/src/main.rs new file mode 100755 index 0000000..83f46ee --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-09/src/main.rs @@ -0,0 +1,36 @@ +use std::env; +use std::fs; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args); + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + let contents = fs::read_to_string(config.filename) + .expect("Something went wrong reading the file"); + + println!("With text:\n{}", contents); +} + +struct Config { + query: String, + filename: String, +} + +// ANCHOR: here +impl Config { + fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-10/Cargo.lock b/listings/ch12-an-io-project/listing-12-10/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-10/Cargo.toml b/listings/ch12-an-io-project/listing-12-10/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-10/output.txt b/listings/ch12-an-io-project/listing-12-10/output.txt new file mode 100755 index 0000000..7aad57f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-10/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.48s + Running `target/debug/minigrep` +Problem parsing arguments: not enough arguments diff --git a/listings/ch12-an-io-project/listing-12-10/poem.txt b/listings/ch12-an-io-project/listing-12-10/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-10/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-10/src/main.rs b/listings/ch12-an-io-project/listing-12-10/src/main.rs new file mode 100755 index 0000000..c8aeb1d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-10/src/main.rs @@ -0,0 +1,42 @@ +use std::env; +use std::fs; +// ANCHOR: here +use std::process; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + // --snip-- + // ANCHOR_END: here + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + let contents = fs::read_to_string(config.filename) + .expect("Something went wrong reading the file"); + + println!("With text:\n{}", contents); +} + +struct Config { + query: String, + filename: String, +} + +impl Config { + fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} diff --git a/listings/ch12-an-io-project/listing-12-11/Cargo.lock b/listings/ch12-an-io-project/listing-12-11/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-11/Cargo.toml b/listings/ch12-an-io-project/listing-12-11/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-11/poem.txt b/listings/ch12-an-io-project/listing-12-11/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-11/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-11/src/main.rs b/listings/ch12-an-io-project/listing-12-11/src/main.rs new file mode 100755 index 0000000..974b503 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-11/src/main.rs @@ -0,0 +1,50 @@ +use std::env; +use std::fs; +use std::process; + +// ANCHOR: here +fn main() { + // --snip-- + + // ANCHOR_END: here + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + // ANCHOR: here + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + run(config); +} + +fn run(config: Config) { + let contents = fs::read_to_string(config.filename) + .expect("Something went wrong reading the file"); + + println!("With text:\n{}", contents); +} + +// --snip-- +// ANCHOR_END: here + +struct Config { + query: String, + filename: String, +} + +impl Config { + fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} diff --git a/listings/ch12-an-io-project/listing-12-12/Cargo.lock b/listings/ch12-an-io-project/listing-12-12/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-12/Cargo.toml b/listings/ch12-an-io-project/listing-12-12/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-12/output.txt b/listings/ch12-an-io-project/listing-12-12/output.txt new file mode 100755 index 0000000..c189025 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/output.txt @@ -0,0 +1,27 @@ +$ cargo run the poem.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) +warning: unused `Result` that must be used + --> src/main.rs:19:5 + | +19 | run(config); + | ^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: this `Result` may be an `Err` variant, which should be handled + +warning: `minigrep` (bin "minigrep") generated 1 warning + Finished dev [unoptimized + debuginfo] target(s) in 0.71s + Running `target/debug/minigrep the poem.txt` +Searching for the +In file poem.txt +With text: +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! + diff --git a/listings/ch12-an-io-project/listing-12-12/poem.txt b/listings/ch12-an-io-project/listing-12-12/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-12/src/main.rs b/listings/ch12-an-io-project/listing-12-12/src/main.rs new file mode 100755 index 0000000..f2e0e6b --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/src/main.rs @@ -0,0 +1,51 @@ +use std::env; +use std::fs; +use std::process; +// ANCHOR: here +use std::error::Error; + +// --snip-- + +// ANCHOR_END: here + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + run(config); +} + +// ANCHOR: here +fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + println!("With text:\n{}", contents); + + Ok(()) +} +// ANCHOR_END: here + +struct Config { + query: String, + filename: String, +} + +impl Config { + fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} diff --git a/listings/ch12-an-io-project/listing-12-13/Cargo.lock b/listings/ch12-an-io-project/listing-12-13/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-13/Cargo.toml b/listings/ch12-an-io-project/listing-12-13/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-13/poem.txt b/listings/ch12-an-io-project/listing-12-13/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-13/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-13/src/lib.rs b/listings/ch12-an-io-project/listing-12-13/src/lib.rs new file mode 100755 index 0000000..5b2850a --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-13/src/lib.rs @@ -0,0 +1,36 @@ +// ANCHOR: here +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + // --snip-- + // ANCHOR_END: here + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + // ANCHOR: here + } +} + +pub fn run(config: Config) -> Result<(), Box> { + // --snip-- + // ANCHOR_END: here + let contents = fs::read_to_string(config.filename)?; + + println!("With text:\n{}", contents); + + Ok(()) + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-13/src/main.rs b/listings/ch12-an-io-project/listing-12-13/src/main.rs new file mode 100755 index 0000000..b2447dc --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-13/src/main.rs @@ -0,0 +1,20 @@ +use std::env; +use std::process; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + if let Err(e) = run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-14/Cargo.lock b/listings/ch12-an-io-project/listing-12-14/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-14/Cargo.toml b/listings/ch12-an-io-project/listing-12-14/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-14/poem.txt b/listings/ch12-an-io-project/listing-12-14/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-14/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-14/src/lib.rs b/listings/ch12-an-io-project/listing-12-14/src/lib.rs new file mode 100755 index 0000000..2ba2fd1 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-14/src/lib.rs @@ -0,0 +1,28 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + println!("With text:\n{}", contents); + + Ok(()) +} diff --git a/listings/ch12-an-io-project/listing-12-14/src/main.rs b/listings/ch12-an-io-project/listing-12-14/src/main.rs new file mode 100755 index 0000000..5eb4024 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-14/src/main.rs @@ -0,0 +1,30 @@ +// ANCHOR: here +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + // --snip-- + // ANCHOR_END: here + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + // ANCHOR: here + if let Err(e) = minigrep::run(config) { + // --snip-- + // ANCHOR_END: here + println!("Application error: {}", e); + + process::exit(1); + // ANCHOR: here + } +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-15/Cargo.lock b/listings/ch12-an-io-project/listing-12-15/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-15/Cargo.toml b/listings/ch12-an-io-project/listing-12-15/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-15/poem.txt b/listings/ch12-an-io-project/listing-12-15/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-15/src/lib.rs b/listings/ch12-an-io-project/listing-12-15/src/lib.rs new file mode 100755 index 0000000..c677188 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/src/lib.rs @@ -0,0 +1,44 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + Ok(()) +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-15/src/main.rs b/listings/ch12-an-io-project/listing-12-15/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-16/Cargo.lock b/listings/ch12-an-io-project/listing-12-16/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-16/Cargo.toml b/listings/ch12-an-io-project/listing-12-16/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-16/output.txt b/listings/ch12-an-io-project/listing-12-16/output.txt new file mode 100755 index 0000000..63ea400 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/output.txt @@ -0,0 +1,23 @@ +$ cargo test + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished test [unoptimized + debuginfo] target(s) in 0.97s + Running unittests (target/debug/deps/minigrep-9cd200e5fac0fc94) + +running 1 test +test tests::one_result ... FAILED + +failures: + +---- tests::one_result stdout ---- +thread 'main' panicked at 'assertion failed: `(left == right)` + left: `["safe, fast, productive."]`, + right: `[]`', src/lib.rs:44:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::one_result + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch12-an-io-project/listing-12-16/poem.txt b/listings/ch12-an-io-project/listing-12-16/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-16/src/lib.rs b/listings/ch12-an-io-project/listing-12-16/src/lib.rs new file mode 100755 index 0000000..8729c32 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/src/lib.rs @@ -0,0 +1,48 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + Ok(()) +} + +// ANCHOR: here +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + vec![] +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/listing-12-16/src/main.rs b/listings/ch12-an-io-project/listing-12-16/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-17/Cargo.lock b/listings/ch12-an-io-project/listing-12-17/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-17/Cargo.toml b/listings/ch12-an-io-project/listing-12-17/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-17/poem.txt b/listings/ch12-an-io-project/listing-12-17/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-17/src/lib.rs b/listings/ch12-an-io-project/listing-12-17/src/lib.rs new file mode 100755 index 0000000..0b094ce --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/src/lib.rs @@ -0,0 +1,50 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + Ok(()) +} + +// ANCHOR: here +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + for line in contents.lines() { + // do something with line + } +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/listing-12-17/src/main.rs b/listings/ch12-an-io-project/listing-12-17/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-18/Cargo.lock b/listings/ch12-an-io-project/listing-12-18/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-18/Cargo.toml b/listings/ch12-an-io-project/listing-12-18/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-18/poem.txt b/listings/ch12-an-io-project/listing-12-18/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-18/src/lib.rs b/listings/ch12-an-io-project/listing-12-18/src/lib.rs new file mode 100755 index 0000000..c9d1f52 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/src/lib.rs @@ -0,0 +1,52 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + Ok(()) +} + +// ANCHOR: here +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + for line in contents.lines() { + if line.contains(query) { + // do something with line + } + } +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/listing-12-18/src/main.rs b/listings/ch12-an-io-project/listing-12-18/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-19/Cargo.lock b/listings/ch12-an-io-project/listing-12-19/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-19/Cargo.toml b/listings/ch12-an-io-project/listing-12-19/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-19/output.txt b/listings/ch12-an-io-project/listing-12-19/output.txt new file mode 100755 index 0000000..176d1b9 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/output.txt @@ -0,0 +1,22 @@ +$ cargo test + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished test [unoptimized + debuginfo] target(s) in 1.22s + Running unittests (target/debug/deps/minigrep-9cd200e5fac0fc94) + +running 1 test +test tests::one_result ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests (target/debug/deps/minigrep-9cd200e5fac0fc94) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests minigrep + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch12-an-io-project/listing-12-19/poem.txt b/listings/ch12-an-io-project/listing-12-19/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-19/src/lib.rs b/listings/ch12-an-io-project/listing-12-19/src/lib.rs new file mode 100755 index 0000000..de8897b --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/src/lib.rs @@ -0,0 +1,58 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + Ok(()) +} + +// ANCHOR: here +// ANCHOR: ch13 +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} +// ANCHOR_END: ch13 +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/listing-12-19/src/main.rs b/listings/ch12-an-io-project/listing-12-19/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-20/Cargo.lock b/listings/ch12-an-io-project/listing-12-20/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-20/Cargo.toml b/listings/ch12-an-io-project/listing-12-20/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-20/poem.txt b/listings/ch12-an-io-project/listing-12-20/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-20/src/lib.rs b/listings/ch12-an-io-project/listing-12-20/src/lib.rs new file mode 100755 index 0000000..542d088 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/src/lib.rs @@ -0,0 +1,76 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + for line in search(&config.query, &contents) { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/listing-12-20/src/main.rs b/listings/ch12-an-io-project/listing-12-20/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-21/Cargo.lock b/listings/ch12-an-io-project/listing-12-21/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-21/Cargo.toml b/listings/ch12-an-io-project/listing-12-21/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-21/output.txt b/listings/ch12-an-io-project/listing-12-21/output.txt new file mode 100755 index 0000000..97ae4a4 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/output.txt @@ -0,0 +1,23 @@ +$ cargo test + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished test [unoptimized + debuginfo] target(s) in 1.33s + Running unittests (target/debug/deps/minigrep-9cd200e5fac0fc94) + +running 2 tests +test tests::case_insensitive ... ok +test tests::case_sensitive ... ok + +test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests (target/debug/deps/minigrep-9cd200e5fac0fc94) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Doc-tests minigrep + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + diff --git a/listings/ch12-an-io-project/listing-12-21/poem.txt b/listings/ch12-an-io-project/listing-12-21/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-21/src/lib.rs b/listings/ch12-an-io-project/listing-12-21/src/lib.rs new file mode 100755 index 0000000..10f6dea --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/src/lib.rs @@ -0,0 +1,92 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + for line in search(&config.query, &contents) { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +// ANCHOR: here +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch12-an-io-project/listing-12-21/src/main.rs b/listings/ch12-an-io-project/listing-12-21/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-22/Cargo.lock b/listings/ch12-an-io-project/listing-12-22/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-22/Cargo.toml b/listings/ch12-an-io-project/listing-12-22/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-22/poem.txt b/listings/ch12-an-io-project/listing-12-22/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-22/src/lib.rs b/listings/ch12-an-io-project/listing-12-22/src/lib.rs new file mode 100755 index 0000000..3402a27 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/src/lib.rs @@ -0,0 +1,101 @@ +use std::error::Error; +use std::fs; + +// ANCHOR: here +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} +// ANCHOR_END: here + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +// ANCHOR: there +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} +// ANCHOR_END: there + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch12-an-io-project/listing-12-22/src/main.rs b/listings/ch12-an-io-project/listing-12-22/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-23/Cargo.lock b/listings/ch12-an-io-project/listing-12-23/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-23/Cargo.toml b/listings/ch12-an-io-project/listing-12-23/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-23/output.txt b/listings/ch12-an-io-project/listing-12-23/output.txt new file mode 100755 index 0000000..0f0f07f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/output.txt @@ -0,0 +1,6 @@ +$ cargo run to poem.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.0s + Running `target/debug/minigrep to poem.txt` +Are you nobody, too? +How dreary to be somebody! diff --git a/listings/ch12-an-io-project/listing-12-23/poem.txt b/listings/ch12-an-io-project/listing-12-23/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-23/src/lib.rs b/listings/ch12-an-io-project/listing-12-23/src/lib.rs new file mode 100755 index 0000000..fa63a8c --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/src/lib.rs @@ -0,0 +1,110 @@ +// ANCHOR: here +use std::env; +// --snip-- + +// ANCHOR_END: here +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +// ANCHOR: here +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} +// ANCHOR_END: here + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch12-an-io-project/listing-12-23/src/main.rs b/listings/ch12-an-io-project/listing-12-23/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/listing-12-24/Cargo.lock b/listings/ch12-an-io-project/listing-12-24/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/listing-12-24/Cargo.toml b/listings/ch12-an-io-project/listing-12-24/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/listing-12-24/poem.txt b/listings/ch12-an-io-project/listing-12-24/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/listing-12-24/src/lib.rs b/listings/ch12-an-io-project/listing-12-24/src/lib.rs new file mode 100755 index 0000000..fe1dccf --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/src/lib.rs @@ -0,0 +1,104 @@ +use std::env; +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch12-an-io-project/listing-12-24/src/main.rs b/listings/ch12-an-io-project/listing-12-24/src/main.rs new file mode 100755 index 0000000..9e38553 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/src/main.rs @@ -0,0 +1,21 @@ +use std::env; +use std::process; + +use minigrep::Config; + +// ANCHOR: here +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + eprintln!("Application error: {}", e); + + process::exit(1); + } +} +// ANCHOR_END: here diff --git a/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.lock b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.toml b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/poem.txt b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs new file mode 100755 index 0000000..44bcfea --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs @@ -0,0 +1,54 @@ +use std::env; +use std::error::Error; +use std::fs; +use std::process; + +// ANCHOR: here +fn main() { + // --snip-- + + // ANCHOR_END: here + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + // ANCHOR: here + println!("Searching for {}", config.query); + println!("In file {}", config.filename); + + if let Err(e) = run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} +// ANCHOR_END: here + +fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + println!("With text:\n{}", contents); + + Ok(()) +} + +struct Config { + query: String, + filename: String, +} + +impl Config { + fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} diff --git a/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.lock b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.toml b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/no-listing-02-using-search-in-run/output.txt b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/output.txt new file mode 100755 index 0000000..91532d0 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/output.txt @@ -0,0 +1,5 @@ +$ cargo run frog poem.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.38s + Running `target/debug/minigrep frog poem.txt` +How public, like a frog diff --git a/listings/ch12-an-io-project/no-listing-02-using-search-in-run/poem.txt b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs new file mode 100755 index 0000000..ede4eb4 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs @@ -0,0 +1,60 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +// ANCHOR: here +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + for line in search(&config.query, &contents) { + println!("{}", line); + } + + Ok(()) +} +// ANCHOR_END: here + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/main.rs b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/output-only-01-with-args/Cargo.lock b/listings/ch12-an-io-project/output-only-01-with-args/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/output-only-01-with-args/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/output-only-01-with-args/Cargo.toml b/listings/ch12-an-io-project/output-only-01-with-args/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-01-with-args/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/output-only-01-with-args/output.txt b/listings/ch12-an-io-project/output-only-01-with-args/output.txt new file mode 100755 index 0000000..eb88d9a --- /dev/null +++ b/listings/ch12-an-io-project/output-only-01-with-args/output.txt @@ -0,0 +1,5 @@ +$ cargo run needle haystack + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 1.57s + Running `target/debug/minigrep needle haystack` +["target/debug/minigrep", "needle", "haystack"] diff --git a/listings/ch12-an-io-project/output-only-01-with-args/src/main.rs b/listings/ch12-an-io-project/output-only-01-with-args/src/main.rs new file mode 100755 index 0000000..aa3056d --- /dev/null +++ b/listings/ch12-an-io-project/output-only-01-with-args/src/main.rs @@ -0,0 +1,6 @@ +use std::env; + +fn main() { + let args: Vec = env::args().collect(); + println!("{:?}", args); +} diff --git a/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.lock b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.toml b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt new file mode 100755 index 0000000..93116dd --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt @@ -0,0 +1,16 @@ +$ cargo build + Compiling minigrep v0.1.0 (file:///projects/minigrep) +error[E0106]: missing lifetime specifier + --> src/lib.rs:28:51 + | +28 | pub fn search(query: &str, contents: &str) -> Vec<&str> { + | ---- ---- ^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `query` or `contents` +help: consider introducing a named lifetime parameter + | +28 | pub fn search<'a>(query: &'a str, contents: &'a str) -> Vec<&'a str> { + | ++++ ++ ++ ++ + +For more information about this error, try `rustc --explain E0106`. +error: could not compile `minigrep` due to previous error diff --git a/listings/ch12-an-io-project/output-only-02-missing-lifetimes/poem.txt b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs new file mode 100755 index 0000000..65af968 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs @@ -0,0 +1,48 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + Ok(()) +} + +// ANCHOR: here +pub fn search(query: &str, contents: &str) -> Vec<&str> { + vec![] +} +// ANCHOR_END: here + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/main.rs b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.lock b/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.toml b/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/output-only-03-multiple-matches/output.txt b/listings/ch12-an-io-project/output-only-03-multiple-matches/output.txt new file mode 100755 index 0000000..2b19bf9 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/output.txt @@ -0,0 +1,7 @@ +$ cargo run body poem.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.0s + Running `target/debug/minigrep body poem.txt` +I'm nobody! Who are you? +Are you nobody, too? +How dreary to be somebody! diff --git a/listings/ch12-an-io-project/output-only-03-multiple-matches/poem.txt b/listings/ch12-an-io-project/output-only-03-multiple-matches/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs b/listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs new file mode 100755 index 0000000..ede4eb4 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs @@ -0,0 +1,60 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +// ANCHOR: here +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + for line in search(&config.query, &contents) { + println!("{}", line); + } + + Ok(()) +} +// ANCHOR_END: here + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/output-only-03-multiple-matches/src/main.rs b/listings/ch12-an-io-project/output-only-03-multiple-matches/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.lock b/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.toml b/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch12-an-io-project/output-only-04-no-matches/output.txt b/listings/ch12-an-io-project/output-only-04-no-matches/output.txt new file mode 100755 index 0000000..4cd6c8a --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/output.txt @@ -0,0 +1,4 @@ +$ cargo run monomorphization poem.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) + Finished dev [unoptimized + debuginfo] target(s) in 0.0s + Running `target/debug/minigrep monomorphization poem.txt` diff --git a/listings/ch12-an-io-project/output-only-04-no-matches/poem.txt b/listings/ch12-an-io-project/output-only-04-no-matches/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs b/listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs new file mode 100755 index 0000000..ede4eb4 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs @@ -0,0 +1,60 @@ +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + Ok(Config { query, filename }) + } +} + +// ANCHOR: here +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + for line in search(&config.query, &contents) { + println!("{}", line); + } + + Ok(()) +} +// ANCHOR_END: here + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn one_result() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } +} diff --git a/listings/ch12-an-io-project/output-only-04-no-matches/src/main.rs b/listings/ch12-an-io-project/output-only-04-no-matches/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.lock b/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.toml b/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-12-23-reproduced/poem.txt b/listings/ch13-functional-features/listing-12-23-reproduced/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-reproduced/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs b/listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs new file mode 100755 index 0000000..7f0178d --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs @@ -0,0 +1,106 @@ +use std::env; +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +// ANCHOR: ch13 +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} +// ANCHOR_END: ch13 + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch13-functional-features/listing-12-23-reproduced/src/main.rs b/listings/ch13-functional-features/listing-12-23-reproduced/src/main.rs new file mode 100755 index 0000000..53af83f --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-reproduced/src/main.rs @@ -0,0 +1,19 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + println!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + println!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.lock b/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.toml b/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-12-24-reproduced/poem.txt b/listings/ch13-functional-features/listing-12-24-reproduced/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs b/listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs new file mode 100755 index 0000000..fe1dccf --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs @@ -0,0 +1,104 @@ +use std::env; +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs b/listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs new file mode 100755 index 0000000..ec27e67 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs @@ -0,0 +1,25 @@ +use std::env; +use std::process; + +use minigrep::Config; + +// ANCHOR: ch13 +fn main() { + let args: Vec = env::args().collect(); + + let config = Config::new(&args).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + // --snip-- + // ANCHOR_END: ch13 + + if let Err(e) = minigrep::run(config) { + eprintln!("Application error: {}", e); + + process::exit(1); + } + // ANCHOR: ch13 +} +// ANCHOR_END: ch13 diff --git a/listings/ch13-functional-features/listing-13-01/Cargo.lock b/listings/ch13-functional-features/listing-13-01/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-01/Cargo.toml b/listings/ch13-functional-features/listing-13-01/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-01/src/main.rs b/listings/ch13-functional-features/listing-13-01/src/main.rs new file mode 100755 index 0000000..97eace0 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-01/src/main.rs @@ -0,0 +1,12 @@ +// ANCHOR: here +use std::thread; +use std::time::Duration; + +fn simulated_expensive_calculation(intensity: u32) -> u32 { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + intensity +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch13-functional-features/listing-13-02/Cargo.lock b/listings/ch13-functional-features/listing-13-02/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-02/Cargo.toml b/listings/ch13-functional-features/listing-13-02/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-02/src/main.rs b/listings/ch13-functional-features/listing-13-02/src/main.rs new file mode 100755 index 0000000..96d06c7 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-02/src/main.rs @@ -0,0 +1,19 @@ +use std::thread; +use std::time::Duration; + +fn simulated_expensive_calculation(intensity: u32) -> u32 { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + intensity +} + +fn generate_workout(intensity: u32, random_number: u32) {} + +// ANCHOR: here +fn main() { + let simulated_user_specified_value = 10; + let simulated_random_number = 7; + + generate_workout(simulated_user_specified_value, simulated_random_number); +} +// ANCHOR_END: here diff --git a/listings/ch13-functional-features/listing-13-03/Cargo.lock b/listings/ch13-functional-features/listing-13-03/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-03/Cargo.toml b/listings/ch13-functional-features/listing-13-03/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-03/src/main.rs b/listings/ch13-functional-features/listing-13-03/src/main.rs new file mode 100755 index 0000000..d43c9b2 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-03/src/main.rs @@ -0,0 +1,39 @@ +use std::thread; +use std::time::Duration; + +fn simulated_expensive_calculation(intensity: u32) -> u32 { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + intensity +} + +// ANCHOR: here +fn generate_workout(intensity: u32, random_number: u32) { + if intensity < 25 { + println!( + "Today, do {} pushups!", + simulated_expensive_calculation(intensity) + ); + println!( + "Next, do {} situps!", + simulated_expensive_calculation(intensity) + ); + } else { + if random_number == 3 { + println!("Take a break today! Remember to stay hydrated!"); + } else { + println!( + "Today, run for {} minutes!", + simulated_expensive_calculation(intensity) + ); + } + } +} +// ANCHOR_END: here + +fn main() { + let simulated_user_specified_value = 10; + let simulated_random_number = 7; + + generate_workout(simulated_user_specified_value, simulated_random_number); +} diff --git a/listings/ch13-functional-features/listing-13-04/Cargo.lock b/listings/ch13-functional-features/listing-13-04/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-04/Cargo.toml b/listings/ch13-functional-features/listing-13-04/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-04/src/main.rs b/listings/ch13-functional-features/listing-13-04/src/main.rs new file mode 100755 index 0000000..fabe0fb --- /dev/null +++ b/listings/ch13-functional-features/listing-13-04/src/main.rs @@ -0,0 +1,32 @@ +use std::thread; +use std::time::Duration; + +fn simulated_expensive_calculation(intensity: u32) -> u32 { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + intensity +} + +// ANCHOR: here +fn generate_workout(intensity: u32, random_number: u32) { + let expensive_result = simulated_expensive_calculation(intensity); + + if intensity < 25 { + println!("Today, do {} pushups!", expensive_result); + println!("Next, do {} situps!", expensive_result); + } else { + if random_number == 3 { + println!("Take a break today! Remember to stay hydrated!"); + } else { + println!("Today, run for {} minutes!", expensive_result); + } + } +} +// ANCHOR_END: here + +fn main() { + let simulated_user_specified_value = 10; + let simulated_random_number = 7; + + generate_workout(simulated_user_specified_value, simulated_random_number); +} diff --git a/listings/ch13-functional-features/listing-13-05/Cargo.lock b/listings/ch13-functional-features/listing-13-05/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-05/Cargo.toml b/listings/ch13-functional-features/listing-13-05/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-05/src/main.rs b/listings/ch13-functional-features/listing-13-05/src/main.rs new file mode 100755 index 0000000..6984a27 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-05/src/main.rs @@ -0,0 +1,33 @@ +use std::thread; +use std::time::Duration; + +fn generate_workout(intensity: u32, random_number: u32) { + // ANCHOR: here + let expensive_closure = |num| { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + num + }; + // ANCHOR_END: here + + if intensity < 25 { + println!("Today, do {} pushups!", expensive_closure(intensity)); + println!("Next, do {} situps!", expensive_closure(intensity)); + } else { + if random_number == 3 { + println!("Take a break today! Remember to stay hydrated!"); + } else { + println!( + "Today, run for {} minutes!", + expensive_closure(intensity) + ); + } + } +} + +fn main() { + let simulated_user_specified_value = 10; + let simulated_random_number = 7; + + generate_workout(simulated_user_specified_value, simulated_random_number); +} diff --git a/listings/ch13-functional-features/listing-13-06/Cargo.lock b/listings/ch13-functional-features/listing-13-06/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-06/Cargo.toml b/listings/ch13-functional-features/listing-13-06/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-06/src/main.rs b/listings/ch13-functional-features/listing-13-06/src/main.rs new file mode 100755 index 0000000..8850e58 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-06/src/main.rs @@ -0,0 +1,33 @@ +use std::thread; +use std::time::Duration; + +// ANCHOR: here +fn generate_workout(intensity: u32, random_number: u32) { + let expensive_closure = |num| { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + num + }; + + if intensity < 25 { + println!("Today, do {} pushups!", expensive_closure(intensity)); + println!("Next, do {} situps!", expensive_closure(intensity)); + } else { + if random_number == 3 { + println!("Take a break today! Remember to stay hydrated!"); + } else { + println!( + "Today, run for {} minutes!", + expensive_closure(intensity) + ); + } + } +} +// ANCHOR_END: here + +fn main() { + let simulated_user_specified_value = 10; + let simulated_random_number = 7; + + generate_workout(simulated_user_specified_value, simulated_random_number); +} diff --git a/listings/ch13-functional-features/listing-13-07/Cargo.lock b/listings/ch13-functional-features/listing-13-07/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-07/Cargo.toml b/listings/ch13-functional-features/listing-13-07/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-07/src/main.rs b/listings/ch13-functional-features/listing-13-07/src/main.rs new file mode 100755 index 0000000..b3f4cc2 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-07/src/main.rs @@ -0,0 +1,33 @@ +use std::thread; +use std::time::Duration; + +fn generate_workout(intensity: u32, random_number: u32) { + // ANCHOR: here + let expensive_closure = |num: u32| -> u32 { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + num + }; + // ANCHOR_END: here + + if intensity < 25 { + println!("Today, do {} pushups!", expensive_closure(intensity)); + println!("Next, do {} situps!", expensive_closure(intensity)); + } else { + if random_number == 3 { + println!("Take a break today! Remember to stay hydrated!"); + } else { + println!( + "Today, run for {} minutes!", + expensive_closure(intensity) + ); + } + } +} + +fn main() { + let simulated_user_specified_value = 10; + let simulated_random_number = 7; + + generate_workout(simulated_user_specified_value, simulated_random_number); +} diff --git a/listings/ch13-functional-features/listing-13-08/Cargo.lock b/listings/ch13-functional-features/listing-13-08/Cargo.lock new file mode 100755 index 0000000..c190d3a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "closure-example" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-08/Cargo.toml b/listings/ch13-functional-features/listing-13-08/Cargo.toml new file mode 100755 index 0000000..914c4cf --- /dev/null +++ b/listings/ch13-functional-features/listing-13-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "closure-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-08/output.txt b/listings/ch13-functional-features/listing-13-08/output.txt new file mode 100755 index 0000000..37d8361 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-08/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling closure-example v0.1.0 (file:///projects/closure-example) +error[E0308]: mismatched types + --> src/main.rs:5:29 + | +5 | let n = example_closure(5); + | ^- help: try using a conversion method: `.to_string()` + | | + | expected struct `String`, found integer + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `closure-example` due to previous error diff --git a/listings/ch13-functional-features/listing-13-08/src/main.rs b/listings/ch13-functional-features/listing-13-08/src/main.rs new file mode 100755 index 0000000..ebb2489 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-08/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let example_closure = |x| x; + + let s = example_closure(String::from("hello")); + let n = example_closure(5); + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-09/Cargo.lock b/listings/ch13-functional-features/listing-13-09/Cargo.lock new file mode 100755 index 0000000..e090432 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cacher" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-09/Cargo.toml b/listings/ch13-functional-features/listing-13-09/Cargo.toml new file mode 100755 index 0000000..6b81ef9 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cacher" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-09/src/main.rs b/listings/ch13-functional-features/listing-13-09/src/main.rs new file mode 100755 index 0000000..3fd4ed0 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-09/src/main.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +struct Cacher +where + T: Fn(u32) -> u32, +{ + calculation: T, + value: Option, +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch13-functional-features/listing-13-10/Cargo.lock b/listings/ch13-functional-features/listing-13-10/Cargo.lock new file mode 100755 index 0000000..e090432 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cacher" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-10/Cargo.toml b/listings/ch13-functional-features/listing-13-10/Cargo.toml new file mode 100755 index 0000000..6b81ef9 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cacher" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-10/src/main.rs b/listings/ch13-functional-features/listing-13-10/src/main.rs new file mode 100755 index 0000000..4d1034d --- /dev/null +++ b/listings/ch13-functional-features/listing-13-10/src/main.rs @@ -0,0 +1,34 @@ +struct Cacher +where + T: Fn(u32) -> u32, +{ + calculation: T, + value: Option, +} + +// ANCHOR: here +impl Cacher +where + T: Fn(u32) -> u32, +{ + fn new(calculation: T) -> Cacher { + Cacher { + calculation, + value: None, + } + } + + fn value(&mut self, arg: u32) -> u32 { + match self.value { + Some(v) => v, + None => { + let v = (self.calculation)(arg); + self.value = Some(v); + v + } + } + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch13-functional-features/listing-13-11/Cargo.lock b/listings/ch13-functional-features/listing-13-11/Cargo.lock new file mode 100755 index 0000000..75ff09e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "workout-app" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-11/Cargo.toml b/listings/ch13-functional-features/listing-13-11/Cargo.toml new file mode 100755 index 0000000..f09a737 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "workout-app" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-11/src/main.rs b/listings/ch13-functional-features/listing-13-11/src/main.rs new file mode 100755 index 0000000..9f378b7 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-11/src/main.rs @@ -0,0 +1,64 @@ +use std::thread; +use std::time::Duration; + +struct Cacher +where + T: Fn(u32) -> u32, +{ + calculation: T, + value: Option, +} + +impl Cacher +where + T: Fn(u32) -> u32, +{ + fn new(calculation: T) -> Cacher { + Cacher { + calculation, + value: None, + } + } + + fn value(&mut self, arg: u32) -> u32 { + match self.value { + Some(v) => v, + None => { + let v = (self.calculation)(arg); + self.value = Some(v); + v + } + } + } +} + +// ANCHOR: here +fn generate_workout(intensity: u32, random_number: u32) { + let mut expensive_result = Cacher::new(|num| { + println!("calculating slowly..."); + thread::sleep(Duration::from_secs(2)); + num + }); + + if intensity < 25 { + println!("Today, do {} pushups!", expensive_result.value(intensity)); + println!("Next, do {} situps!", expensive_result.value(intensity)); + } else { + if random_number == 3 { + println!("Take a break today! Remember to stay hydrated!"); + } else { + println!( + "Today, run for {} minutes!", + expensive_result.value(intensity) + ); + } + } +} +// ANCHOR_END: here + +fn main() { + let simulated_user_specified_value = 10; + let simulated_random_number = 7; + + generate_workout(simulated_user_specified_value, simulated_random_number); +} diff --git a/listings/ch13-functional-features/listing-13-12/Cargo.lock b/listings/ch13-functional-features/listing-13-12/Cargo.lock new file mode 100755 index 0000000..a96532a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "equal-to-x" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-12/Cargo.toml b/listings/ch13-functional-features/listing-13-12/Cargo.toml new file mode 100755 index 0000000..ca73ff7 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "equal-to-x" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-12/src/main.rs b/listings/ch13-functional-features/listing-13-12/src/main.rs new file mode 100755 index 0000000..7352b80 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-12/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let x = 4; + + let equal_to_x = |z| z == x; + + let y = 4; + + assert!(equal_to_x(y)); +} diff --git a/listings/ch13-functional-features/listing-13-13/Cargo.lock b/listings/ch13-functional-features/listing-13-13/Cargo.lock new file mode 100755 index 0000000..e91eaa8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "iterators" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-13/Cargo.toml b/listings/ch13-functional-features/listing-13-13/Cargo.toml new file mode 100755 index 0000000..2652a8a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "iterators" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-13/src/main.rs b/listings/ch13-functional-features/listing-13-13/src/main.rs new file mode 100755 index 0000000..55a0dd3 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-13/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + let v1 = vec![1, 2, 3]; + + let v1_iter = v1.iter(); + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-14/Cargo.lock b/listings/ch13-functional-features/listing-13-14/Cargo.lock new file mode 100755 index 0000000..e91eaa8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "iterators" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-14/Cargo.toml b/listings/ch13-functional-features/listing-13-14/Cargo.toml new file mode 100755 index 0000000..2652a8a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "iterators" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-14/src/main.rs b/listings/ch13-functional-features/listing-13-14/src/main.rs new file mode 100755 index 0000000..712aff4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-14/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let v1 = vec![1, 2, 3]; + + let v1_iter = v1.iter(); + + for val in v1_iter { + println!("Got: {}", val); + } + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-15/Cargo.lock b/listings/ch13-functional-features/listing-13-15/Cargo.lock new file mode 100755 index 0000000..e91eaa8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "iterators" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-15/Cargo.toml b/listings/ch13-functional-features/listing-13-15/Cargo.toml new file mode 100755 index 0000000..2652a8a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "iterators" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-15/src/lib.rs b/listings/ch13-functional-features/listing-13-15/src/lib.rs new file mode 100755 index 0000000..7582840 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-15/src/lib.rs @@ -0,0 +1,16 @@ +#[cfg(test)] +mod tests { + // ANCHOR: here + #[test] + fn iterator_demonstration() { + let v1 = vec![1, 2, 3]; + + let mut v1_iter = v1.iter(); + + assert_eq!(v1_iter.next(), Some(&1)); + assert_eq!(v1_iter.next(), Some(&2)); + assert_eq!(v1_iter.next(), Some(&3)); + assert_eq!(v1_iter.next(), None); + } + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-16/Cargo.lock b/listings/ch13-functional-features/listing-13-16/Cargo.lock new file mode 100755 index 0000000..e91eaa8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "iterators" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-16/Cargo.toml b/listings/ch13-functional-features/listing-13-16/Cargo.toml new file mode 100755 index 0000000..2652a8a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "iterators" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-16/src/lib.rs b/listings/ch13-functional-features/listing-13-16/src/lib.rs new file mode 100755 index 0000000..d1cb54d --- /dev/null +++ b/listings/ch13-functional-features/listing-13-16/src/lib.rs @@ -0,0 +1,15 @@ +#[cfg(test)] +mod tests { + // ANCHOR: here + #[test] + fn iterator_sum() { + let v1 = vec![1, 2, 3]; + + let v1_iter = v1.iter(); + + let total: i32 = v1_iter.sum(); + + assert_eq!(total, 6); + } + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-17/Cargo.lock b/listings/ch13-functional-features/listing-13-17/Cargo.lock new file mode 100755 index 0000000..e91eaa8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "iterators" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-17/Cargo.toml b/listings/ch13-functional-features/listing-13-17/Cargo.toml new file mode 100755 index 0000000..2652a8a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "iterators" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-17/output.txt b/listings/ch13-functional-features/listing-13-17/output.txt new file mode 100755 index 0000000..228c764 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-17/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling iterators v0.1.0 (file:///projects/iterators) +warning: unused `Map` that must be used + --> src/main.rs:4:5 + | +4 | v1.iter().map(|x| x + 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unused_must_use)]` on by default + = note: iterators are lazy and do nothing unless consumed + +warning: `iterators` (bin "iterators") generated 1 warning + Finished dev [unoptimized + debuginfo] target(s) in 0.47s + Running `target/debug/iterators` diff --git a/listings/ch13-functional-features/listing-13-17/src/main.rs b/listings/ch13-functional-features/listing-13-17/src/main.rs new file mode 100755 index 0000000..62a68be --- /dev/null +++ b/listings/ch13-functional-features/listing-13-17/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + let v1: Vec = vec![1, 2, 3]; + + v1.iter().map(|x| x + 1); + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-18/Cargo.lock b/listings/ch13-functional-features/listing-13-18/Cargo.lock new file mode 100755 index 0000000..e91eaa8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "iterators" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-18/Cargo.toml b/listings/ch13-functional-features/listing-13-18/Cargo.toml new file mode 100755 index 0000000..2652a8a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "iterators" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-18/src/main.rs b/listings/ch13-functional-features/listing-13-18/src/main.rs new file mode 100755 index 0000000..db9025d --- /dev/null +++ b/listings/ch13-functional-features/listing-13-18/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + let v1: Vec = vec![1, 2, 3]; + + let v2: Vec<_> = v1.iter().map(|x| x + 1).collect(); + + assert_eq!(v2, vec![2, 3, 4]); + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-19/Cargo.lock b/listings/ch13-functional-features/listing-13-19/Cargo.lock new file mode 100755 index 0000000..0b15e21 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "shoe_size" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-19/Cargo.toml b/listings/ch13-functional-features/listing-13-19/Cargo.toml new file mode 100755 index 0000000..cc80377 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "shoe_size" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-19/src/lib.rs b/listings/ch13-functional-features/listing-13-19/src/lib.rs new file mode 100755 index 0000000..281c3c9 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-19/src/lib.rs @@ -0,0 +1,48 @@ +#[derive(PartialEq, Debug)] +struct Shoe { + size: u32, + style: String, +} + +fn shoes_in_size(shoes: Vec, shoe_size: u32) -> Vec { + shoes.into_iter().filter(|s| s.size == shoe_size).collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn filters_by_size() { + let shoes = vec![ + Shoe { + size: 10, + style: String::from("sneaker"), + }, + Shoe { + size: 13, + style: String::from("sandal"), + }, + Shoe { + size: 10, + style: String::from("boot"), + }, + ]; + + let in_my_size = shoes_in_size(shoes, 10); + + assert_eq!( + in_my_size, + vec![ + Shoe { + size: 10, + style: String::from("sneaker") + }, + Shoe { + size: 10, + style: String::from("boot") + }, + ] + ); + } +} diff --git a/listings/ch13-functional-features/listing-13-20/Cargo.lock b/listings/ch13-functional-features/listing-13-20/Cargo.lock new file mode 100755 index 0000000..58b70c5 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "counter" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-20/Cargo.toml b/listings/ch13-functional-features/listing-13-20/Cargo.toml new file mode 100755 index 0000000..9e103f3 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "counter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-20/src/lib.rs b/listings/ch13-functional-features/listing-13-20/src/lib.rs new file mode 100755 index 0000000..fb8a0cb --- /dev/null +++ b/listings/ch13-functional-features/listing-13-20/src/lib.rs @@ -0,0 +1,9 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} diff --git a/listings/ch13-functional-features/listing-13-21/Cargo.lock b/listings/ch13-functional-features/listing-13-21/Cargo.lock new file mode 100755 index 0000000..58b70c5 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "counter" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-21/Cargo.toml b/listings/ch13-functional-features/listing-13-21/Cargo.toml new file mode 100755 index 0000000..9e103f3 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "counter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-21/src/lib.rs b/listings/ch13-functional-features/listing-13-21/src/lib.rs new file mode 100755 index 0000000..35ea8e5 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-21/src/lib.rs @@ -0,0 +1,24 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +// ANCHOR: here +impl Iterator for Counter { + type Item = u32; + + fn next(&mut self) -> Option { + if self.count < 5 { + self.count += 1; + Some(self.count) + } else { + None + } + } +} +// ANCHOR_END: here diff --git a/listings/ch13-functional-features/listing-13-22/Cargo.lock b/listings/ch13-functional-features/listing-13-22/Cargo.lock new file mode 100755 index 0000000..58b70c5 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "counter" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-22/Cargo.toml b/listings/ch13-functional-features/listing-13-22/Cargo.toml new file mode 100755 index 0000000..9e103f3 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "counter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-22/src/lib.rs b/listings/ch13-functional-features/listing-13-22/src/lib.rs new file mode 100755 index 0000000..05afa41 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-22/src/lib.rs @@ -0,0 +1,41 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +impl Iterator for Counter { + type Item = u32; + + fn next(&mut self) -> Option { + if self.count < 5 { + self.count += 1; + Some(self.count) + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // ANCHOR: here + #[test] + fn calling_next_directly() { + let mut counter = Counter::new(); + + assert_eq!(counter.next(), Some(1)); + assert_eq!(counter.next(), Some(2)); + assert_eq!(counter.next(), Some(3)); + assert_eq!(counter.next(), Some(4)); + assert_eq!(counter.next(), Some(5)); + assert_eq!(counter.next(), None); + } + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-23/Cargo.lock b/listings/ch13-functional-features/listing-13-23/Cargo.lock new file mode 100755 index 0000000..58b70c5 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "counter" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-23/Cargo.toml b/listings/ch13-functional-features/listing-13-23/Cargo.toml new file mode 100755 index 0000000..9e103f3 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "counter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-23/src/lib.rs b/listings/ch13-functional-features/listing-13-23/src/lib.rs new file mode 100755 index 0000000..f04d730 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-23/src/lib.rs @@ -0,0 +1,51 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +impl Iterator for Counter { + type Item = u32; + + fn next(&mut self) -> Option { + if self.count < 5 { + self.count += 1; + Some(self.count) + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn calling_next_directly() { + let mut counter = Counter::new(); + + assert_eq!(counter.next(), Some(1)); + assert_eq!(counter.next(), Some(2)); + assert_eq!(counter.next(), Some(3)); + assert_eq!(counter.next(), Some(4)); + assert_eq!(counter.next(), Some(5)); + assert_eq!(counter.next(), None); + } + + // ANCHOR: here + #[test] + fn using_other_iterator_trait_methods() { + let sum: u32 = Counter::new() + .zip(Counter::new().skip(1)) + .map(|(a, b)| a * b) + .filter(|x| x % 3 == 0) + .sum(); + assert_eq!(18, sum); + } + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/listing-13-25/Cargo.lock b/listings/ch13-functional-features/listing-13-25/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-25/Cargo.toml b/listings/ch13-functional-features/listing-13-25/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-25/poem.txt b/listings/ch13-functional-features/listing-13-25/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch13-functional-features/listing-13-25/src/lib.rs b/listings/ch13-functional-features/listing-13-25/src/lib.rs new file mode 100755 index 0000000..fe1dccf --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/src/lib.rs @@ -0,0 +1,104 @@ +use std::env; +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +impl Config { + pub fn new(args: &[String]) -> Result { + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch13-functional-features/listing-13-25/src/main.rs b/listings/ch13-functional-features/listing-13-25/src/main.rs new file mode 100755 index 0000000..d09966e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/src/main.rs @@ -0,0 +1,23 @@ +use std::env; +use std::process; + +use minigrep::Config; + +// ANCHOR: here +fn main() { + let config = Config::new(env::args()).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + // --snip-- + // ANCHOR_END: here + + if let Err(e) = minigrep::run(config) { + eprintln!("Application error: {}", e); + + process::exit(1); + } + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch13-functional-features/listing-13-26/Cargo.lock b/listings/ch13-functional-features/listing-13-26/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-26/Cargo.toml b/listings/ch13-functional-features/listing-13-26/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-26/poem.txt b/listings/ch13-functional-features/listing-13-26/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch13-functional-features/listing-13-26/src/lib.rs b/listings/ch13-functional-features/listing-13-26/src/lib.rs new file mode 100755 index 0000000..2cb0bea --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/src/lib.rs @@ -0,0 +1,107 @@ +use std::env; +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +// ANCHOR: here +impl Config { + pub fn new(mut args: env::Args) -> Result { + // --snip-- + // ANCHOR_END: here + if args.len() < 3 { + return Err("not enough arguments"); + } + + let query = args[1].clone(); + let filename = args[2].clone(); + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch13-functional-features/listing-13-26/src/main.rs b/listings/ch13-functional-features/listing-13-26/src/main.rs new file mode 100755 index 0000000..06aac30 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/src/main.rs @@ -0,0 +1,17 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let config = Config::new(env::args()).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + eprintln!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch13-functional-features/listing-13-27/Cargo.lock b/listings/ch13-functional-features/listing-13-27/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-27/Cargo.toml b/listings/ch13-functional-features/listing-13-27/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-27/poem.txt b/listings/ch13-functional-features/listing-13-27/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch13-functional-features/listing-13-27/src/lib.rs b/listings/ch13-functional-features/listing-13-27/src/lib.rs new file mode 100755 index 0000000..7a33565 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/src/lib.rs @@ -0,0 +1,111 @@ +use std::env; +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +// ANCHOR: here +impl Config { + pub fn new(mut args: env::Args) -> Result { + args.next(); + + let query = match args.next() { + Some(arg) => arg, + None => return Err("Didn't get a query string"), + }; + + let filename = match args.next() { + Some(arg) => arg, + None => return Err("Didn't get a file name"), + }; + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} +// ANCHOR_END: here + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + let mut results = Vec::new(); + + for line in contents.lines() { + if line.contains(query) { + results.push(line); + } + } + + results +} + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch13-functional-features/listing-13-27/src/main.rs b/listings/ch13-functional-features/listing-13-27/src/main.rs new file mode 100755 index 0000000..06aac30 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/src/main.rs @@ -0,0 +1,17 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let config = Config::new(env::args()).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + eprintln!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch13-functional-features/listing-13-29/Cargo.lock b/listings/ch13-functional-features/listing-13-29/Cargo.lock new file mode 100755 index 0000000..88bf82d --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "minigrep" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/listing-13-29/Cargo.toml b/listings/ch13-functional-features/listing-13-29/Cargo.toml new file mode 100755 index 0000000..64c2a3f --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "minigrep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/listing-13-29/poem.txt b/listings/ch13-functional-features/listing-13-29/poem.txt new file mode 100755 index 0000000..8707527 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/poem.txt @@ -0,0 +1,9 @@ +I'm nobody! Who are you? +Are you nobody, too? +Then there's a pair of us - don't tell! +They'd banish us, you know. + +How dreary to be somebody! +How public, like a frog +To tell your name the livelong day +To an admiring bog! diff --git a/listings/ch13-functional-features/listing-13-29/src/lib.rs b/listings/ch13-functional-features/listing-13-29/src/lib.rs new file mode 100755 index 0000000..bc8a77e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/src/lib.rs @@ -0,0 +1,106 @@ +use std::env; +use std::error::Error; +use std::fs; + +pub struct Config { + pub query: String, + pub filename: String, + pub case_sensitive: bool, +} + +impl Config { + pub fn new(mut args: std::env::Args) -> Result { + args.next(); + + let query = match args.next() { + Some(arg) => arg, + None => return Err("Didn't get a query string"), + }; + + let filename = match args.next() { + Some(arg) => arg, + None => return Err("Didn't get a file name"), + }; + + let case_sensitive = env::var("CASE_INSENSITIVE").is_err(); + + Ok(Config { + query, + filename, + case_sensitive, + }) + } +} + +pub fn run(config: Config) -> Result<(), Box> { + let contents = fs::read_to_string(config.filename)?; + + let results = if config.case_sensitive { + search(&config.query, &contents) + } else { + search_case_insensitive(&config.query, &contents) + }; + + for line in results { + println!("{}", line); + } + + Ok(()) +} + +// ANCHOR: here +pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { + contents + .lines() + .filter(|line| line.contains(query)) + .collect() +} +// ANCHOR_END: here + +pub fn search_case_insensitive<'a>( + query: &str, + contents: &'a str, +) -> Vec<&'a str> { + let query = query.to_lowercase(); + let mut results = Vec::new(); + + for line in contents.lines() { + if line.to_lowercase().contains(&query) { + results.push(line); + } + } + + results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn case_sensitive() { + let query = "duct"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Duct tape."; + + assert_eq!(vec!["safe, fast, productive."], search(query, contents)); + } + + #[test] + fn case_insensitive() { + let query = "rUsT"; + let contents = "\ +Rust: +safe, fast, productive. +Pick three. +Trust me."; + + assert_eq!( + vec!["Rust:", "Trust me."], + search_case_insensitive(query, contents) + ); + } +} diff --git a/listings/ch13-functional-features/listing-13-29/src/main.rs b/listings/ch13-functional-features/listing-13-29/src/main.rs new file mode 100755 index 0000000..06aac30 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/src/main.rs @@ -0,0 +1,17 @@ +use std::env; +use std::process; + +use minigrep::Config; + +fn main() { + let config = Config::new(env::args()).unwrap_or_else(|err| { + eprintln!("Problem parsing arguments: {}", err); + process::exit(1); + }); + + if let Err(e) = minigrep::run(config) { + eprintln!("Application error: {}", e); + + process::exit(1); + } +} diff --git a/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.lock b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.lock new file mode 100755 index 0000000..e090432 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cacher" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.toml b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.toml new file mode 100755 index 0000000..6b81ef9 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cacher" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/no-listing-01-failing-cacher-test/output.txt b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/output.txt new file mode 100755 index 0000000..c9bda8c --- /dev/null +++ b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/output.txt @@ -0,0 +1,23 @@ +$ cargo test + Compiling cacher v0.1.0 (file:///projects/cacher) + Finished test [unoptimized + debuginfo] target(s) in 0.72s + Running unittests (target/debug/deps/cacher-074d7c200c000afa) + +running 1 test +test tests::call_with_different_values ... FAILED + +failures: + +---- tests::call_with_different_values stdout ---- +thread 'main' panicked at 'assertion failed: `(left == right)` + left: `1`, + right: `2`', src/lib.rs:43:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::call_with_different_values + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch13-functional-features/no-listing-01-failing-cacher-test/src/lib.rs b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/src/lib.rs new file mode 100755 index 0000000..e7d677d --- /dev/null +++ b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/src/lib.rs @@ -0,0 +1,47 @@ +struct Cacher +where + T: Fn(u32) -> u32, +{ + calculation: T, + value: Option, +} + +impl Cacher +where + T: Fn(u32) -> u32, +{ + fn new(calculation: T) -> Cacher { + Cacher { + calculation, + value: None, + } + } + + fn value(&mut self, arg: u32) -> u32 { + match self.value { + Some(v) => v, + None => { + let v = (self.calculation)(arg); + self.value = Some(v); + v + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // ANCHOR: here + #[test] + fn call_with_different_values() { + let mut c = Cacher::new(|a| a); + + let v1 = c.value(1); + let v2 = c.value(2); + + assert_eq!(v2, 2); + } + // ANCHOR_END: here +} diff --git a/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.lock b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.lock new file mode 100755 index 0000000..a96532a --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "equal-to-x" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.toml b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.toml new file mode 100755 index 0000000..ca73ff7 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "equal-to-x" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/no-listing-02-functions-cant-capture/output.txt b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/output.txt new file mode 100755 index 0000000..3cf9915 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling equal-to-x v0.1.0 (file:///projects/equal-to-x) +error[E0434]: can't capture dynamic environment in a fn item + --> src/main.rs:5:14 + | +5 | z == x + | ^ + | + = help: use the `|| { ... }` closure form instead + +For more information about this error, try `rustc --explain E0434`. +error: could not compile `equal-to-x` due to previous error diff --git a/listings/ch13-functional-features/no-listing-02-functions-cant-capture/src/main.rs b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/src/main.rs new file mode 100755 index 0000000..1b5d2b9 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let x = 4; + + fn equal_to_x(z: i32) -> bool { + z == x + } + + let y = 4; + + assert!(equal_to_x(y)); +} diff --git a/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.lock b/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.lock new file mode 100755 index 0000000..a96532a --- /dev/null +++ b/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "equal-to-x" +version = "0.1.0" + diff --git a/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.toml b/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.toml new file mode 100755 index 0000000..ca73ff7 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "equal-to-x" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch13-functional-features/no-listing-03-move-closures/output.txt b/listings/ch13-functional-features/no-listing-03-move-closures/output.txt new file mode 100755 index 0000000..ae1aa91 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-03-move-closures/output.txt @@ -0,0 +1,18 @@ +$ cargo run + Compiling equal-to-x v0.1.0 (file:///projects/equal-to-x) +error[E0382]: borrow of moved value: `x` + --> src/main.rs:6:40 + | +2 | let x = vec![1, 2, 3]; + | - move occurs because `x` has type `Vec`, which does not implement the `Copy` trait +3 | +4 | let equal_to_x = move |z| z == x; + | -------- - variable moved due to use in closure + | | + | value moved into closure here +5 | +6 | println!("can't use x here: {:?}", x); + | ^ value borrowed here after move + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `equal-to-x` due to previous error diff --git a/listings/ch13-functional-features/no-listing-03-move-closures/src/main.rs b/listings/ch13-functional-features/no-listing-03-move-closures/src/main.rs new file mode 100755 index 0000000..19d4776 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-03-move-closures/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + let x = vec![1, 2, 3]; + + let equal_to_x = move |z| z == x; + + println!("can't use x here: {:?}", x); + + let y = vec![1, 2, 3]; + + assert!(equal_to_x(y)); +} diff --git a/listings/ch14-more-about-cargo/listing-14-01/Cargo.lock b/listings/ch14-more-about-cargo/listing-14-01/Cargo.lock new file mode 100755 index 0000000..b304dd7 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "my_crate" +version = "0.1.0" + diff --git a/listings/ch14-more-about-cargo/listing-14-01/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-01/Cargo.toml new file mode 100755 index 0000000..c52da04 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "my_crate" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/listing-14-01/src/lib.rs b/listings/ch14-more-about-cargo/listing-14-01/src/lib.rs new file mode 100755 index 0000000..ed7abb7 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-01/src/lib.rs @@ -0,0 +1,13 @@ +/// Adds one to the number given. +/// +/// # Examples +/// +/// ``` +/// let arg = 5; +/// let answer = my_crate::add_one(arg); +/// +/// assert_eq!(6, answer); +/// ``` +pub fn add_one(x: i32) -> i32 { + x + 1 +} diff --git a/listings/ch14-more-about-cargo/listing-14-02/Cargo.lock b/listings/ch14-more-about-cargo/listing-14-02/Cargo.lock new file mode 100755 index 0000000..b304dd7 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "my_crate" +version = "0.1.0" + diff --git a/listings/ch14-more-about-cargo/listing-14-02/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-02/Cargo.toml new file mode 100755 index 0000000..c52da04 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "my_crate" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/listing-14-02/src/lib.rs b/listings/ch14-more-about-cargo/listing-14-02/src/lib.rs new file mode 100755 index 0000000..64c9c43 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-02/src/lib.rs @@ -0,0 +1,21 @@ +// ANCHOR: here +//! # My Crate +//! +//! `my_crate` is a collection of utilities to make performing certain +//! calculations more convenient. + +/// Adds one to the number given. +// --snip-- +// ANCHOR_END: here +/// +/// # Examples +/// +/// ``` +/// let arg = 5; +/// let answer = my_crate::add_one(arg); +/// +/// assert_eq!(6, answer); +/// ``` +pub fn add_one(x: i32) -> i32 { + x + 1 +} diff --git a/listings/ch14-more-about-cargo/listing-14-03/Cargo.lock b/listings/ch14-more-about-cargo/listing-14-03/Cargo.lock new file mode 100755 index 0000000..df19c24 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "art" +version = "0.1.0" + diff --git a/listings/ch14-more-about-cargo/listing-14-03/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-03/Cargo.toml new file mode 100755 index 0000000..66ef4b5 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "art" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/listing-14-03/src/lib.rs b/listings/ch14-more-about-cargo/listing-14-03/src/lib.rs new file mode 100755 index 0000000..bffbe05 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-03/src/lib.rs @@ -0,0 +1,34 @@ +// ANCHOR: here +//! # Art +//! +//! A library for modeling artistic concepts. + +pub mod kinds { + /// The primary colors according to the RYB color model. + pub enum PrimaryColor { + Red, + Yellow, + Blue, + } + + /// The secondary colors according to the RYB color model. + pub enum SecondaryColor { + Orange, + Green, + Purple, + } +} + +pub mod utils { + use crate::kinds::*; + + /// Combines two primary colors in equal amounts to create + /// a secondary color. + pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor { + // --snip-- + // ANCHOR_END: here + unimplemented!(); + // ANCHOR: here + } +} +// ANCHOR_END: here diff --git a/listings/ch14-more-about-cargo/listing-14-04/Cargo.lock b/listings/ch14-more-about-cargo/listing-14-04/Cargo.lock new file mode 100755 index 0000000..df19c24 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "art" +version = "0.1.0" + diff --git a/listings/ch14-more-about-cargo/listing-14-04/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-04/Cargo.toml new file mode 100755 index 0000000..66ef4b5 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "art" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/listing-14-04/src/lib.rs b/listings/ch14-more-about-cargo/listing-14-04/src/lib.rs new file mode 100755 index 0000000..b077a9a --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-04/src/lib.rs @@ -0,0 +1,29 @@ +//! # Art +//! +//! A library for modeling artistic concepts. + +pub mod kinds { + /// The primary colors according to the RYB color model. + pub enum PrimaryColor { + Red, + Yellow, + Blue, + } + + /// The secondary colors according to the RYB color model. + pub enum SecondaryColor { + Orange, + Green, + Purple, + } +} + +pub mod utils { + use crate::kinds::*; + + /// Combines two primary colors in equal amounts to create + /// a secondary color. + pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor { + SecondaryColor::Orange + } +} diff --git a/listings/ch14-more-about-cargo/listing-14-04/src/main.rs b/listings/ch14-more-about-cargo/listing-14-04/src/main.rs new file mode 100755 index 0000000..b1a4bf7 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-04/src/main.rs @@ -0,0 +1,8 @@ +use art::kinds::PrimaryColor; +use art::utils::mix; + +fn main() { + let red = PrimaryColor::Red; + let yellow = PrimaryColor::Yellow; + mix(red, yellow); +} diff --git a/listings/ch14-more-about-cargo/listing-14-05/Cargo.lock b/listings/ch14-more-about-cargo/listing-14-05/Cargo.lock new file mode 100755 index 0000000..df19c24 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "art" +version = "0.1.0" + diff --git a/listings/ch14-more-about-cargo/listing-14-05/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-05/Cargo.toml new file mode 100755 index 0000000..66ef4b5 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "art" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/listing-14-05/src/lib.rs b/listings/ch14-more-about-cargo/listing-14-05/src/lib.rs new file mode 100755 index 0000000..c5aa9e7 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-05/src/lib.rs @@ -0,0 +1,41 @@ +// ANCHOR: here +//! # Art +//! +//! A library for modeling artistic concepts. + +pub use self::kinds::PrimaryColor; +pub use self::kinds::SecondaryColor; +pub use self::utils::mix; + +pub mod kinds { + // --snip-- + // ANCHOR_END: here + /// The primary colors according to the RYB color model. + pub enum PrimaryColor { + Red, + Yellow, + Blue, + } + + /// The secondary colors according to the RYB color model. + pub enum SecondaryColor { + Orange, + Green, + Purple, + } + // ANCHOR: here +} + +pub mod utils { + // --snip-- + // ANCHOR_END: here + use crate::kinds::*; + + /// Combines two primary colors in equal amounts to create + /// a secondary color. + pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor { + SecondaryColor::Orange + } + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch14-more-about-cargo/listing-14-06/Cargo.lock b/listings/ch14-more-about-cargo/listing-14-06/Cargo.lock new file mode 100755 index 0000000..df19c24 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "art" +version = "0.1.0" + diff --git a/listings/ch14-more-about-cargo/listing-14-06/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-06/Cargo.toml new file mode 100755 index 0000000..66ef4b5 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "art" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/listing-14-06/src/lib.rs b/listings/ch14-more-about-cargo/listing-14-06/src/lib.rs new file mode 100755 index 0000000..daabd00 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-06/src/lib.rs @@ -0,0 +1,33 @@ +//! # Art +//! +//! A library for modeling artistic concepts. + +pub use self::kinds::PrimaryColor; +pub use self::kinds::SecondaryColor; +pub use self::utils::mix; + +pub mod kinds { + /// The primary colors according to the RYB color model. + pub enum PrimaryColor { + Red, + Yellow, + Blue, + } + + /// The secondary colors according to the RYB color model. + pub enum SecondaryColor { + Orange, + Green, + Purple, + } +} + +pub mod utils { + use crate::kinds::*; + + /// Combines two primary colors in equal amounts to create + /// a secondary color. + pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor { + SecondaryColor::Orange + } +} diff --git a/listings/ch14-more-about-cargo/listing-14-06/src/main.rs b/listings/ch14-more-about-cargo/listing-14-06/src/main.rs new file mode 100755 index 0000000..51f3b76 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-06/src/main.rs @@ -0,0 +1,13 @@ +// ANCHOR: here +use art::mix; +use art::PrimaryColor; + +fn main() { + // --snip-- + // ANCHOR_END: here + let red = PrimaryColor::Red; + let yellow = PrimaryColor::Yellow; + mix(red, yellow); + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch14-more-about-cargo/listing-14-07/add/Cargo.lock b/listings/ch14-more-about-cargo/listing-14-07/add/Cargo.lock new file mode 100755 index 0000000..a456055 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/Cargo.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add_one" +version = "0.1.0" + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add_one 0.1.0", +] + diff --git a/listings/ch14-more-about-cargo/listing-14-07/add/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-07/add/Cargo.toml new file mode 100755 index 0000000..1448801 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "adder", + "add_one", +] diff --git a/listings/ch14-more-about-cargo/listing-14-07/add/add_one/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-07/add/add_one/Cargo.toml new file mode 100755 index 0000000..8af4ab8 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/add_one/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "add_one" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/listing-14-07/add/add_one/src/lib.rs b/listings/ch14-more-about-cargo/listing-14-07/add/add_one/src/lib.rs new file mode 100755 index 0000000..b0bb869 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/add_one/src/lib.rs @@ -0,0 +1,3 @@ +pub fn add_one(x: i32) -> i32 { + x + 1 +} diff --git a/listings/ch14-more-about-cargo/listing-14-07/add/adder/Cargo.toml b/listings/ch14-more-about-cargo/listing-14-07/add/adder/Cargo.toml new file mode 100755 index 0000000..feb3d95 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/adder/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] + +add_one = { path = "../add_one" } diff --git a/listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs b/listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs new file mode 100755 index 0000000..7deb796 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs @@ -0,0 +1,10 @@ +use add_one; + +fn main() { + let num = 10; + println!( + "Hello, world! {} plus one is {}!", + num, + add_one::add_one(num) + ); +} diff --git a/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.lock b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.lock new file mode 100755 index 0000000..d37189b --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" + diff --git a/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.toml new file mode 100755 index 0000000..c5ea8e5 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] + +members = [ + "adder", +] diff --git a/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/Cargo.toml new file mode 100755 index 0000000..e61cb12 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/src/main.rs b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/src/main.rs new file mode 100755 index 0000000..e7a11a9 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.lock b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.lock new file mode 100755 index 0000000..a456055 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add_one" +version = "0.1.0" + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add_one 0.1.0", +] + diff --git a/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.toml new file mode 100755 index 0000000..1448801 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "adder", + "add_one", +] diff --git a/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add_one/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add_one/Cargo.toml new file mode 100755 index 0000000..8af4ab8 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add_one/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "add_one" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add_one/src/lib.rs b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add_one/src/lib.rs new file mode 100755 index 0000000..b0bb869 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add_one/src/lib.rs @@ -0,0 +1,3 @@ +pub fn add_one(x: i32) -> i32 { + x + 1 +} diff --git a/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/Cargo.toml new file mode 100755 index 0000000..55c0203 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] +add_one = { path = "../add_one" } diff --git a/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/src/main.rs b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/src/main.rs new file mode 100755 index 0000000..e7a11a9 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.lock b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.lock new file mode 100755 index 0000000..eec3a9e --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.lock @@ -0,0 +1,90 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add_one" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add_one", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.toml new file mode 100755 index 0000000..1448801 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "adder", + "add_one", +] diff --git a/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add_one/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add_one/Cargo.toml new file mode 100755 index 0000000..fd4942a --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add_one/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "add_one" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add_one/src/lib.rs b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add_one/src/lib.rs new file mode 100755 index 0000000..7b61b40 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add_one/src/lib.rs @@ -0,0 +1,5 @@ +use rand; + +pub fn add_one(x: i32) -> i32 { + x + 1 +} diff --git a/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/Cargo.toml new file mode 100755 index 0000000..feb3d95 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] + +add_one = { path = "../add_one" } diff --git a/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs new file mode 100755 index 0000000..7deb796 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs @@ -0,0 +1,10 @@ +use add_one; + +fn main() { + let num = 10; + println!( + "Hello, world! {} plus one is {}!", + num, + add_one::add_one(num) + ); +} diff --git a/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.lock b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.lock new file mode 100755 index 0000000..a456055 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add_one" +version = "0.1.0" + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add_one 0.1.0", +] + diff --git a/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.toml new file mode 100755 index 0000000..1448801 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "adder", + "add_one", +] diff --git a/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/Cargo.toml new file mode 100755 index 0000000..8af4ab8 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "add_one" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/src/lib.rs b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/src/lib.rs new file mode 100755 index 0000000..40ceb12 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/src/lib.rs @@ -0,0 +1,13 @@ +pub fn add_one(x: i32) -> i32 { + x + 1 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + assert_eq!(3, add_one(2)); + } +} diff --git a/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/Cargo.toml b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/Cargo.toml new file mode 100755 index 0000000..feb3d95 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] + +add_one = { path = "../add_one" } diff --git a/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs new file mode 100755 index 0000000..7deb796 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs @@ -0,0 +1,10 @@ +use add_one; + +fn main() { + let num = 10; + println!( + "Hello, world! {} plus one is {}!", + num, + add_one::add_one(num) + ); +} diff --git a/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/.gitignore b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/.gitignore new file mode 100755 index 0000000..b46d5c4 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/.gitignore @@ -0,0 +1 @@ +adder diff --git a/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.lock b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.lock new file mode 100755 index 0000000..d98623d --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "adder" +version = "0.1.0" diff --git a/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.toml b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.toml new file mode 100755 index 0000000..c5ea8e5 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] + +members = [ + "adder", +] diff --git a/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/rustfmt-ignore b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/rustfmt-ignore new file mode 100755 index 0000000..958e568 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/rustfmt-ignore @@ -0,0 +1,2 @@ +This listing is used for demonstrating how to set up a workspace, but the workspace isn't +completely set up yet, so rustfmt complains the crate mentioned in Cargo.toml doesn't exist yet. diff --git a/listings/ch14-more-about-cargo/output-only-02-add-one/add/.gitignore b/listings/ch14-more-about-cargo/output-only-02-add-one/add/.gitignore new file mode 100755 index 0000000..fc0f08e --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/.gitignore @@ -0,0 +1 @@ +add_one diff --git a/listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.lock b/listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.lock new file mode 100755 index 0000000..a456055 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add_one" +version = "0.1.0" + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add_one 0.1.0", +] + diff --git a/listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.toml b/listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.toml new file mode 100755 index 0000000..1448801 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "adder", + "add_one", +] diff --git a/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/Cargo.toml b/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/Cargo.toml new file mode 100755 index 0000000..feb3d95 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] + +add_one = { path = "../add_one" } diff --git a/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/src/main.rs b/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/src/main.rs new file mode 100755 index 0000000..e7a11a9 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.lock b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.lock new file mode 100755 index 0000000..eec3a9e --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.lock @@ -0,0 +1,90 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add_one" +version = "0.1.0" +dependencies = [ + "rand", +] + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add_one", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.toml b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.toml new file mode 100755 index 0000000..1448801 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "adder", + "add_one", +] diff --git a/listings/ch14-more-about-cargo/output-only-03-use-rand/add/add_one/Cargo.toml b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/add_one/Cargo.toml new file mode 100755 index 0000000..fd4942a --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/add_one/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "add_one" +version = "0.1.0" +edition = "2021" + +[dependencies] +rand = "0.8.3" diff --git a/listings/ch14-more-about-cargo/output-only-03-use-rand/add/add_one/src/lib.rs b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/add_one/src/lib.rs new file mode 100755 index 0000000..7b61b40 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/add_one/src/lib.rs @@ -0,0 +1,5 @@ +use rand; + +pub fn add_one(x: i32) -> i32 { + x + 1 +} diff --git a/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/Cargo.toml b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/Cargo.toml new file mode 100755 index 0000000..feb3d95 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "adder" +version = "0.1.0" +edition = "2021" + +[dependencies] + +add_one = { path = "../add_one" } diff --git a/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs new file mode 100755 index 0000000..eb4050d --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs @@ -0,0 +1,11 @@ +use add_one; +use rand; + +fn main() { + let num = 10; + println!( + "Hello, world! {} plus one is {}!", + num, + add_one::add_one(num) + ); +} diff --git a/listings/ch15-smart-pointers/listing-15-01/Cargo.lock b/listings/ch15-smart-pointers/listing-15-01/Cargo.lock new file mode 100755 index 0000000..8c125fc --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "box-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-01/Cargo.toml b/listings/ch15-smart-pointers/listing-15-01/Cargo.toml new file mode 100755 index 0000000..690385c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "box-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-01/src/main.rs b/listings/ch15-smart-pointers/listing-15-01/src/main.rs new file mode 100755 index 0000000..8da1d90 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-01/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + let b = Box::new(5); + println!("b = {}", b); +} diff --git a/listings/ch15-smart-pointers/listing-15-02/Cargo.lock b/listings/ch15-smart-pointers/listing-15-02/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-02/Cargo.toml b/listings/ch15-smart-pointers/listing-15-02/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-02/src/main.rs b/listings/ch15-smart-pointers/listing-15-02/src/main.rs new file mode 100755 index 0000000..84640b9 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-02/src/main.rs @@ -0,0 +1,8 @@ +// ANCHOR: here +enum List { + Cons(i32, List), + Nil, +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch15-smart-pointers/listing-15-03/Cargo.lock b/listings/ch15-smart-pointers/listing-15-03/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-03/Cargo.toml b/listings/ch15-smart-pointers/listing-15-03/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-03/output.txt b/listings/ch15-smart-pointers/listing-15-03/output.txt new file mode 100755 index 0000000..87e7b57 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-03/output.txt @@ -0,0 +1,27 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) +error[E0072]: recursive type `List` has infinite size + --> src/main.rs:1:1 + | +1 | enum List { + | ^^^^^^^^^ recursive type has infinite size +2 | Cons(i32, List), + | ---- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` representable + | +2 | Cons(i32, Box), + | ++++ + + +error[E0391]: cycle detected when computing drop-check constraints for `List` + --> src/main.rs:1:1 + | +1 | enum List { + | ^^^^^^^^^ + | + = note: ...which immediately requires computing drop-check constraints for `List` again + = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: List } }` + +Some errors have detailed explanations: E0072, E0391. +For more information about an error, try `rustc --explain E0072`. +error: could not compile `cons-list` due to 2 previous errors diff --git a/listings/ch15-smart-pointers/listing-15-03/src/main.rs b/listings/ch15-smart-pointers/listing-15-03/src/main.rs new file mode 100755 index 0000000..a96f3d7 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-03/src/main.rs @@ -0,0 +1,12 @@ +enum List { + Cons(i32, List), + Nil, +} + +// ANCHOR: here +use crate::List::{Cons, Nil}; + +fn main() { + let list = Cons(1, Cons(2, Cons(3, Nil))); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-05/Cargo.lock b/listings/ch15-smart-pointers/listing-15-05/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-05/Cargo.toml b/listings/ch15-smart-pointers/listing-15-05/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-05/src/main.rs b/listings/ch15-smart-pointers/listing-15-05/src/main.rs new file mode 100755 index 0000000..22f7d83 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-05/src/main.rs @@ -0,0 +1,10 @@ +enum List { + Cons(i32, Box), + Nil, +} + +use crate::List::{Cons, Nil}; + +fn main() { + let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil)))))); +} diff --git a/listings/ch15-smart-pointers/listing-15-06/Cargo.lock b/listings/ch15-smart-pointers/listing-15-06/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-06/Cargo.toml b/listings/ch15-smart-pointers/listing-15-06/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-06/src/main.rs b/listings/ch15-smart-pointers/listing-15-06/src/main.rs new file mode 100755 index 0000000..174b620 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-06/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let x = 5; + let y = &x; + + assert_eq!(5, x); + assert_eq!(5, *y); +} diff --git a/listings/ch15-smart-pointers/listing-15-07/Cargo.lock b/listings/ch15-smart-pointers/listing-15-07/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-07/Cargo.toml b/listings/ch15-smart-pointers/listing-15-07/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-07/src/main.rs b/listings/ch15-smart-pointers/listing-15-07/src/main.rs new file mode 100755 index 0000000..4933a41 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-07/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let x = 5; + let y = Box::new(x); + + assert_eq!(5, x); + assert_eq!(5, *y); +} diff --git a/listings/ch15-smart-pointers/listing-15-08/Cargo.lock b/listings/ch15-smart-pointers/listing-15-08/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-08/Cargo.toml b/listings/ch15-smart-pointers/listing-15-08/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-08/src/main.rs b/listings/ch15-smart-pointers/listing-15-08/src/main.rs new file mode 100755 index 0000000..f485946 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-08/src/main.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +struct MyBox(T); + +impl MyBox { + fn new(x: T) -> MyBox { + MyBox(x) + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch15-smart-pointers/listing-15-09/Cargo.lock b/listings/ch15-smart-pointers/listing-15-09/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-09/Cargo.toml b/listings/ch15-smart-pointers/listing-15-09/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-09/output.txt b/listings/ch15-smart-pointers/listing-15-09/output.txt new file mode 100755 index 0000000..75e5f1c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-09/output.txt @@ -0,0 +1,10 @@ +$ cargo run + Compiling deref-example v0.1.0 (file:///projects/deref-example) +error[E0614]: type `MyBox<{integer}>` cannot be dereferenced + --> src/main.rs:14:19 + | +14 | assert_eq!(5, *y); + | ^^ + +For more information about this error, try `rustc --explain E0614`. +error: could not compile `deref-example` due to previous error diff --git a/listings/ch15-smart-pointers/listing-15-09/src/main.rs b/listings/ch15-smart-pointers/listing-15-09/src/main.rs new file mode 100755 index 0000000..d07f2d7 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-09/src/main.rs @@ -0,0 +1,17 @@ +struct MyBox(T); + +impl MyBox { + fn new(x: T) -> MyBox { + MyBox(x) + } +} + +// ANCHOR: here +fn main() { + let x = 5; + let y = MyBox::new(x); + + assert_eq!(5, x); + assert_eq!(5, *y); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-10/Cargo.lock b/listings/ch15-smart-pointers/listing-15-10/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-10/Cargo.toml b/listings/ch15-smart-pointers/listing-15-10/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-10/src/main.rs b/listings/ch15-smart-pointers/listing-15-10/src/main.rs new file mode 100755 index 0000000..cce754d --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-10/src/main.rs @@ -0,0 +1,27 @@ +// ANCHOR: here +use std::ops::Deref; + +impl Deref for MyBox { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} +// ANCHOR_END: here + +struct MyBox(T); + +impl MyBox { + fn new(x: T) -> MyBox { + MyBox(x) + } +} + +fn main() { + let x = 5; + let y = MyBox::new(x); + + assert_eq!(5, x); + assert_eq!(5, *y); +} diff --git a/listings/ch15-smart-pointers/listing-15-11/Cargo.lock b/listings/ch15-smart-pointers/listing-15-11/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-11/Cargo.toml b/listings/ch15-smart-pointers/listing-15-11/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-11/src/main.rs b/listings/ch15-smart-pointers/listing-15-11/src/main.rs new file mode 100755 index 0000000..b73ad89 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-11/src/main.rs @@ -0,0 +1,7 @@ +// ANCHOR: here +fn hello(name: &str) { + println!("Hello, {}!", name); +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch15-smart-pointers/listing-15-12/Cargo.lock b/listings/ch15-smart-pointers/listing-15-12/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-12/Cargo.toml b/listings/ch15-smart-pointers/listing-15-12/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-12/src/main.rs b/listings/ch15-smart-pointers/listing-15-12/src/main.rs new file mode 100755 index 0000000..6a3e143 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-12/src/main.rs @@ -0,0 +1,28 @@ +use std::ops::Deref; + +impl Deref for MyBox { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +struct MyBox(T); + +impl MyBox { + fn new(x: T) -> MyBox { + MyBox(x) + } +} + +fn hello(name: &str) { + println!("Hello, {}!", name); +} + +// ANCHOR: here +fn main() { + let m = MyBox::new(String::from("Rust")); + hello(&m); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-13/Cargo.lock b/listings/ch15-smart-pointers/listing-15-13/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-13/Cargo.toml b/listings/ch15-smart-pointers/listing-15-13/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-13/src/main.rs b/listings/ch15-smart-pointers/listing-15-13/src/main.rs new file mode 100755 index 0000000..ef5361c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-13/src/main.rs @@ -0,0 +1,28 @@ +use std::ops::Deref; + +impl Deref for MyBox { + type Target = T; + + fn deref(&self) -> &T { + &self.0 + } +} + +struct MyBox(T); + +impl MyBox { + fn new(x: T) -> MyBox { + MyBox(x) + } +} + +fn hello(name: &str) { + println!("Hello, {}!", name); +} + +// ANCHOR: here +fn main() { + let m = MyBox::new(String::from("Rust")); + hello(&(*m)[..]); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-14/Cargo.lock b/listings/ch15-smart-pointers/listing-15-14/Cargo.lock new file mode 100755 index 0000000..eb8a281 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "drop-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-14/Cargo.toml b/listings/ch15-smart-pointers/listing-15-14/Cargo.toml new file mode 100755 index 0000000..1e4c994 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "drop-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-14/output.txt b/listings/ch15-smart-pointers/listing-15-14/output.txt new file mode 100755 index 0000000..4e79594 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-14/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling drop-example v0.1.0 (file:///projects/drop-example) + Finished dev [unoptimized + debuginfo] target(s) in 0.60s + Running `target/debug/drop-example` +CustomSmartPointers created. +Dropping CustomSmartPointer with data `other stuff`! +Dropping CustomSmartPointer with data `my stuff`! diff --git a/listings/ch15-smart-pointers/listing-15-14/src/main.rs b/listings/ch15-smart-pointers/listing-15-14/src/main.rs new file mode 100755 index 0000000..231612a --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-14/src/main.rs @@ -0,0 +1,19 @@ +struct CustomSmartPointer { + data: String, +} + +impl Drop for CustomSmartPointer { + fn drop(&mut self) { + println!("Dropping CustomSmartPointer with data `{}`!", self.data); + } +} + +fn main() { + let c = CustomSmartPointer { + data: String::from("my stuff"), + }; + let d = CustomSmartPointer { + data: String::from("other stuff"), + }; + println!("CustomSmartPointers created."); +} diff --git a/listings/ch15-smart-pointers/listing-15-15/Cargo.lock b/listings/ch15-smart-pointers/listing-15-15/Cargo.lock new file mode 100755 index 0000000..eb8a281 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "drop-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-15/Cargo.toml b/listings/ch15-smart-pointers/listing-15-15/Cargo.toml new file mode 100755 index 0000000..1e4c994 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "drop-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-15/output.txt b/listings/ch15-smart-pointers/listing-15-15/output.txt new file mode 100755 index 0000000..a38c9cc --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/output.txt @@ -0,0 +1,13 @@ +$ cargo run + Compiling drop-example v0.1.0 (file:///projects/drop-example) +error[E0040]: explicit use of destructor method + --> src/main.rs:16:7 + | +16 | c.drop(); + | --^^^^-- + | | | + | | explicit destructor calls not allowed + | help: consider using `drop` function: `drop(c)` + +For more information about this error, try `rustc --explain E0040`. +error: could not compile `drop-example` due to previous error diff --git a/listings/ch15-smart-pointers/listing-15-15/src/main.rs b/listings/ch15-smart-pointers/listing-15-15/src/main.rs new file mode 100755 index 0000000..ff3b391 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/src/main.rs @@ -0,0 +1,20 @@ +struct CustomSmartPointer { + data: String, +} + +impl Drop for CustomSmartPointer { + fn drop(&mut self) { + println!("Dropping CustomSmartPointer with data `{}`!", self.data); + } +} + +// ANCHOR: here +fn main() { + let c = CustomSmartPointer { + data: String::from("some data"), + }; + println!("CustomSmartPointer created."); + c.drop(); + println!("CustomSmartPointer dropped before the end of main."); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-16/Cargo.lock b/listings/ch15-smart-pointers/listing-15-16/Cargo.lock new file mode 100755 index 0000000..eb8a281 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "drop-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-16/Cargo.toml b/listings/ch15-smart-pointers/listing-15-16/Cargo.toml new file mode 100755 index 0000000..1e4c994 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "drop-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-16/output.txt b/listings/ch15-smart-pointers/listing-15-16/output.txt new file mode 100755 index 0000000..e960cd8 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-16/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling drop-example v0.1.0 (file:///projects/drop-example) + Finished dev [unoptimized + debuginfo] target(s) in 0.73s + Running `target/debug/drop-example` +CustomSmartPointer created. +Dropping CustomSmartPointer with data `some data`! +CustomSmartPointer dropped before the end of main. diff --git a/listings/ch15-smart-pointers/listing-15-16/src/main.rs b/listings/ch15-smart-pointers/listing-15-16/src/main.rs new file mode 100755 index 0000000..f11715c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-16/src/main.rs @@ -0,0 +1,20 @@ +struct CustomSmartPointer { + data: String, +} + +impl Drop for CustomSmartPointer { + fn drop(&mut self) { + println!("Dropping CustomSmartPointer with data `{}`!", self.data); + } +} + +// ANCHOR: here +fn main() { + let c = CustomSmartPointer { + data: String::from("some data"), + }; + println!("CustomSmartPointer created."); + drop(c); + println!("CustomSmartPointer dropped before the end of main."); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-17/Cargo.lock b/listings/ch15-smart-pointers/listing-15-17/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-17/Cargo.toml b/listings/ch15-smart-pointers/listing-15-17/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-17/output.txt b/listings/ch15-smart-pointers/listing-15-17/output.txt new file mode 100755 index 0000000..ab314d8 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) +error[E0382]: use of moved value: `a` + --> src/main.rs:11:30 + | +9 | let a = Cons(5, Box::new(Cons(10, Box::new(Nil)))); + | - move occurs because `a` has type `List`, which does not implement the `Copy` trait +10 | let b = Cons(3, Box::new(a)); + | - value moved here +11 | let c = Cons(4, Box::new(a)); + | ^ value used here after move + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `cons-list` due to previous error diff --git a/listings/ch15-smart-pointers/listing-15-17/src/main.rs b/listings/ch15-smart-pointers/listing-15-17/src/main.rs new file mode 100755 index 0000000..47c33e4 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/src/main.rs @@ -0,0 +1,12 @@ +enum List { + Cons(i32, Box), + Nil, +} + +use crate::List::{Cons, Nil}; + +fn main() { + let a = Cons(5, Box::new(Cons(10, Box::new(Nil)))); + let b = Cons(3, Box::new(a)); + let c = Cons(4, Box::new(a)); +} diff --git a/listings/ch15-smart-pointers/listing-15-18/Cargo.lock b/listings/ch15-smart-pointers/listing-15-18/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-18/Cargo.toml b/listings/ch15-smart-pointers/listing-15-18/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-18/src/main.rs b/listings/ch15-smart-pointers/listing-15-18/src/main.rs new file mode 100755 index 0000000..602f7de --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-18/src/main.rs @@ -0,0 +1,13 @@ +enum List { + Cons(i32, Rc), + Nil, +} + +use crate::List::{Cons, Nil}; +use std::rc::Rc; + +fn main() { + let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); + let b = Cons(3, Rc::clone(&a)); + let c = Cons(4, Rc::clone(&a)); +} diff --git a/listings/ch15-smart-pointers/listing-15-19/Cargo.lock b/listings/ch15-smart-pointers/listing-15-19/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-19/Cargo.toml b/listings/ch15-smart-pointers/listing-15-19/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-19/output.txt b/listings/ch15-smart-pointers/listing-15-19/output.txt new file mode 100755 index 0000000..6a8cc8e --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-19/output.txt @@ -0,0 +1,8 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) + Finished dev [unoptimized + debuginfo] target(s) in 0.45s + Running `target/debug/cons-list` +count after creating a = 1 +count after creating b = 2 +count after creating c = 3 +count after c goes out of scope = 2 diff --git a/listings/ch15-smart-pointers/listing-15-19/src/main.rs b/listings/ch15-smart-pointers/listing-15-19/src/main.rs new file mode 100755 index 0000000..1bd7bc5 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-19/src/main.rs @@ -0,0 +1,21 @@ +enum List { + Cons(i32, Rc), + Nil, +} + +use crate::List::{Cons, Nil}; +use std::rc::Rc; + +// ANCHOR: here +fn main() { + let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); + println!("count after creating a = {}", Rc::strong_count(&a)); + let b = Cons(3, Rc::clone(&a)); + println!("count after creating b = {}", Rc::strong_count(&a)); + { + let c = Cons(4, Rc::clone(&a)); + println!("count after creating c = {}", Rc::strong_count(&a)); + } + println!("count after c goes out of scope = {}", Rc::strong_count(&a)); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-20/Cargo.lock b/listings/ch15-smart-pointers/listing-15-20/Cargo.lock new file mode 100755 index 0000000..4dc2226 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-20/Cargo.toml b/listings/ch15-smart-pointers/listing-15-20/Cargo.toml new file mode 100755 index 0000000..98c3f53 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-20/src/lib.rs b/listings/ch15-smart-pointers/listing-15-20/src/lib.rs new file mode 100755 index 0000000..d3a9003 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-20/src/lib.rs @@ -0,0 +1,38 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &T, max: usize) -> LimitTracker { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} diff --git a/listings/ch15-smart-pointers/listing-15-21/Cargo.lock b/listings/ch15-smart-pointers/listing-15-21/Cargo.lock new file mode 100755 index 0000000..4dc2226 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-21/Cargo.toml b/listings/ch15-smart-pointers/listing-15-21/Cargo.toml new file mode 100755 index 0000000..98c3f53 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-21/output.txt b/listings/ch15-smart-pointers/listing-15-21/output.txt new file mode 100755 index 0000000..91a928e --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/output.txt @@ -0,0 +1,15 @@ +$ cargo test + Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker) +error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a `&` reference + --> src/lib.rs:58:13 + | +2 | fn send(&self, msg: &str); + | ----- help: consider changing that to be a mutable reference: `&mut self` +... +58 | self.sent_messages.push(String::from(message)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + +For more information about this error, try `rustc --explain E0596`. +error: could not compile `limit-tracker` due to previous error +warning: build failed, waiting for other jobs to finish... +error: build failed diff --git a/listings/ch15-smart-pointers/listing-15-21/src/lib.rs b/listings/ch15-smart-pointers/listing-15-21/src/lib.rs new file mode 100755 index 0000000..9e403e3 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/src/lib.rs @@ -0,0 +1,73 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &T, max: usize) -> LimitTracker { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + + struct MockMessenger { + sent_messages: Vec, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { + sent_messages: vec![], + } + } + } + + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + self.sent_messages.push(String::from(message)); + } + } + + #[test] + fn it_sends_an_over_75_percent_warning_message() { + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + + assert_eq!(mock_messenger.sent_messages.len(), 1); + } +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-22/Cargo.lock b/listings/ch15-smart-pointers/listing-15-22/Cargo.lock new file mode 100755 index 0000000..4dc2226 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-22/Cargo.toml b/listings/ch15-smart-pointers/listing-15-22/Cargo.toml new file mode 100755 index 0000000..98c3f53 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-22/src/lib.rs b/listings/ch15-smart-pointers/listing-15-22/src/lib.rs new file mode 100755 index 0000000..539578e --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-22/src/lib.rs @@ -0,0 +1,78 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &T, max: usize) -> LimitTracker { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} + +// ANCHOR: here +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + + struct MockMessenger { + sent_messages: RefCell>, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { + sent_messages: RefCell::new(vec![]), + } + } + } + + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + self.sent_messages.borrow_mut().push(String::from(message)); + } + } + + #[test] + fn it_sends_an_over_75_percent_warning_message() { + // --snip-- + // ANCHOR_END: here + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + // ANCHOR: here + + // ANCHOR: here + assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); + } +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-23/Cargo.lock b/listings/ch15-smart-pointers/listing-15-23/Cargo.lock new file mode 100755 index 0000000..4dc2226 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "limit-tracker" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-23/Cargo.toml b/listings/ch15-smart-pointers/listing-15-23/Cargo.toml new file mode 100755 index 0000000..98c3f53 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-23/output.txt b/listings/ch15-smart-pointers/listing-15-23/output.txt new file mode 100755 index 0000000..22c2f79 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-23/output.txt @@ -0,0 +1,21 @@ +$ cargo test + Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker) + Finished test [unoptimized + debuginfo] target(s) in 0.91s + Running unittests (target/debug/deps/limit_tracker-e599811fa246dbde) + +running 1 test +test tests::it_sends_an_over_75_percent_warning_message ... FAILED + +failures: + +---- tests::it_sends_an_over_75_percent_warning_message stdout ---- +thread 'main' panicked at 'already borrowed: BorrowMutError', src/lib.rs:60:53 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + + +failures: + tests::it_sends_an_over_75_percent_warning_message + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +error: test failed, to rerun pass '--lib' diff --git a/listings/ch15-smart-pointers/listing-15-23/src/lib.rs b/listings/ch15-smart-pointers/listing-15-23/src/lib.rs new file mode 100755 index 0000000..4e599dd --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-23/src/lib.rs @@ -0,0 +1,78 @@ +pub trait Messenger { + fn send(&self, msg: &str); +} + +pub struct LimitTracker<'a, T: Messenger> { + messenger: &'a T, + value: usize, + max: usize, +} + +impl<'a, T> LimitTracker<'a, T> +where + T: Messenger, +{ + pub fn new(messenger: &T, max: usize) -> LimitTracker { + LimitTracker { + messenger, + value: 0, + max, + } + } + + pub fn set_value(&mut self, value: usize) { + self.value = value; + + let percentage_of_max = self.value as f64 / self.max as f64; + + if percentage_of_max >= 1.0 { + self.messenger.send("Error: You are over your quota!"); + } else if percentage_of_max >= 0.9 { + self.messenger + .send("Urgent warning: You've used up over 90% of your quota!"); + } else if percentage_of_max >= 0.75 { + self.messenger + .send("Warning: You've used up over 75% of your quota!"); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::cell::RefCell; + + struct MockMessenger { + sent_messages: RefCell>, + } + + impl MockMessenger { + fn new() -> MockMessenger { + MockMessenger { + sent_messages: RefCell::new(vec![]), + } + } + } + + // ANCHOR: here + impl Messenger for MockMessenger { + fn send(&self, message: &str) { + let mut one_borrow = self.sent_messages.borrow_mut(); + let mut two_borrow = self.sent_messages.borrow_mut(); + + one_borrow.push(String::from(message)); + two_borrow.push(String::from(message)); + } + } + // ANCHOR_END: here + + #[test] + fn it_sends_an_over_75_percent_warning_message() { + let mock_messenger = MockMessenger::new(); + let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); + + limit_tracker.set_value(80); + + assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); + } +} diff --git a/listings/ch15-smart-pointers/listing-15-24/Cargo.lock b/listings/ch15-smart-pointers/listing-15-24/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-24/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-24/Cargo.toml b/listings/ch15-smart-pointers/listing-15-24/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-24/output.txt b/listings/ch15-smart-pointers/listing-15-24/output.txt new file mode 100755 index 0000000..21b3530 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-24/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) + Finished dev [unoptimized + debuginfo] target(s) in 0.63s + Running `target/debug/cons-list` +a after = Cons(RefCell { value: 15 }, Nil) +b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil)) +c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil)) diff --git a/listings/ch15-smart-pointers/listing-15-24/src/main.rs b/listings/ch15-smart-pointers/listing-15-24/src/main.rs new file mode 100755 index 0000000..e225bd8 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-24/src/main.rs @@ -0,0 +1,24 @@ +#[derive(Debug)] +enum List { + Cons(Rc>, Rc), + Nil, +} + +use crate::List::{Cons, Nil}; +use std::cell::RefCell; +use std::rc::Rc; + +fn main() { + let value = Rc::new(RefCell::new(5)); + + let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); + + let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a)); + let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a)); + + *value.borrow_mut() += 10; + + println!("a after = {:?}", a); + println!("b after = {:?}", b); + println!("c after = {:?}", c); +} diff --git a/listings/ch15-smart-pointers/listing-15-25/Cargo.lock b/listings/ch15-smart-pointers/listing-15-25/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-25/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-25/Cargo.toml b/listings/ch15-smart-pointers/listing-15-25/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-25/src/main.rs b/listings/ch15-smart-pointers/listing-15-25/src/main.rs new file mode 100755 index 0000000..f36c7fd --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-25/src/main.rs @@ -0,0 +1,20 @@ +use crate::List::{Cons, Nil}; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Debug)] +enum List { + Cons(i32, RefCell>), + Nil, +} + +impl List { + fn tail(&self) -> Option<&RefCell>> { + match self { + Cons(_, item) => Some(item), + Nil => None, + } + } +} + +fn main() {} diff --git a/listings/ch15-smart-pointers/listing-15-26/Cargo.lock b/listings/ch15-smart-pointers/listing-15-26/Cargo.lock new file mode 100755 index 0000000..a792c49 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-26/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "cons-list" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-26/Cargo.toml b/listings/ch15-smart-pointers/listing-15-26/Cargo.toml new file mode 100755 index 0000000..dce1515 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-26/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "cons-list" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-26/output.txt b/listings/ch15-smart-pointers/listing-15-26/output.txt new file mode 100755 index 0000000..8b8eb40 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-26/output.txt @@ -0,0 +1,11 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) + Finished dev [unoptimized + debuginfo] target(s) in 0.53s + Running `target/debug/cons-list` +a initial rc count = 1 +a next item = Some(RefCell { value: Nil }) +a rc count after b creation = 2 +b initial rc count = 1 +b next item = Some(RefCell { value: Cons(5, RefCell { value: Nil }) }) +b rc count after changing a = 2 +a rc count after changing a = 2 diff --git a/listings/ch15-smart-pointers/listing-15-26/src/main.rs b/listings/ch15-smart-pointers/listing-15-26/src/main.rs new file mode 100755 index 0000000..08963aa --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-26/src/main.rs @@ -0,0 +1,44 @@ +use crate::List::{Cons, Nil}; +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Debug)] +enum List { + Cons(i32, RefCell>), + Nil, +} + +impl List { + fn tail(&self) -> Option<&RefCell>> { + match self { + Cons(_, item) => Some(item), + Nil => None, + } + } +} + +// ANCHOR: here +fn main() { + let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil)))); + + println!("a initial rc count = {}", Rc::strong_count(&a)); + println!("a next item = {:?}", a.tail()); + + let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a)))); + + println!("a rc count after b creation = {}", Rc::strong_count(&a)); + println!("b initial rc count = {}", Rc::strong_count(&b)); + println!("b next item = {:?}", b.tail()); + + if let Some(link) = a.tail() { + *link.borrow_mut() = Rc::clone(&b); + } + + println!("b rc count after changing a = {}", Rc::strong_count(&b)); + println!("a rc count after changing a = {}", Rc::strong_count(&a)); + + // Uncomment the next line to see that we have a cycle; + // it will overflow the stack + // println!("a next item = {:?}", a.tail()); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/listing-15-27/Cargo.lock b/listings/ch15-smart-pointers/listing-15-27/Cargo.lock new file mode 100755 index 0000000..dd1f00a --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-27/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tree" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-27/Cargo.toml b/listings/ch15-smart-pointers/listing-15-27/Cargo.toml new file mode 100755 index 0000000..0bbf897 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-27/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tree" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-27/src/main.rs b/listings/ch15-smart-pointers/listing-15-27/src/main.rs new file mode 100755 index 0000000..335d154 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-27/src/main.rs @@ -0,0 +1,24 @@ +// ANCHOR: here +use std::cell::RefCell; +use std::rc::Rc; + +#[derive(Debug)] +struct Node { + value: i32, + children: RefCell>>, +} +// ANCHOR_END: here + +// ANCHOR: there +fn main() { + let leaf = Rc::new(Node { + value: 3, + children: RefCell::new(vec![]), + }); + + let branch = Rc::new(Node { + value: 5, + children: RefCell::new(vec![Rc::clone(&leaf)]), + }); +} +// ANCHOR_END: there diff --git a/listings/ch15-smart-pointers/listing-15-28/Cargo.lock b/listings/ch15-smart-pointers/listing-15-28/Cargo.lock new file mode 100755 index 0000000..dd1f00a --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-28/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tree" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-28/Cargo.toml b/listings/ch15-smart-pointers/listing-15-28/Cargo.toml new file mode 100755 index 0000000..0bbf897 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-28/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tree" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-28/src/main.rs b/listings/ch15-smart-pointers/listing-15-28/src/main.rs new file mode 100755 index 0000000..fabd1cb --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-28/src/main.rs @@ -0,0 +1,33 @@ +// ANCHOR: here +use std::cell::RefCell; +use std::rc::{Rc, Weak}; + +#[derive(Debug)] +struct Node { + value: i32, + parent: RefCell>, + children: RefCell>>, +} +// ANCHOR_END: here + +// ANCHOR: there +fn main() { + let leaf = Rc::new(Node { + value: 3, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![]), + }); + + println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); + + let branch = Rc::new(Node { + value: 5, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![Rc::clone(&leaf)]), + }); + + *leaf.parent.borrow_mut() = Rc::downgrade(&branch); + + println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); +} +// ANCHOR_END: there diff --git a/listings/ch15-smart-pointers/listing-15-29/Cargo.lock b/listings/ch15-smart-pointers/listing-15-29/Cargo.lock new file mode 100755 index 0000000..dd1f00a --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-29/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "tree" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/listing-15-29/Cargo.toml b/listings/ch15-smart-pointers/listing-15-29/Cargo.toml new file mode 100755 index 0000000..0bbf897 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-29/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "tree" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/listing-15-29/src/main.rs b/listings/ch15-smart-pointers/listing-15-29/src/main.rs new file mode 100755 index 0000000..ea13df0 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-29/src/main.rs @@ -0,0 +1,54 @@ +use std::cell::RefCell; +use std::rc::{Rc, Weak}; + +#[derive(Debug)] +struct Node { + value: i32, + parent: RefCell>, + children: RefCell>>, +} + +// ANCHOR: here +fn main() { + let leaf = Rc::new(Node { + value: 3, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![]), + }); + + println!( + "leaf strong = {}, weak = {}", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); + + { + let branch = Rc::new(Node { + value: 5, + parent: RefCell::new(Weak::new()), + children: RefCell::new(vec![Rc::clone(&leaf)]), + }); + + *leaf.parent.borrow_mut() = Rc::downgrade(&branch); + + println!( + "branch strong = {}, weak = {}", + Rc::strong_count(&branch), + Rc::weak_count(&branch), + ); + + println!( + "leaf strong = {}, weak = {}", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); + } + + println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); + println!( + "leaf strong = {}, weak = {}", + Rc::strong_count(&leaf), + Rc::weak_count(&leaf), + ); +} +// ANCHOR_END: here diff --git a/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock new file mode 100755 index 0000000..340f660 --- /dev/null +++ b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "borrowing" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml new file mode 100755 index 0000000..16f9244 --- /dev/null +++ b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "borrowing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt new file mode 100755 index 0000000..8e84746 --- /dev/null +++ b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling borrowing v0.1.0 (file:///projects/borrowing) +error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable + --> src/main.rs:3:13 + | +2 | let x = 5; + | - help: consider changing this to be mutable: `mut x` +3 | let y = &mut x; + | ^^^^^^ cannot borrow as mutable + +For more information about this error, try `rustc --explain E0596`. +error: could not compile `borrowing` due to previous error diff --git a/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs new file mode 100755 index 0000000..8f48d41 --- /dev/null +++ b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + let x = 5; + let y = &mut x; +} diff --git a/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock new file mode 100755 index 0000000..4297c67 --- /dev/null +++ b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "deref-example" +version = "0.1.0" + diff --git a/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml new file mode 100755 index 0000000..67ec198 --- /dev/null +++ b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "deref-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt new file mode 100755 index 0000000..ed54370 --- /dev/null +++ b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt @@ -0,0 +1,13 @@ +$ cargo run + Compiling deref-example v0.1.0 (file:///projects/deref-example) +error[E0277]: can't compare `{integer}` with `&{integer}` + --> src/main.rs:6:5 + | +6 | assert_eq!(5, y); + | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}` + | + = help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}` + = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `deref-example` due to previous error diff --git a/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs new file mode 100755 index 0000000..4e20cae --- /dev/null +++ b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + let x = 5; + let y = &x; + + assert_eq!(5, x); + assert_eq!(5, y); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-01/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-01/Cargo.lock new file mode 100755 index 0000000..8ecc3ae --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "threads" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-01/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-01/Cargo.toml new file mode 100755 index 0000000..bd4edf7 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "threads" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-01/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-01/src/main.rs new file mode 100755 index 0000000..6305a98 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-01/src/main.rs @@ -0,0 +1,16 @@ +use std::thread; +use std::time::Duration; + +fn main() { + thread::spawn(|| { + for i in 1..10 { + println!("hi number {} from the spawned thread!", i); + thread::sleep(Duration::from_millis(1)); + } + }); + + for i in 1..5 { + println!("hi number {} from the main thread!", i); + thread::sleep(Duration::from_millis(1)); + } +} diff --git a/listings/ch16-fearless-concurrency/listing-16-02/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-02/Cargo.lock new file mode 100755 index 0000000..8ecc3ae --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "threads" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-02/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-02/Cargo.toml new file mode 100755 index 0000000..bd4edf7 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "threads" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-02/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-02/src/main.rs new file mode 100755 index 0000000..e37607f --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-02/src/main.rs @@ -0,0 +1,18 @@ +use std::thread; +use std::time::Duration; + +fn main() { + let handle = thread::spawn(|| { + for i in 1..10 { + println!("hi number {} from the spawned thread!", i); + thread::sleep(Duration::from_millis(1)); + } + }); + + for i in 1..5 { + println!("hi number {} from the main thread!", i); + thread::sleep(Duration::from_millis(1)); + } + + handle.join().unwrap(); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-03/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-03/Cargo.lock new file mode 100755 index 0000000..8ecc3ae --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "threads" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-03/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-03/Cargo.toml new file mode 100755 index 0000000..bd4edf7 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "threads" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-03/output.txt b/listings/ch16-fearless-concurrency/listing-16-03/output.txt new file mode 100755 index 0000000..321bf59 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-03/output.txt @@ -0,0 +1,25 @@ +$ cargo run + Compiling threads v0.1.0 (file:///projects/threads) +error[E0373]: closure may outlive the current function, but it borrows `v`, which is owned by the current function + --> src/main.rs:6:32 + | +6 | let handle = thread::spawn(|| { + | ^^ may outlive borrowed value `v` +7 | println!("Here's a vector: {:?}", v); + | - `v` is borrowed here + | +note: function requires argument type to outlive `'static` + --> src/main.rs:6:18 + | +6 | let handle = thread::spawn(|| { + | __________________^ +7 | | println!("Here's a vector: {:?}", v); +8 | | }); + | |______^ +help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword + | +6 | let handle = thread::spawn(move || { + | ++++ + +For more information about this error, try `rustc --explain E0373`. +error: could not compile `threads` due to previous error diff --git a/listings/ch16-fearless-concurrency/listing-16-03/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-03/src/main.rs new file mode 100755 index 0000000..defc876 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-03/src/main.rs @@ -0,0 +1,11 @@ +use std::thread; + +fn main() { + let v = vec![1, 2, 3]; + + let handle = thread::spawn(|| { + println!("Here's a vector: {:?}", v); + }); + + handle.join().unwrap(); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-04/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-04/Cargo.lock new file mode 100755 index 0000000..8ecc3ae --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "threads" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-04/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-04/Cargo.toml new file mode 100755 index 0000000..bd4edf7 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "threads" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-04/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-04/src/main.rs new file mode 100755 index 0000000..0bccc5f --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-04/src/main.rs @@ -0,0 +1,13 @@ +use std::thread; + +fn main() { + let v = vec![1, 2, 3]; + + let handle = thread::spawn(|| { + println!("Here's a vector: {:?}", v); + }); + + drop(v); // oh no! + + handle.join().unwrap(); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-05/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-05/Cargo.lock new file mode 100755 index 0000000..8ecc3ae --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "threads" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-05/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-05/Cargo.toml new file mode 100755 index 0000000..bd4edf7 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "threads" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-05/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-05/src/main.rs new file mode 100755 index 0000000..a6547dc --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-05/src/main.rs @@ -0,0 +1,11 @@ +use std::thread; + +fn main() { + let v = vec![1, 2, 3]; + + let handle = thread::spawn(move || { + println!("Here's a vector: {:?}", v); + }); + + handle.join().unwrap(); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-06/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-06/Cargo.lock new file mode 100755 index 0000000..55d2252 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "message-passing" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-06/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-06/Cargo.toml new file mode 100755 index 0000000..24bd2ee --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "message-passing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-06/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-06/src/main.rs new file mode 100755 index 0000000..d80dac4 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-06/src/main.rs @@ -0,0 +1,5 @@ +use std::sync::mpsc; + +fn main() { + let (tx, rx) = mpsc::channel(); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-07/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-07/Cargo.lock new file mode 100755 index 0000000..55d2252 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "message-passing" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-07/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-07/Cargo.toml new file mode 100755 index 0000000..24bd2ee --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "message-passing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-07/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-07/src/main.rs new file mode 100755 index 0000000..7859b64 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-07/src/main.rs @@ -0,0 +1,11 @@ +use std::sync::mpsc; +use std::thread; + +fn main() { + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || { + let val = String::from("hi"); + tx.send(val).unwrap(); + }); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-08/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-08/Cargo.lock new file mode 100755 index 0000000..55d2252 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "message-passing" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-08/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-08/Cargo.toml new file mode 100755 index 0000000..24bd2ee --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "message-passing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-08/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-08/src/main.rs new file mode 100755 index 0000000..fbba916 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-08/src/main.rs @@ -0,0 +1,14 @@ +use std::sync::mpsc; +use std::thread; + +fn main() { + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || { + let val = String::from("hi"); + tx.send(val).unwrap(); + }); + + let received = rx.recv().unwrap(); + println!("Got: {}", received); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-09/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-09/Cargo.lock new file mode 100755 index 0000000..55d2252 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "message-passing" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-09/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-09/Cargo.toml new file mode 100755 index 0000000..24bd2ee --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "message-passing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-09/output.txt b/listings/ch16-fearless-concurrency/listing-16-09/output.txt new file mode 100755 index 0000000..bb2639d --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling message-passing v0.1.0 (file:///projects/message-passing) +error[E0382]: borrow of moved value: `val` + --> src/main.rs:10:31 + | +8 | let val = String::from("hi"); + | --- move occurs because `val` has type `String`, which does not implement the `Copy` trait +9 | tx.send(val).unwrap(); + | --- value moved here +10 | println!("val is {}", val); + | ^^^ value borrowed here after move + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `message-passing` due to previous error diff --git a/listings/ch16-fearless-concurrency/listing-16-09/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-09/src/main.rs new file mode 100755 index 0000000..98a8129 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/src/main.rs @@ -0,0 +1,15 @@ +use std::sync::mpsc; +use std::thread; + +fn main() { + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || { + let val = String::from("hi"); + tx.send(val).unwrap(); + println!("val is {}", val); + }); + + let received = rx.recv().unwrap(); + println!("Got: {}", received); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-10/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-10/Cargo.lock new file mode 100755 index 0000000..55d2252 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "message-passing" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-10/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-10/Cargo.toml new file mode 100755 index 0000000..24bd2ee --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "message-passing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-10/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-10/src/main.rs new file mode 100755 index 0000000..82b220d --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-10/src/main.rs @@ -0,0 +1,25 @@ +use std::sync::mpsc; +use std::thread; +use std::time::Duration; + +fn main() { + let (tx, rx) = mpsc::channel(); + + thread::spawn(move || { + let vals = vec![ + String::from("hi"), + String::from("from"), + String::from("the"), + String::from("thread"), + ]; + + for val in vals { + tx.send(val).unwrap(); + thread::sleep(Duration::from_secs(1)); + } + }); + + for received in rx { + println!("Got: {}", received); + } +} diff --git a/listings/ch16-fearless-concurrency/listing-16-11/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-11/Cargo.lock new file mode 100755 index 0000000..55d2252 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "message-passing" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-11/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-11/Cargo.toml new file mode 100755 index 0000000..24bd2ee --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "message-passing" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-11/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-11/src/main.rs new file mode 100755 index 0000000..d92deab --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-11/src/main.rs @@ -0,0 +1,46 @@ +use std::sync::mpsc; +use std::thread; +use std::time::Duration; + +fn main() { + // ANCHOR: here + // --snip-- + + let (tx, rx) = mpsc::channel(); + + let tx1 = tx.clone(); + thread::spawn(move || { + let vals = vec![ + String::from("hi"), + String::from("from"), + String::from("the"), + String::from("thread"), + ]; + + for val in vals { + tx1.send(val).unwrap(); + thread::sleep(Duration::from_secs(1)); + } + }); + + thread::spawn(move || { + let vals = vec![ + String::from("more"), + String::from("messages"), + String::from("for"), + String::from("you"), + ]; + + for val in vals { + tx.send(val).unwrap(); + thread::sleep(Duration::from_secs(1)); + } + }); + + for received in rx { + println!("Got: {}", received); + } + + // --snip-- + // ANCHOR_END: here +} diff --git a/listings/ch16-fearless-concurrency/listing-16-12/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-12/Cargo.lock new file mode 100755 index 0000000..8e7ba9c --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "shared-state" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-12/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-12/Cargo.toml new file mode 100755 index 0000000..da297ea --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "shared-state" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-12/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-12/src/main.rs new file mode 100755 index 0000000..0c0d676 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-12/src/main.rs @@ -0,0 +1,12 @@ +use std::sync::Mutex; + +fn main() { + let m = Mutex::new(5); + + { + let mut num = m.lock().unwrap(); + *num = 6; + } + + println!("m = {:?}", m); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-13/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-13/Cargo.lock new file mode 100755 index 0000000..8e7ba9c --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "shared-state" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-13/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-13/Cargo.toml new file mode 100755 index 0000000..da297ea --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "shared-state" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-13/output.txt b/listings/ch16-fearless-concurrency/listing-16-13/output.txt new file mode 100755 index 0000000..ea69639 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-13/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling shared-state v0.1.0 (file:///projects/shared-state) +error[E0382]: use of moved value: `counter` + --> src/main.rs:9:36 + | +5 | let counter = Mutex::new(0); + | ------- move occurs because `counter` has type `Mutex`, which does not implement the `Copy` trait +... +9 | let handle = thread::spawn(move || { + | ^^^^^^^ value moved into closure here, in previous iteration of loop +10 | let mut num = counter.lock().unwrap(); + | ------- use occurs due to use in closure + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `shared-state` due to previous error diff --git a/listings/ch16-fearless-concurrency/listing-16-13/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-13/src/main.rs new file mode 100755 index 0000000..4e380a5 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-13/src/main.rs @@ -0,0 +1,22 @@ +use std::sync::Mutex; +use std::thread; + +fn main() { + let counter = Mutex::new(0); + let mut handles = vec![]; + + for _ in 0..10 { + let handle = thread::spawn(move || { + let mut num = counter.lock().unwrap(); + + *num += 1; + }); + handles.push(handle); + } + + for handle in handles { + handle.join().unwrap(); + } + + println!("Result: {}", *counter.lock().unwrap()); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-14/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-14/Cargo.lock new file mode 100755 index 0000000..8e7ba9c --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "shared-state" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-14/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-14/Cargo.toml new file mode 100755 index 0000000..da297ea --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "shared-state" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-14/output.txt b/listings/ch16-fearless-concurrency/listing-16-14/output.txt new file mode 100755 index 0000000..9546e1e --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-14/output.txt @@ -0,0 +1,21 @@ +$ cargo run + Compiling shared-state v0.1.0 (file:///projects/shared-state) +error[E0277]: `Rc>` cannot be sent between threads safely + --> src/main.rs:11:22 + | +11 | let handle = thread::spawn(move || { + | ______________________^^^^^^^^^^^^^_- + | | | + | | `Rc>` cannot be sent between threads safely +12 | | let mut num = counter.lock().unwrap(); +13 | | +14 | | *num += 1; +15 | | }); + | |_________- within this `[closure@src/main.rs:11:36: 15:10]` + | + = help: within `[closure@src/main.rs:11:36: 15:10]`, the trait `Send` is not implemented for `Rc>` + = note: required because it appears within the type `[closure@src/main.rs:11:36: 15:10]` +note: required by a bound in `spawn` + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `shared-state` due to previous error diff --git a/listings/ch16-fearless-concurrency/listing-16-14/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-14/src/main.rs new file mode 100755 index 0000000..d940b1a --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-14/src/main.rs @@ -0,0 +1,24 @@ +use std::rc::Rc; +use std::sync::Mutex; +use std::thread; + +fn main() { + let counter = Rc::new(Mutex::new(0)); + let mut handles = vec![]; + + for _ in 0..10 { + let counter = Rc::clone(&counter); + let handle = thread::spawn(move || { + let mut num = counter.lock().unwrap(); + + *num += 1; + }); + handles.push(handle); + } + + for handle in handles { + handle.join().unwrap(); + } + + println!("Result: {}", *counter.lock().unwrap()); +} diff --git a/listings/ch16-fearless-concurrency/listing-16-15/Cargo.lock b/listings/ch16-fearless-concurrency/listing-16-15/Cargo.lock new file mode 100755 index 0000000..8e7ba9c --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "shared-state" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/listing-16-15/Cargo.toml b/listings/ch16-fearless-concurrency/listing-16-15/Cargo.toml new file mode 100755 index 0000000..da297ea --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "shared-state" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/listing-16-15/src/main.rs b/listings/ch16-fearless-concurrency/listing-16-15/src/main.rs new file mode 100755 index 0000000..30247dd --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-15/src/main.rs @@ -0,0 +1,23 @@ +use std::sync::{Arc, Mutex}; +use std::thread; + +fn main() { + let counter = Arc::new(Mutex::new(0)); + let mut handles = vec![]; + + for _ in 0..10 { + let counter = Arc::clone(&counter); + let handle = thread::spawn(move || { + let mut num = counter.lock().unwrap(); + + *num += 1; + }); + handles.push(handle); + } + + for handle in handles { + handle.join().unwrap(); + } + + println!("Result: {}", *counter.lock().unwrap()); +} diff --git a/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.lock b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.lock new file mode 100755 index 0000000..8ecc3ae --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "threads" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.toml b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.toml new file mode 100755 index 0000000..bd4edf7 --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "threads" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs new file mode 100755 index 0000000..6205e57 --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs @@ -0,0 +1,18 @@ +use std::thread; +use std::time::Duration; + +fn main() { + let handle = thread::spawn(|| { + for i in 1..10 { + println!("hi number {} from the spawned thread!", i); + thread::sleep(Duration::from_millis(1)); + } + }); + + handle.join().unwrap(); + + for i in 1..5 { + println!("hi number {} from the main thread!", i); + thread::sleep(Duration::from_millis(1)); + } +} diff --git a/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.lock b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.lock new file mode 100755 index 0000000..8e7ba9c --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "shared-state" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.toml b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.toml new file mode 100755 index 0000000..da297ea --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "shared-state" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/src/main.rs b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/src/main.rs new file mode 100755 index 0000000..dbb1397 --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/src/main.rs @@ -0,0 +1,27 @@ +use std::sync::Mutex; +use std::thread; + +fn main() { + let counter = Mutex::new(0); + let mut handles = vec![]; + + let handle = thread::spawn(move || { + let mut num = counter.lock().unwrap(); + + *num += 1; + }); + handles.push(handle); + + let handle2 = thread::spawn(move || { + let mut num2 = counter.lock().unwrap(); + + *num2 += 1; + }); + handles.push(handle2); + + for handle in handles { + handle.join().unwrap(); + } + + println!("Result: {}", *counter.lock().unwrap()); +} diff --git a/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.lock b/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.lock new file mode 100755 index 0000000..8ecc3ae --- /dev/null +++ b/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "threads" +version = "0.1.0" + diff --git a/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.toml b/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.toml new file mode 100755 index 0000000..bd4edf7 --- /dev/null +++ b/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "threads" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt b/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt new file mode 100755 index 0000000..f7be53b --- /dev/null +++ b/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt @@ -0,0 +1,18 @@ +$ cargo run + Compiling threads v0.1.0 (file:///projects/threads) +error[E0382]: use of moved value: `v` + --> src/main.rs:10:10 + | +4 | let v = vec![1, 2, 3]; + | - move occurs because `v` has type `Vec`, which does not implement the `Copy` trait +5 | +6 | let handle = thread::spawn(move || { + | ------- value moved into closure here +7 | println!("Here's a vector: {:?}", v); + | - variable moved due to use in closure +... +10 | drop(v); // oh no! + | ^ value used here after move + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `threads` due to previous error diff --git a/listings/ch16-fearless-concurrency/output-only-01-move-drop/src/main.rs b/listings/ch16-fearless-concurrency/output-only-01-move-drop/src/main.rs new file mode 100755 index 0000000..70f659c --- /dev/null +++ b/listings/ch16-fearless-concurrency/output-only-01-move-drop/src/main.rs @@ -0,0 +1,13 @@ +use std::thread; + +fn main() { + let v = vec![1, 2, 3]; + + let handle = thread::spawn(move || { + println!("Here's a vector: {:?}", v); + }); + + drop(v); // oh no! + + handle.join().unwrap(); +} diff --git a/listings/ch17-oop/listing-17-01/Cargo.lock b/listings/ch17-oop/listing-17-01/Cargo.lock new file mode 100755 index 0000000..471d8df --- /dev/null +++ b/listings/ch17-oop/listing-17-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "averaged-collection" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-01/Cargo.toml b/listings/ch17-oop/listing-17-01/Cargo.toml new file mode 100755 index 0000000..aed614e --- /dev/null +++ b/listings/ch17-oop/listing-17-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "averaged-collection" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-01/src/lib.rs b/listings/ch17-oop/listing-17-01/src/lib.rs new file mode 100755 index 0000000..b5ce2ab --- /dev/null +++ b/listings/ch17-oop/listing-17-01/src/lib.rs @@ -0,0 +1,4 @@ +pub struct AveragedCollection { + list: Vec, + average: f64, +} diff --git a/listings/ch17-oop/listing-17-02/Cargo.lock b/listings/ch17-oop/listing-17-02/Cargo.lock new file mode 100755 index 0000000..471d8df --- /dev/null +++ b/listings/ch17-oop/listing-17-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "averaged-collection" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-02/Cargo.toml b/listings/ch17-oop/listing-17-02/Cargo.toml new file mode 100755 index 0000000..aed614e --- /dev/null +++ b/listings/ch17-oop/listing-17-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "averaged-collection" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-02/src/lib.rs b/listings/ch17-oop/listing-17-02/src/lib.rs new file mode 100755 index 0000000..bb407ec --- /dev/null +++ b/listings/ch17-oop/listing-17-02/src/lib.rs @@ -0,0 +1,33 @@ +pub struct AveragedCollection { + list: Vec, + average: f64, +} + +// ANCHOR: here +impl AveragedCollection { + pub fn add(&mut self, value: i32) { + self.list.push(value); + self.update_average(); + } + + pub fn remove(&mut self) -> Option { + let result = self.list.pop(); + match result { + Some(value) => { + self.update_average(); + Some(value) + } + None => None, + } + } + + pub fn average(&self) -> f64 { + self.average + } + + fn update_average(&mut self) { + let total: i32 = self.list.iter().sum(); + self.average = total as f64 / self.list.len() as f64; + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-03/Cargo.lock b/listings/ch17-oop/listing-17-03/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-03/Cargo.toml b/listings/ch17-oop/listing-17-03/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-03/src/lib.rs b/listings/ch17-oop/listing-17-03/src/lib.rs new file mode 100755 index 0000000..3a5cb77 --- /dev/null +++ b/listings/ch17-oop/listing-17-03/src/lib.rs @@ -0,0 +1,3 @@ +pub trait Draw { + fn draw(&self); +} diff --git a/listings/ch17-oop/listing-17-04/Cargo.lock b/listings/ch17-oop/listing-17-04/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-04/Cargo.toml b/listings/ch17-oop/listing-17-04/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-04/src/lib.rs b/listings/ch17-oop/listing-17-04/src/lib.rs new file mode 100755 index 0000000..0c45e2a --- /dev/null +++ b/listings/ch17-oop/listing-17-04/src/lib.rs @@ -0,0 +1,9 @@ +pub trait Draw { + fn draw(&self); +} + +// ANCHOR: here +pub struct Screen { + pub components: Vec>, +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-05/Cargo.lock b/listings/ch17-oop/listing-17-05/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-05/Cargo.toml b/listings/ch17-oop/listing-17-05/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-05/src/lib.rs b/listings/ch17-oop/listing-17-05/src/lib.rs new file mode 100755 index 0000000..57ebb57 --- /dev/null +++ b/listings/ch17-oop/listing-17-05/src/lib.rs @@ -0,0 +1,17 @@ +pub trait Draw { + fn draw(&self); +} + +pub struct Screen { + pub components: Vec>, +} + +// ANCHOR: here +impl Screen { + pub fn run(&self) { + for component in self.components.iter() { + component.draw(); + } + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-06/Cargo.lock b/listings/ch17-oop/listing-17-06/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-06/Cargo.toml b/listings/ch17-oop/listing-17-06/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-06/src/lib.rs b/listings/ch17-oop/listing-17-06/src/lib.rs new file mode 100755 index 0000000..63a8907 --- /dev/null +++ b/listings/ch17-oop/listing-17-06/src/lib.rs @@ -0,0 +1,20 @@ +pub trait Draw { + fn draw(&self); +} + +// ANCHOR: here +pub struct Screen { + pub components: Vec, +} + +impl Screen +where + T: Draw, +{ + pub fn run(&self) { + for component in self.components.iter() { + component.draw(); + } + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-07/Cargo.lock b/listings/ch17-oop/listing-17-07/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-07/Cargo.toml b/listings/ch17-oop/listing-17-07/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-07/src/lib.rs b/listings/ch17-oop/listing-17-07/src/lib.rs new file mode 100755 index 0000000..b16cd01 --- /dev/null +++ b/listings/ch17-oop/listing-17-07/src/lib.rs @@ -0,0 +1,29 @@ +pub trait Draw { + fn draw(&self); +} + +pub struct Screen { + pub components: Vec>, +} + +impl Screen { + pub fn run(&self) { + for component in self.components.iter() { + component.draw(); + } + } +} + +// ANCHOR: here +pub struct Button { + pub width: u32, + pub height: u32, + pub label: String, +} + +impl Draw for Button { + fn draw(&self) { + // code to actually draw a button + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-08/Cargo.lock b/listings/ch17-oop/listing-17-08/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-08/Cargo.toml b/listings/ch17-oop/listing-17-08/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-08/src/lib.rs b/listings/ch17-oop/listing-17-08/src/lib.rs new file mode 100755 index 0000000..960fee2 --- /dev/null +++ b/listings/ch17-oop/listing-17-08/src/lib.rs @@ -0,0 +1,27 @@ +pub trait Draw { + fn draw(&self); +} + +pub struct Screen { + pub components: Vec>, +} + +impl Screen { + pub fn run(&self) { + for component in self.components.iter() { + component.draw(); + } + } +} + +pub struct Button { + pub width: u32, + pub height: u32, + pub label: String, +} + +impl Draw for Button { + fn draw(&self) { + // code to actually draw a button + } +} diff --git a/listings/ch17-oop/listing-17-08/src/main.rs b/listings/ch17-oop/listing-17-08/src/main.rs new file mode 100755 index 0000000..9575d40 --- /dev/null +++ b/listings/ch17-oop/listing-17-08/src/main.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +use gui::Draw; + +struct SelectBox { + width: u32, + height: u32, + options: Vec, +} + +impl Draw for SelectBox { + fn draw(&self) { + // code to actually draw a select box + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch17-oop/listing-17-09/Cargo.lock b/listings/ch17-oop/listing-17-09/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-09/Cargo.toml b/listings/ch17-oop/listing-17-09/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-09/src/lib.rs b/listings/ch17-oop/listing-17-09/src/lib.rs new file mode 100755 index 0000000..960fee2 --- /dev/null +++ b/listings/ch17-oop/listing-17-09/src/lib.rs @@ -0,0 +1,27 @@ +pub trait Draw { + fn draw(&self); +} + +pub struct Screen { + pub components: Vec>, +} + +impl Screen { + pub fn run(&self) { + for component in self.components.iter() { + component.draw(); + } + } +} + +pub struct Button { + pub width: u32, + pub height: u32, + pub label: String, +} + +impl Draw for Button { + fn draw(&self) { + // code to actually draw a button + } +} diff --git a/listings/ch17-oop/listing-17-09/src/main.rs b/listings/ch17-oop/listing-17-09/src/main.rs new file mode 100755 index 0000000..4eb13f6 --- /dev/null +++ b/listings/ch17-oop/listing-17-09/src/main.rs @@ -0,0 +1,40 @@ +use gui::Draw; + +struct SelectBox { + width: u32, + height: u32, + options: Vec, +} + +impl Draw for SelectBox { + fn draw(&self) { + // code to actually draw a select box + } +} + +// ANCHOR: here +use gui::{Button, Screen}; + +fn main() { + let screen = Screen { + components: vec![ + Box::new(SelectBox { + width: 75, + height: 10, + options: vec![ + String::from("Yes"), + String::from("Maybe"), + String::from("No"), + ], + }), + Box::new(Button { + width: 50, + height: 10, + label: String::from("OK"), + }), + ], + }; + + screen.run(); +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-10/Cargo.lock b/listings/ch17-oop/listing-17-10/Cargo.lock new file mode 100755 index 0000000..00d7b21 --- /dev/null +++ b/listings/ch17-oop/listing-17-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-10/Cargo.toml b/listings/ch17-oop/listing-17-10/Cargo.toml new file mode 100755 index 0000000..9b816e7 --- /dev/null +++ b/listings/ch17-oop/listing-17-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "gui" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-10/output.txt b/listings/ch17-oop/listing-17-10/output.txt new file mode 100755 index 0000000..4015577 --- /dev/null +++ b/listings/ch17-oop/listing-17-10/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling gui v0.1.0 (file:///projects/gui) +error[E0277]: the trait bound `String: Draw` is not satisfied + --> src/main.rs:5:26 + | +5 | components: vec![Box::new(String::from("Hi"))], + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Draw` is not implemented for `String` + | + = note: required for the cast to the object type `dyn Draw` + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `gui` due to previous error diff --git a/listings/ch17-oop/listing-17-10/src/lib.rs b/listings/ch17-oop/listing-17-10/src/lib.rs new file mode 100755 index 0000000..960fee2 --- /dev/null +++ b/listings/ch17-oop/listing-17-10/src/lib.rs @@ -0,0 +1,27 @@ +pub trait Draw { + fn draw(&self); +} + +pub struct Screen { + pub components: Vec>, +} + +impl Screen { + pub fn run(&self) { + for component in self.components.iter() { + component.draw(); + } + } +} + +pub struct Button { + pub width: u32, + pub height: u32, + pub label: String, +} + +impl Draw for Button { + fn draw(&self) { + // code to actually draw a button + } +} diff --git a/listings/ch17-oop/listing-17-10/src/main.rs b/listings/ch17-oop/listing-17-10/src/main.rs new file mode 100755 index 0000000..2ede87a --- /dev/null +++ b/listings/ch17-oop/listing-17-10/src/main.rs @@ -0,0 +1,9 @@ +use gui::Screen; + +fn main() { + let screen = Screen { + components: vec![Box::new(String::from("Hi"))], + }; + + screen.run(); +} diff --git a/listings/ch17-oop/listing-17-11/Cargo.lock b/listings/ch17-oop/listing-17-11/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-11/Cargo.toml b/listings/ch17-oop/listing-17-11/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-11/src/main.rs b/listings/ch17-oop/listing-17-11/src/main.rs new file mode 100755 index 0000000..d99170a --- /dev/null +++ b/listings/ch17-oop/listing-17-11/src/main.rs @@ -0,0 +1,20 @@ +// ANCHOR: all +use blog::Post; + +// ANCHOR: here +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + // ANCHOR_END: here + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); + // ANCHOR: here +} +// ANCHOR_END: here +// ANCHOR_END: all diff --git a/listings/ch17-oop/listing-17-12/Cargo.lock b/listings/ch17-oop/listing-17-12/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-12/Cargo.toml b/listings/ch17-oop/listing-17-12/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-12/src/lib.rs b/listings/ch17-oop/listing-17-12/src/lib.rs new file mode 100755 index 0000000..b8156c3 --- /dev/null +++ b/listings/ch17-oop/listing-17-12/src/lib.rs @@ -0,0 +1,19 @@ +pub struct Post { + state: Option>, + content: String, +} + +impl Post { + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } +} + +trait State {} + +struct Draft {} + +impl State for Draft {} diff --git a/listings/ch17-oop/listing-17-12/src/main.rs b/listings/ch17-oop/listing-17-12/src/main.rs new file mode 100755 index 0000000..14b4c08 --- /dev/null +++ b/listings/ch17-oop/listing-17-12/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch17-oop/listing-17-13/Cargo.lock b/listings/ch17-oop/listing-17-13/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-13/Cargo.toml b/listings/ch17-oop/listing-17-13/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-13/src/lib.rs b/listings/ch17-oop/listing-17-13/src/lib.rs new file mode 100755 index 0000000..bd68557 --- /dev/null +++ b/listings/ch17-oop/listing-17-13/src/lib.rs @@ -0,0 +1,28 @@ +pub struct Post { + state: Option>, + content: String, +} + +// ANCHOR: here +impl Post { + // --snip-- + // ANCHOR_END: here + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + // ANCHOR: here + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } +} +// ANCHOR_END: here + +trait State {} + +struct Draft {} + +impl State for Draft {} diff --git a/listings/ch17-oop/listing-17-13/src/main.rs b/listings/ch17-oop/listing-17-13/src/main.rs new file mode 100755 index 0000000..14b4c08 --- /dev/null +++ b/listings/ch17-oop/listing-17-13/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch17-oop/listing-17-14/Cargo.lock b/listings/ch17-oop/listing-17-14/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-14/Cargo.toml b/listings/ch17-oop/listing-17-14/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-14/src/lib.rs b/listings/ch17-oop/listing-17-14/src/lib.rs new file mode 100755 index 0000000..09cf0c4 --- /dev/null +++ b/listings/ch17-oop/listing-17-14/src/lib.rs @@ -0,0 +1,32 @@ +pub struct Post { + state: Option>, + content: String, +} + +// ANCHOR: here +impl Post { + // --snip-- + // ANCHOR_END: here + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + // ANCHOR: here + pub fn content(&self) -> &str { + "" + } +} +// ANCHOR_END: here + +trait State {} + +struct Draft {} + +impl State for Draft {} diff --git a/listings/ch17-oop/listing-17-14/src/main.rs b/listings/ch17-oop/listing-17-14/src/main.rs new file mode 100755 index 0000000..14b4c08 --- /dev/null +++ b/listings/ch17-oop/listing-17-14/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch17-oop/listing-17-15/Cargo.lock b/listings/ch17-oop/listing-17-15/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-15/Cargo.toml b/listings/ch17-oop/listing-17-15/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-15/src/lib.rs b/listings/ch17-oop/listing-17-15/src/lib.rs new file mode 100755 index 0000000..909dd52 --- /dev/null +++ b/listings/ch17-oop/listing-17-15/src/lib.rs @@ -0,0 +1,52 @@ +pub struct Post { + state: Option>, + content: String, +} + +// ANCHOR: here +impl Post { + // --snip-- + // ANCHOR_END: here + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + pub fn content(&self) -> &str { + "" + } + + // ANCHOR: here + pub fn request_review(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.request_review()) + } + } +} + +trait State { + fn request_review(self: Box) -> Box; +} + +struct Draft {} + +impl State for Draft { + fn request_review(self: Box) -> Box { + Box::new(PendingReview {}) + } +} + +struct PendingReview {} + +impl State for PendingReview { + fn request_review(self: Box) -> Box { + self + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-15/src/main.rs b/listings/ch17-oop/listing-17-15/src/main.rs new file mode 100755 index 0000000..14b4c08 --- /dev/null +++ b/listings/ch17-oop/listing-17-15/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch17-oop/listing-17-16/Cargo.lock b/listings/ch17-oop/listing-17-16/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-16/Cargo.toml b/listings/ch17-oop/listing-17-16/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-16/src/lib.rs b/listings/ch17-oop/listing-17-16/src/lib.rs new file mode 100755 index 0000000..92cb298 --- /dev/null +++ b/listings/ch17-oop/listing-17-16/src/lib.rs @@ -0,0 +1,85 @@ +pub struct Post { + state: Option>, + content: String, +} + +// ANCHOR: here +impl Post { + // --snip-- + // ANCHOR_END: here + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + pub fn content(&self) -> &str { + "" + } + + pub fn request_review(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.request_review()) + } + } + + // ANCHOR: here + pub fn approve(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.approve()) + } + } +} + +trait State { + fn request_review(self: Box) -> Box; + fn approve(self: Box) -> Box; +} + +struct Draft {} + +impl State for Draft { + // --snip-- + // ANCHOR_END: here + fn request_review(self: Box) -> Box { + Box::new(PendingReview {}) + } + + // ANCHOR: here + fn approve(self: Box) -> Box { + self + } +} + +struct PendingReview {} + +impl State for PendingReview { + // --snip-- + // ANCHOR_END: here + fn request_review(self: Box) -> Box { + self + } + + // ANCHOR: here + fn approve(self: Box) -> Box { + Box::new(Published {}) + } +} + +struct Published {} + +impl State for Published { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + self + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-16/src/main.rs b/listings/ch17-oop/listing-17-16/src/main.rs new file mode 100755 index 0000000..14b4c08 --- /dev/null +++ b/listings/ch17-oop/listing-17-16/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch17-oop/listing-17-17/Cargo.lock b/listings/ch17-oop/listing-17-17/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-17/Cargo.toml b/listings/ch17-oop/listing-17-17/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-17/src/lib.rs b/listings/ch17-oop/listing-17-17/src/lib.rs new file mode 100755 index 0000000..0beee7b --- /dev/null +++ b/listings/ch17-oop/listing-17-17/src/lib.rs @@ -0,0 +1,82 @@ +pub struct Post { + state: Option>, + content: String, +} + +// ANCHOR: here +impl Post { + // --snip-- + // ANCHOR_END: here + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + // ANCHOR: here + pub fn content(&self) -> &str { + self.state.as_ref().unwrap().content(self) + } + // --snip-- + // ANCHOR_END: here + + pub fn request_review(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.request_review()) + } + } + + pub fn approve(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.approve()) + } + } + // ANCHOR: here +} +// ANCHOR_END: here + +trait State { + fn request_review(self: Box) -> Box; + fn approve(self: Box) -> Box; +} + +struct Draft {} + +impl State for Draft { + fn request_review(self: Box) -> Box { + Box::new(PendingReview {}) + } + + fn approve(self: Box) -> Box { + self + } +} + +struct PendingReview {} + +impl State for PendingReview { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + Box::new(Published {}) + } +} + +struct Published {} + +impl State for Published { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + self + } +} diff --git a/listings/ch17-oop/listing-17-17/src/main.rs b/listings/ch17-oop/listing-17-17/src/main.rs new file mode 100755 index 0000000..14b4c08 --- /dev/null +++ b/listings/ch17-oop/listing-17-17/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch17-oop/listing-17-18/Cargo.lock b/listings/ch17-oop/listing-17-18/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-18/Cargo.toml b/listings/ch17-oop/listing-17-18/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-18/src/lib.rs b/listings/ch17-oop/listing-17-18/src/lib.rs new file mode 100755 index 0000000..1bac8a8 --- /dev/null +++ b/listings/ch17-oop/listing-17-18/src/lib.rs @@ -0,0 +1,94 @@ +pub struct Post { + state: Option>, + content: String, +} + +impl Post { + pub fn new() -> Post { + Post { + state: Some(Box::new(Draft {})), + content: String::new(), + } + } + + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + pub fn content(&self) -> &str { + self.state.as_ref().unwrap().content(self) + } + + pub fn request_review(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.request_review()) + } + } + + pub fn approve(&mut self) { + if let Some(s) = self.state.take() { + self.state = Some(s.approve()) + } + } +} + +// ANCHOR: here +trait State { + // --snip-- + // ANCHOR_END: here + fn request_review(self: Box) -> Box; + fn approve(self: Box) -> Box; + + // ANCHOR: here + fn content<'a>(&self, post: &'a Post) -> &'a str { + "" + } +} + +// --snip-- +// ANCHOR_END: here + +struct Draft {} + +impl State for Draft { + fn request_review(self: Box) -> Box { + Box::new(PendingReview {}) + } + + fn approve(self: Box) -> Box { + self + } +} + +struct PendingReview {} + +impl State for PendingReview { + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + Box::new(Published {}) + } +} + +// ANCHOR: here +struct Published {} + +impl State for Published { + // --snip-- + // ANCHOR_END: here + fn request_review(self: Box) -> Box { + self + } + + fn approve(self: Box) -> Box { + self + } + + // ANCHOR: here + fn content<'a>(&self, post: &'a Post) -> &'a str { + &post.content + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-18/src/main.rs b/listings/ch17-oop/listing-17-18/src/main.rs new file mode 100755 index 0000000..14b4c08 --- /dev/null +++ b/listings/ch17-oop/listing-17-18/src/main.rs @@ -0,0 +1,14 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + assert_eq!("", post.content()); + + post.request_review(); + assert_eq!("", post.content()); + + post.approve(); + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch17-oop/listing-17-19/Cargo.lock b/listings/ch17-oop/listing-17-19/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-19/Cargo.toml b/listings/ch17-oop/listing-17-19/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-19/src/lib.rs b/listings/ch17-oop/listing-17-19/src/lib.rs new file mode 100755 index 0000000..bfe034e --- /dev/null +++ b/listings/ch17-oop/listing-17-19/src/lib.rs @@ -0,0 +1,25 @@ +pub struct Post { + content: String, +} + +pub struct DraftPost { + content: String, +} + +impl Post { + pub fn new() -> DraftPost { + DraftPost { + content: String::new(), + } + } + + pub fn content(&self) -> &str { + &self.content + } +} + +impl DraftPost { + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } +} diff --git a/listings/ch17-oop/listing-17-20/Cargo.lock b/listings/ch17-oop/listing-17-20/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-20/Cargo.toml b/listings/ch17-oop/listing-17-20/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-20/src/lib.rs b/listings/ch17-oop/listing-17-20/src/lib.rs new file mode 100755 index 0000000..3b82ec0 --- /dev/null +++ b/listings/ch17-oop/listing-17-20/src/lib.rs @@ -0,0 +1,48 @@ +pub struct Post { + content: String, +} + +pub struct DraftPost { + content: String, +} + +impl Post { + pub fn new() -> DraftPost { + DraftPost { + content: String::new(), + } + } + + pub fn content(&self) -> &str { + &self.content + } +} + +// ANCHOR: here +impl DraftPost { + // --snip-- + // ANCHOR_END: here + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + // ANCHOR: here + pub fn request_review(self) -> PendingReviewPost { + PendingReviewPost { + content: self.content, + } + } +} + +pub struct PendingReviewPost { + content: String, +} + +impl PendingReviewPost { + pub fn approve(self) -> Post { + Post { + content: self.content, + } + } +} +// ANCHOR_END: here diff --git a/listings/ch17-oop/listing-17-21/Cargo.lock b/listings/ch17-oop/listing-17-21/Cargo.lock new file mode 100755 index 0000000..b6f4232 --- /dev/null +++ b/listings/ch17-oop/listing-17-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "blog" +version = "0.1.0" + diff --git a/listings/ch17-oop/listing-17-21/Cargo.toml b/listings/ch17-oop/listing-17-21/Cargo.toml new file mode 100755 index 0000000..1619af5 --- /dev/null +++ b/listings/ch17-oop/listing-17-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "blog" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-21/src/lib.rs b/listings/ch17-oop/listing-17-21/src/lib.rs new file mode 100755 index 0000000..38500a6 --- /dev/null +++ b/listings/ch17-oop/listing-17-21/src/lib.rs @@ -0,0 +1,43 @@ +pub struct Post { + content: String, +} + +pub struct DraftPost { + content: String, +} + +impl Post { + pub fn new() -> DraftPost { + DraftPost { + content: String::new(), + } + } + + pub fn content(&self) -> &str { + &self.content + } +} + +impl DraftPost { + pub fn add_text(&mut self, text: &str) { + self.content.push_str(text); + } + + pub fn request_review(self) -> PendingReviewPost { + PendingReviewPost { + content: self.content, + } + } +} + +pub struct PendingReviewPost { + content: String, +} + +impl PendingReviewPost { + pub fn approve(self) -> Post { + Post { + content: self.content, + } + } +} diff --git a/listings/ch17-oop/listing-17-21/src/main.rs b/listings/ch17-oop/listing-17-21/src/main.rs new file mode 100755 index 0000000..720c55e --- /dev/null +++ b/listings/ch17-oop/listing-17-21/src/main.rs @@ -0,0 +1,13 @@ +use blog::Post; + +fn main() { + let mut post = Post::new(); + + post.add_text("I ate a salad for lunch today"); + + let post = post.request_review(); + + let post = post.approve(); + + assert_eq!("I ate a salad for lunch today", post.content()); +} diff --git a/listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-01/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-01/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-01/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-01/src/main.rs new file mode 100755 index 0000000..d28c369 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-01/src/main.rs @@ -0,0 +1,19 @@ +fn main() { + let favorite_color: Option<&str> = None; + let is_tuesday = false; + let age: Result = "34".parse(); + + if let Some(color) = favorite_color { + println!("Using your favorite color, {}, as the background", color); + } else if is_tuesday { + println!("Tuesday is green day!"); + } else if let Ok(age) = age { + if age > 30 { + println!("Using purple as the background color"); + } else { + println!("Using orange as the background color"); + } + } else { + println!("Using blue as the background color"); + } +} diff --git a/listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-02/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-02/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-02/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-02/src/main.rs new file mode 100755 index 0000000..5f75a4f --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-02/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + let mut stack = Vec::new(); + + stack.push(1); + stack.push(2); + stack.push(3); + + while let Some(top) = stack.pop() { + println!("{}", top); + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-03/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-03/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-03/output.txt b/listings/ch18-patterns-and-matching/listing-18-03/output.txt new file mode 100755 index 0000000..02fdecb --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-03/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling patterns v0.1.0 (file:///projects/patterns) + Finished dev [unoptimized + debuginfo] target(s) in 0.52s + Running `target/debug/patterns` +a is at index 0 +b is at index 1 +c is at index 2 diff --git a/listings/ch18-patterns-and-matching/listing-18-03/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-03/src/main.rs new file mode 100755 index 0000000..eb922d6 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-03/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + let v = vec!['a', 'b', 'c']; + + for (index, value) in v.iter().enumerate() { + println!("{} is at index {}", value, index); + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-04/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-04/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-04/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-04/src/main.rs new file mode 100755 index 0000000..27b0c3f --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-04/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + // ANCHOR: here + let (x, y, z) = (1, 2, 3); + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-05/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-05/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-05/output.txt b/listings/ch18-patterns-and-matching/listing-18-05/output.txt new file mode 100755 index 0000000..57916a1 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-05/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling patterns v0.1.0 (file:///projects/patterns) +error[E0308]: mismatched types + --> src/main.rs:2:9 + | +2 | let (x, y) = (1, 2, 3); + | ^^^^^^ --------- this expression has type `({integer}, {integer}, {integer})` + | | + | expected a tuple with 3 elements, found one with 2 elements + | + = note: expected tuple `({integer}, {integer}, {integer})` + found tuple `(_, _)` + +For more information about this error, try `rustc --explain E0308`. +error: could not compile `patterns` due to previous error diff --git a/listings/ch18-patterns-and-matching/listing-18-05/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-05/src/main.rs new file mode 100755 index 0000000..39f768e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-05/src/main.rs @@ -0,0 +1,5 @@ +fn main() { + // ANCHOR: here + let (x, y) = (1, 2, 3); + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-06/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-06/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-06/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-06/src/main.rs new file mode 100755 index 0000000..c5d71e6 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-06/src/main.rs @@ -0,0 +1,7 @@ +// ANCHOR: here +fn foo(x: i32) { + // code goes here +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-07/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-07/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-07/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-07/src/main.rs new file mode 100755 index 0000000..4eccb80 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-07/src/main.rs @@ -0,0 +1,8 @@ +fn print_coordinates(&(x, y): &(i32, i32)) { + println!("Current location: ({}, {})", x, y); +} + +fn main() { + let point = (3, 5); + print_coordinates(&point); +} diff --git a/listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-08/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-08/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-08/output.txt b/listings/ch18-patterns-and-matching/listing-18-08/output.txt new file mode 100755 index 0000000..5915c39 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-08/output.txt @@ -0,0 +1,18 @@ +$ cargo run + Compiling patterns v0.1.0 (file:///projects/patterns) +error[E0005]: refutable pattern in local binding: `None` not covered + --> src/main.rs:3:9 + | +3 | let Some(x) = some_option_value; + | ^^^^^^^ pattern `None` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `Option` +help: you might want to use `if let` to ignore the variant that isn't matched + | +3 | if let Some(x) = some_option_value { /* */ } + | + +For more information about this error, try `rustc --explain E0005`. +error: could not compile `patterns` due to previous error diff --git a/listings/ch18-patterns-and-matching/listing-18-08/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-08/src/main.rs new file mode 100755 index 0000000..7baa02a --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-08/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + let some_option_value: Option = None; + // ANCHOR: here + let Some(x) = some_option_value; + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-09/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-09/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-09/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-09/src/main.rs new file mode 100755 index 0000000..d6274fc --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-09/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + let some_option_value: Option = None; + // ANCHOR: here + if let Some(x) = some_option_value { + println!("{}", x); + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-10/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-10/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-10/output.txt b/listings/ch18-patterns-and-matching/listing-18-10/output.txt new file mode 100755 index 0000000..702d10a --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-10/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling patterns v0.1.0 (file:///projects/patterns) +warning: irrefutable `if let` pattern + --> src/main.rs:2:8 + | +2 | if let x = 5 { + | ^^^^^^^^^ + | + = note: `#[warn(irrefutable_let_patterns)]` on by default + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` + +warning: `patterns` (bin "patterns") generated 1 warning + Finished dev [unoptimized + debuginfo] target(s) in 0.39s + Running `target/debug/patterns` +5 diff --git a/listings/ch18-patterns-and-matching/listing-18-10/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-10/src/main.rs new file mode 100755 index 0000000..cb81772 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-10/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + if let x = 5 { + println!("{}", x); + }; + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-11/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-11/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-11/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-11/src/main.rs new file mode 100755 index 0000000..25eaa79 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-11/src/main.rs @@ -0,0 +1,14 @@ +fn main() { + // ANCHOR: here + let x = Some(5); + let y = 10; + + match x { + Some(50) => println!("Got 50"), + Some(y) => println!("Matched, y = {:?}", y), + _ => println!("Default case, x = {:?}", x), + } + + println!("at the end: x = {:?}, y = {:?}", x, y); + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-12/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-12/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-12/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-12/src/main.rs new file mode 100755 index 0000000..62f4ccb --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-12/src/main.rs @@ -0,0 +1,12 @@ +struct Point { + x: i32, + y: i32, +} + +fn main() { + let p = Point { x: 0, y: 7 }; + + let Point { x: a, y: b } = p; + assert_eq!(0, a); + assert_eq!(7, b); +} diff --git a/listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-13/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-13/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-13/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-13/src/main.rs new file mode 100755 index 0000000..5badc15 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-13/src/main.rs @@ -0,0 +1,12 @@ +struct Point { + x: i32, + y: i32, +} + +fn main() { + let p = Point { x: 0, y: 7 }; + + let Point { x, y } = p; + assert_eq!(0, x); + assert_eq!(7, y); +} diff --git a/listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-14/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-14/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-14/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-14/src/main.rs new file mode 100755 index 0000000..8d445d9 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-14/src/main.rs @@ -0,0 +1,16 @@ +struct Point { + x: i32, + y: i32, +} + +// ANCHOR: here +fn main() { + let p = Point { x: 0, y: 7 }; + + match p { + Point { x, y: 0 } => println!("On the x axis at {}", x), + Point { x: 0, y } => println!("On the y axis at {}", y), + Point { x, y } => println!("On neither axis: ({}, {})", x, y), + } +} +// ANCHOR_END: here diff --git a/listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-15/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-15/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs new file mode 100755 index 0000000..9b8dac1 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs @@ -0,0 +1,27 @@ +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(i32, i32, i32), +} + +fn main() { + let msg = Message::ChangeColor(0, 160, 255); + + match msg { + Message::Quit => { + println!("The Quit variant has no data to destructure.") + } + Message::Move { x, y } => { + println!( + "Move in the x direction {} and in the y direction {}", + x, y + ); + } + Message::Write(text) => println!("Text message: {}", text), + Message::ChangeColor(r, g, b) => println!( + "Change the color to red {}, green {}, and blue {}", + r, g, b + ), + } +} diff --git a/listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-16/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-16/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs new file mode 100755 index 0000000..ed6a20b --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs @@ -0,0 +1,27 @@ +enum Color { + Rgb(i32, i32, i32), + Hsv(i32, i32, i32), +} + +enum Message { + Quit, + Move { x: i32, y: i32 }, + Write(String), + ChangeColor(Color), +} + +fn main() { + let msg = Message::ChangeColor(Color::Hsv(0, 160, 255)); + + match msg { + Message::ChangeColor(Color::Rgb(r, g, b)) => println!( + "Change the color to red {}, green {}, and blue {}", + r, g, b + ), + Message::ChangeColor(Color::Hsv(h, s, v)) => println!( + "Change the color to hue {}, saturation {}, and value {}", + h, s, v + ), + _ => (), + } +} diff --git a/listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-17/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-17/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-17/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-17/src/main.rs new file mode 100755 index 0000000..cf1fbe0 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-17/src/main.rs @@ -0,0 +1,7 @@ +fn foo(_: i32, y: i32) { + println!("This code only uses the y parameter: {}", y); +} + +fn main() { + foo(3, 4); +} diff --git a/listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-18/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-18/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-18/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-18/src/main.rs new file mode 100755 index 0000000..b776c64 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-18/src/main.rs @@ -0,0 +1,17 @@ +fn main() { + // ANCHOR: here + let mut setting_value = Some(5); + let new_setting_value = Some(10); + + match (setting_value, new_setting_value) { + (Some(_), Some(_)) => { + println!("Can't overwrite an existing customized value"); + } + _ => { + setting_value = new_setting_value; + } + } + + println!("setting is {:?}", setting_value); + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-19/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-19/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-19/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-19/src/main.rs new file mode 100755 index 0000000..59b48c9 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-19/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let numbers = (2, 4, 8, 16, 32); + + match numbers { + (first, _, third, _, fifth) => { + println!("Some numbers: {}, {}, {}", first, third, fifth) + } + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-20/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-20/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-20/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-20/src/main.rs new file mode 100755 index 0000000..1ffc46b --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-20/src/main.rs @@ -0,0 +1,4 @@ +fn main() { + let _x = 5; + let y = 10; +} diff --git a/listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-21/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-21/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-21/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-21/src/main.rs new file mode 100755 index 0000000..9806105 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-21/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let s = Some(String::from("Hello!")); + + if let Some(_s) = s { + println!("found a string"); + } + + println!("{:?}", s); + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-22/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-22/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-22/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-22/src/main.rs new file mode 100755 index 0000000..e2faa34 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-22/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let s = Some(String::from("Hello!")); + + if let Some(_) = s { + println!("found a string"); + } + + println!("{:?}", s); + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-23/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-23/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-23/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-23/src/main.rs new file mode 100755 index 0000000..7a9d9bb --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-23/src/main.rs @@ -0,0 +1,15 @@ +fn main() { + // ANCHOR: here + struct Point { + x: i32, + y: i32, + z: i32, + } + + let origin = Point { x: 0, y: 0, z: 0 }; + + match origin { + Point { x, .. } => println!("x is {}", x), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-24/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-24/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-24/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-24/src/main.rs new file mode 100755 index 0000000..f22dbe8 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-24/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let numbers = (2, 4, 8, 16, 32); + + match numbers { + (first, .., last) => { + println!("Some numbers: {}, {}", first, last); + } + } +} diff --git a/listings/ch18-patterns-and-matching/listing-18-25/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-25/Cargo.lock new file mode 100755 index 0000000..a233623 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-25/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-25/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-25/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-25/output.txt b/listings/ch18-patterns-and-matching/listing-18-25/output.txt new file mode 100755 index 0000000..7e0357e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-25/output.txt @@ -0,0 +1,11 @@ +$ cargo run + Compiling patterns v0.1.0 (file:///projects/patterns) +error: `..` can only be used once per tuple pattern + --> src/main.rs:5:22 + | +5 | (.., second, ..) => { + | -- ^^ can only be used once per tuple pattern + | | + | previously used here + +error: could not compile `patterns` due to previous error diff --git a/listings/ch18-patterns-and-matching/listing-18-25/rustfmt-ignore b/listings/ch18-patterns-and-matching/listing-18-25/rustfmt-ignore new file mode 100755 index 0000000..06a976d --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-25/rustfmt-ignore @@ -0,0 +1 @@ +This listing deliberately doesn't parse so rustfmt fails. diff --git a/listings/ch18-patterns-and-matching/listing-18-25/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-25/src/main.rs new file mode 100755 index 0000000..b90884e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-25/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let numbers = (2, 4, 8, 16, 32); + + match numbers { + (.., second, ..) => { + println!("Some numbers: {}", second) + }, + } +} diff --git a/listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-26/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-26/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-26/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-26/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-26/src/main.rs new file mode 100755 index 0000000..4ec86cb --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-26/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let num = Some(4); + + match num { + Some(x) if x < 5 => println!("less than five: {}", x), + Some(x) => println!("{}", x), + None => (), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-27/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-27/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-27/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-27/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-27/src/main.rs new file mode 100755 index 0000000..348e367 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-27/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + let x = Some(5); + let y = 10; + + match x { + Some(50) => println!("Got 50"), + Some(n) if n == y => println!("Matched, n = {}", n), + _ => println!("Default case, x = {:?}", x), + } + + println!("at the end: x = {:?}, y = {}", x, y); +} diff --git a/listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-28/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-28/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-28/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-28/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-28/src/main.rs new file mode 100755 index 0000000..1580455 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-28/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let x = 4; + let y = false; + + match x { + 4 | 5 | 6 if y => println!("yes"), + _ => println!("no"), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock b/listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/listing-18-29/Cargo.toml b/listings/ch18-patterns-and-matching/listing-18-29/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-29/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/listing-18-29/src/main.rs b/listings/ch18-patterns-and-matching/listing-18-29/src/main.rs new file mode 100755 index 0000000..3514deb --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-29/src/main.rs @@ -0,0 +1,19 @@ +fn main() { + // ANCHOR: here + enum Message { + Hello { id: i32 }, + } + + let msg = Message::Hello { id: 5 }; + + match msg { + Message::Hello { + id: id_variable @ 3..=7, + } => println!("Found an id in range: {}", id_variable), + Message::Hello { id: 10..=12 } => { + println!("Found an id in another range") + } + Message::Hello { id } => println!("Found some other id: {}", id), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock b/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.toml b/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/no-listing-01-literals/src/main.rs b/listings/ch18-patterns-and-matching/no-listing-01-literals/src/main.rs new file mode 100755 index 0000000..7978e1a --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-01-literals/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: here + let x = 1; + + match x { + 1 => println!("one"), + 2 => println!("two"), + 3 => println!("three"), + _ => println!("anything"), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.toml b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs new file mode 100755 index 0000000..e52d815 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let x = 1; + + match x { + 1 | 2 => println!("one or two"), + 3 => println!("three"), + _ => println!("anything"), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock b/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.toml b/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs b/listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs new file mode 100755 index 0000000..a3ebe7a --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + let x = 5; + + match x { + 1..=5 => println!("one through five"), + _ => println!("something else"), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.toml b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/src/main.rs b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/src/main.rs new file mode 100755 index 0000000..8cebfef --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/src/main.rs @@ -0,0 +1,11 @@ +fn main() { + // ANCHOR: here + let x = 'c'; + + match x { + 'a'..='j' => println!("early ASCII letter"), + 'k'..='z' => println!("late ASCII letter"), + _ => println!("something else"), + } + // ANCHOR_END: here +} diff --git a/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock new file mode 100755 index 0000000..2b4fa29 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "patterns" +version = "0.1.0" + diff --git a/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.toml b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.toml new file mode 100755 index 0000000..82fe057 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "patterns" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/src/main.rs b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/src/main.rs new file mode 100755 index 0000000..962d093 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + struct Point { + x: i32, + y: i32, + } + + // ANCHOR: here + let ((feet, inches), Point { x, y }) = ((3, 10), Point { x: 3, y: -10 }); + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.lock b/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.lock new file mode 100755 index 0000000..58b70c5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "counter" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.toml b/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.toml new file mode 100755 index 0000000..9e103f3 --- /dev/null +++ b/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "counter" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-13-21-reproduced/src/lib.rs b/listings/ch19-advanced-features/listing-13-21-reproduced/src/lib.rs new file mode 100755 index 0000000..04c7f38 --- /dev/null +++ b/listings/ch19-advanced-features/listing-13-21-reproduced/src/lib.rs @@ -0,0 +1,25 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +// ANCHOR: ch19 +impl Iterator for Counter { + type Item = u32; + + fn next(&mut self) -> Option { + // --snip-- + // ANCHOR_END: ch19 + if self.count < 5 { + self.count += 1; + Some(self.count) + } else { + None + } + } +} diff --git a/listings/ch19-advanced-features/listing-19-01/Cargo.lock b/listings/ch19-advanced-features/listing-19-01/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-01/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-01/Cargo.toml b/listings/ch19-advanced-features/listing-19-01/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-01/src/main.rs b/listings/ch19-advanced-features/listing-19-01/src/main.rs new file mode 100755 index 0000000..893f578 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-01/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + // ANCHOR: here + let mut num = 5; + + let r1 = &num as *const i32; + let r2 = &mut num as *mut i32; + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-19-02/Cargo.lock b/listings/ch19-advanced-features/listing-19-02/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-02/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-02/Cargo.toml b/listings/ch19-advanced-features/listing-19-02/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-02/src/main.rs b/listings/ch19-advanced-features/listing-19-02/src/main.rs new file mode 100755 index 0000000..849629a --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-02/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let address = 0x012345usize; + let r = address as *const i32; + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-19-03/Cargo.lock b/listings/ch19-advanced-features/listing-19-03/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-03/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-03/Cargo.toml b/listings/ch19-advanced-features/listing-19-03/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-03/src/main.rs b/listings/ch19-advanced-features/listing-19-03/src/main.rs new file mode 100755 index 0000000..02a0be6 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-03/src/main.rs @@ -0,0 +1,13 @@ +fn main() { + // ANCHOR: here + let mut num = 5; + + let r1 = &num as *const i32; + let r2 = &mut num as *mut i32; + + unsafe { + println!("r1 is: {}", *r1); + println!("r2 is: {}", *r2); + } + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-19-04/Cargo.lock b/listings/ch19-advanced-features/listing-19-04/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-04/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-04/Cargo.toml b/listings/ch19-advanced-features/listing-19-04/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-04/src/main.rs b/listings/ch19-advanced-features/listing-19-04/src/main.rs new file mode 100755 index 0000000..6ac5844 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-04/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: here + let mut v = vec![1, 2, 3, 4, 5, 6]; + + let r = &mut v[..]; + + let (a, b) = r.split_at_mut(3); + + assert_eq!(a, &mut [1, 2, 3]); + assert_eq!(b, &mut [4, 5, 6]); + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-19-05/Cargo.lock b/listings/ch19-advanced-features/listing-19-05/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-05/Cargo.toml b/listings/ch19-advanced-features/listing-19-05/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-05/output.txt b/listings/ch19-advanced-features/listing-19-05/output.txt new file mode 100755 index 0000000..18191f8 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/output.txt @@ -0,0 +1,17 @@ +$ cargo run + Compiling unsafe-example v0.1.0 (file:///projects/unsafe-example) +error[E0499]: cannot borrow `*slice` as mutable more than once at a time + --> src/main.rs:6:30 + | +1 | fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { + | - let's call the lifetime of this reference `'1` +... +6 | (&mut slice[..mid], &mut slice[mid..]) + | -------------------------^^^^^-------- + | | | | + | | | second mutable borrow occurs here + | | first mutable borrow occurs here + | returning this value requires that `*slice` is borrowed for `'1` + +For more information about this error, try `rustc --explain E0499`. +error: could not compile `unsafe-example` due to previous error diff --git a/listings/ch19-advanced-features/listing-19-05/src/main.rs b/listings/ch19-advanced-features/listing-19-05/src/main.rs new file mode 100755 index 0000000..c4b83ef --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/src/main.rs @@ -0,0 +1,14 @@ +// ANCHOR: here +fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { + let len = slice.len(); + + assert!(mid <= len); + + (&mut slice[..mid], &mut slice[mid..]) +} +// ANCHOR_END: here + +fn main() { + let mut vector = vec![1, 2, 3, 4, 5, 6]; + let (left, right) = split_at_mut(&mut vector, 3); +} diff --git a/listings/ch19-advanced-features/listing-19-06/Cargo.lock b/listings/ch19-advanced-features/listing-19-06/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-06/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-06/Cargo.toml b/listings/ch19-advanced-features/listing-19-06/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-06/src/main.rs b/listings/ch19-advanced-features/listing-19-06/src/main.rs new file mode 100755 index 0000000..f25cbf4 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-06/src/main.rs @@ -0,0 +1,22 @@ +// ANCHOR: here +use std::slice; + +fn split_at_mut(slice: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { + let len = slice.len(); + let ptr = slice.as_mut_ptr(); + + assert!(mid <= len); + + unsafe { + ( + slice::from_raw_parts_mut(ptr, mid), + slice::from_raw_parts_mut(ptr.add(mid), len - mid), + ) + } +} +// ANCHOR_END: here + +fn main() { + let mut vector = vec![1, 2, 3, 4, 5, 6]; + let (left, right) = split_at_mut(&mut vector, 3); +} diff --git a/listings/ch19-advanced-features/listing-19-07/Cargo.lock b/listings/ch19-advanced-features/listing-19-07/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-07/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-07/Cargo.toml b/listings/ch19-advanced-features/listing-19-07/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-07/src/main.rs b/listings/ch19-advanced-features/listing-19-07/src/main.rs new file mode 100755 index 0000000..0ab39ae --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-07/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + use std::slice; + + let address = 0x01234usize; + let r = address as *mut i32; + + let slice: &[i32] = unsafe { slice::from_raw_parts_mut(r, 10000) }; + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-19-08/Cargo.lock b/listings/ch19-advanced-features/listing-19-08/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-08/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-08/Cargo.toml b/listings/ch19-advanced-features/listing-19-08/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-08/src/main.rs b/listings/ch19-advanced-features/listing-19-08/src/main.rs new file mode 100755 index 0000000..8b56630 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-08/src/main.rs @@ -0,0 +1,9 @@ +extern "C" { + fn abs(input: i32) -> i32; +} + +fn main() { + unsafe { + println!("Absolute value of -3 according to C: {}", abs(-3)); + } +} diff --git a/listings/ch19-advanced-features/listing-19-09/Cargo.lock b/listings/ch19-advanced-features/listing-19-09/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-09/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-09/Cargo.toml b/listings/ch19-advanced-features/listing-19-09/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-09/src/main.rs b/listings/ch19-advanced-features/listing-19-09/src/main.rs new file mode 100755 index 0000000..82a4b42 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-09/src/main.rs @@ -0,0 +1,5 @@ +static HELLO_WORLD: &str = "Hello, world!"; + +fn main() { + println!("name is: {}", HELLO_WORLD); +} diff --git a/listings/ch19-advanced-features/listing-19-10/Cargo.lock b/listings/ch19-advanced-features/listing-19-10/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-10/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-10/Cargo.toml b/listings/ch19-advanced-features/listing-19-10/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-10/src/main.rs b/listings/ch19-advanced-features/listing-19-10/src/main.rs new file mode 100755 index 0000000..e8dab68 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-10/src/main.rs @@ -0,0 +1,15 @@ +static mut COUNTER: u32 = 0; + +fn add_to_count(inc: u32) { + unsafe { + COUNTER += inc; + } +} + +fn main() { + add_to_count(3); + + unsafe { + println!("COUNTER: {}", COUNTER); + } +} diff --git a/listings/ch19-advanced-features/listing-19-11/Cargo.lock b/listings/ch19-advanced-features/listing-19-11/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-11/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-11/Cargo.toml b/listings/ch19-advanced-features/listing-19-11/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-11/src/main.rs b/listings/ch19-advanced-features/listing-19-11/src/main.rs new file mode 100755 index 0000000..885c1aa --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-11/src/main.rs @@ -0,0 +1,9 @@ +unsafe trait Foo { + // methods go here +} + +unsafe impl Foo for i32 { + // method implementations go here +} + +fn main() {} diff --git a/listings/ch19-advanced-features/listing-19-12/Cargo.lock b/listings/ch19-advanced-features/listing-19-12/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-12/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-12/Cargo.toml b/listings/ch19-advanced-features/listing-19-12/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-12/src/lib.rs b/listings/ch19-advanced-features/listing-19-12/src/lib.rs new file mode 100755 index 0000000..dbe0462 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-12/src/lib.rs @@ -0,0 +1,5 @@ +pub trait Iterator { + type Item; + + fn next(&mut self) -> Option; +} diff --git a/listings/ch19-advanced-features/listing-19-13/Cargo.lock b/listings/ch19-advanced-features/listing-19-13/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-13/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-13/Cargo.toml b/listings/ch19-advanced-features/listing-19-13/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-13/src/lib.rs b/listings/ch19-advanced-features/listing-19-13/src/lib.rs new file mode 100755 index 0000000..7c9479c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-13/src/lib.rs @@ -0,0 +1,3 @@ +pub trait Iterator { + fn next(&mut self) -> Option; +} diff --git a/listings/ch19-advanced-features/listing-19-14/Cargo.lock b/listings/ch19-advanced-features/listing-19-14/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-14/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-14/Cargo.toml b/listings/ch19-advanced-features/listing-19-14/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-14/src/main.rs b/listings/ch19-advanced-features/listing-19-14/src/main.rs new file mode 100755 index 0000000..9111fbc --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-14/src/main.rs @@ -0,0 +1,25 @@ +use std::ops::Add; + +#[derive(Debug, Copy, Clone, PartialEq)] +struct Point { + x: i32, + y: i32, +} + +impl Add for Point { + type Output = Point; + + fn add(self, other: Point) -> Point { + Point { + x: self.x + other.x, + y: self.y + other.y, + } + } +} + +fn main() { + assert_eq!( + Point { x: 1, y: 0 } + Point { x: 2, y: 3 }, + Point { x: 3, y: 3 } + ); +} diff --git a/listings/ch19-advanced-features/listing-19-15/Cargo.lock b/listings/ch19-advanced-features/listing-19-15/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-15/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-15/Cargo.toml b/listings/ch19-advanced-features/listing-19-15/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-15/src/lib.rs b/listings/ch19-advanced-features/listing-19-15/src/lib.rs new file mode 100755 index 0000000..f38bf47 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-15/src/lib.rs @@ -0,0 +1,12 @@ +use std::ops::Add; + +struct Millimeters(u32); +struct Meters(u32); + +impl Add for Millimeters { + type Output = Millimeters; + + fn add(self, other: Meters) -> Millimeters { + Millimeters(self.0 + (other.0 * 1000)) + } +} diff --git a/listings/ch19-advanced-features/listing-19-16/Cargo.lock b/listings/ch19-advanced-features/listing-19-16/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-16/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-16/Cargo.toml b/listings/ch19-advanced-features/listing-19-16/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-16/src/main.rs b/listings/ch19-advanced-features/listing-19-16/src/main.rs new file mode 100755 index 0000000..d854e28 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-16/src/main.rs @@ -0,0 +1,31 @@ +// ANCHOR: here +trait Pilot { + fn fly(&self); +} + +trait Wizard { + fn fly(&self); +} + +struct Human; + +impl Pilot for Human { + fn fly(&self) { + println!("This is your captain speaking."); + } +} + +impl Wizard for Human { + fn fly(&self) { + println!("Up!"); + } +} + +impl Human { + fn fly(&self) { + println!("*waving arms furiously*"); + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch19-advanced-features/listing-19-17/Cargo.lock b/listings/ch19-advanced-features/listing-19-17/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-17/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-17/Cargo.toml b/listings/ch19-advanced-features/listing-19-17/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-17/src/main.rs b/listings/ch19-advanced-features/listing-19-17/src/main.rs new file mode 100755 index 0000000..3df65a7 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-17/src/main.rs @@ -0,0 +1,34 @@ +trait Pilot { + fn fly(&self); +} + +trait Wizard { + fn fly(&self); +} + +struct Human; + +impl Pilot for Human { + fn fly(&self) { + println!("This is your captain speaking."); + } +} + +impl Wizard for Human { + fn fly(&self) { + println!("Up!"); + } +} + +impl Human { + fn fly(&self) { + println!("*waving arms furiously*"); + } +} + +// ANCHOR: here +fn main() { + let person = Human; + person.fly(); +} +// ANCHOR_END: here diff --git a/listings/ch19-advanced-features/listing-19-18/Cargo.lock b/listings/ch19-advanced-features/listing-19-18/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-18/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-18/Cargo.toml b/listings/ch19-advanced-features/listing-19-18/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-18/output.txt b/listings/ch19-advanced-features/listing-19-18/output.txt new file mode 100755 index 0000000..2e9da17 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-18/output.txt @@ -0,0 +1,7 @@ +$ cargo run + Compiling traits-example v0.1.0 (file:///projects/traits-example) + Finished dev [unoptimized + debuginfo] target(s) in 0.46s + Running `target/debug/traits-example` +This is your captain speaking. +Up! +*waving arms furiously* diff --git a/listings/ch19-advanced-features/listing-19-18/src/main.rs b/listings/ch19-advanced-features/listing-19-18/src/main.rs new file mode 100755 index 0000000..fa01c09 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-18/src/main.rs @@ -0,0 +1,36 @@ +trait Pilot { + fn fly(&self); +} + +trait Wizard { + fn fly(&self); +} + +struct Human; + +impl Pilot for Human { + fn fly(&self) { + println!("This is your captain speaking."); + } +} + +impl Wizard for Human { + fn fly(&self) { + println!("Up!"); + } +} + +impl Human { + fn fly(&self) { + println!("*waving arms furiously*"); + } +} + +// ANCHOR: here +fn main() { + let person = Human; + Pilot::fly(&person); + Wizard::fly(&person); + person.fly(); +} +// ANCHOR_END: here diff --git a/listings/ch19-advanced-features/listing-19-19/Cargo.lock b/listings/ch19-advanced-features/listing-19-19/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-19/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-19/Cargo.toml b/listings/ch19-advanced-features/listing-19-19/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-19/output.txt b/listings/ch19-advanced-features/listing-19-19/output.txt new file mode 100755 index 0000000..087e802 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-19/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling traits-example v0.1.0 (file:///projects/traits-example) + Finished dev [unoptimized + debuginfo] target(s) in 0.54s + Running `target/debug/traits-example` +A baby dog is called a Spot diff --git a/listings/ch19-advanced-features/listing-19-19/src/main.rs b/listings/ch19-advanced-features/listing-19-19/src/main.rs new file mode 100755 index 0000000..44affe0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-19/src/main.rs @@ -0,0 +1,21 @@ +trait Animal { + fn baby_name() -> String; +} + +struct Dog; + +impl Dog { + fn baby_name() -> String { + String::from("Spot") + } +} + +impl Animal for Dog { + fn baby_name() -> String { + String::from("puppy") + } +} + +fn main() { + println!("A baby dog is called a {}", Dog::baby_name()); +} diff --git a/listings/ch19-advanced-features/listing-19-20/Cargo.lock b/listings/ch19-advanced-features/listing-19-20/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-20/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-20/Cargo.toml b/listings/ch19-advanced-features/listing-19-20/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-20/output.txt b/listings/ch19-advanced-features/listing-19-20/output.txt new file mode 100755 index 0000000..6845082 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-20/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling traits-example v0.1.0 (file:///projects/traits-example) +error[E0283]: type annotations needed + --> src/main.rs:20:43 + | +20 | println!("A baby dog is called a {}", Animal::baby_name()); + | ^^^^^^^^^^^^^^^^^ cannot infer type + | + = note: cannot satisfy `_: Animal` + +For more information about this error, try `rustc --explain E0283`. +error: could not compile `traits-example` due to previous error diff --git a/listings/ch19-advanced-features/listing-19-20/src/main.rs b/listings/ch19-advanced-features/listing-19-20/src/main.rs new file mode 100755 index 0000000..8e295c9 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-20/src/main.rs @@ -0,0 +1,23 @@ +trait Animal { + fn baby_name() -> String; +} + +struct Dog; + +impl Dog { + fn baby_name() -> String { + String::from("Spot") + } +} + +impl Animal for Dog { + fn baby_name() -> String { + String::from("puppy") + } +} + +// ANCHOR: here +fn main() { + println!("A baby dog is called a {}", Animal::baby_name()); +} +// ANCHOR_END: here diff --git a/listings/ch19-advanced-features/listing-19-21/Cargo.lock b/listings/ch19-advanced-features/listing-19-21/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-21/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-21/Cargo.toml b/listings/ch19-advanced-features/listing-19-21/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-21/output.txt b/listings/ch19-advanced-features/listing-19-21/output.txt new file mode 100755 index 0000000..4d1ee5a --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-21/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling traits-example v0.1.0 (file:///projects/traits-example) + Finished dev [unoptimized + debuginfo] target(s) in 0.48s + Running `target/debug/traits-example` +A baby dog is called a puppy diff --git a/listings/ch19-advanced-features/listing-19-21/src/main.rs b/listings/ch19-advanced-features/listing-19-21/src/main.rs new file mode 100755 index 0000000..b1df728 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-21/src/main.rs @@ -0,0 +1,23 @@ +trait Animal { + fn baby_name() -> String; +} + +struct Dog; + +impl Dog { + fn baby_name() -> String { + String::from("Spot") + } +} + +impl Animal for Dog { + fn baby_name() -> String { + String::from("puppy") + } +} + +// ANCHOR: here +fn main() { + println!("A baby dog is called a {}", ::baby_name()); +} +// ANCHOR_END: here diff --git a/listings/ch19-advanced-features/listing-19-22/Cargo.lock b/listings/ch19-advanced-features/listing-19-22/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-22/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-22/Cargo.toml b/listings/ch19-advanced-features/listing-19-22/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-22/src/main.rs b/listings/ch19-advanced-features/listing-19-22/src/main.rs new file mode 100755 index 0000000..febe58b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-22/src/main.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +use std::fmt; + +trait OutlinePrint: fmt::Display { + fn outline_print(&self) { + let output = self.to_string(); + let len = output.len(); + println!("{}", "*".repeat(len + 4)); + println!("*{}*", " ".repeat(len + 2)); + println!("* {} *", output); + println!("*{}*", " ".repeat(len + 2)); + println!("{}", "*".repeat(len + 4)); + } +} +// ANCHOR_END: here + +fn main() {} diff --git a/listings/ch19-advanced-features/listing-19-23/Cargo.lock b/listings/ch19-advanced-features/listing-19-23/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-23/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-23/Cargo.toml b/listings/ch19-advanced-features/listing-19-23/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-23/src/main.rs b/listings/ch19-advanced-features/listing-19-23/src/main.rs new file mode 100755 index 0000000..eae46c9 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-23/src/main.rs @@ -0,0 +1,14 @@ +use std::fmt; + +struct Wrapper(Vec); + +impl fmt::Display for Wrapper { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "[{}]", self.0.join(", ")) + } +} + +fn main() { + let w = Wrapper(vec![String::from("hello"), String::from("world")]); + println!("w = {}", w); +} diff --git a/listings/ch19-advanced-features/listing-19-24/Cargo.lock b/listings/ch19-advanced-features/listing-19-24/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-24/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-24/Cargo.toml b/listings/ch19-advanced-features/listing-19-24/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-24/src/main.rs b/listings/ch19-advanced-features/listing-19-24/src/main.rs new file mode 100755 index 0000000..d604ae8 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-24/src/main.rs @@ -0,0 +1,16 @@ +fn main() { + // ANCHOR: here + let f: Box = Box::new(|| println!("hi")); + + fn takes_long_type(f: Box) { + // --snip-- + } + + fn returns_long_type() -> Box { + // --snip-- + // ANCHOR_END: here + Box::new(|| ()) + // ANCHOR: here + } + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-19-25/Cargo.lock b/listings/ch19-advanced-features/listing-19-25/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-25/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-25/Cargo.toml b/listings/ch19-advanced-features/listing-19-25/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-25/src/main.rs b/listings/ch19-advanced-features/listing-19-25/src/main.rs new file mode 100755 index 0000000..af35bed --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-25/src/main.rs @@ -0,0 +1,18 @@ +fn main() { + // ANCHOR: here + type Thunk = Box; + + let f: Thunk = Box::new(|| println!("hi")); + + fn takes_long_type(f: Thunk) { + // --snip-- + } + + fn returns_long_type() -> Thunk { + // --snip-- + // ANCHOR_END: here + Box::new(|| ()) + // ANCHOR: here + } + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/listing-19-27/Cargo.lock b/listings/ch19-advanced-features/listing-19-27/Cargo.lock new file mode 100755 index 0000000..b2327c7 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-27/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-27/Cargo.toml b/listings/ch19-advanced-features/listing-19-27/Cargo.toml new file mode 100755 index 0000000..b196f35 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-27/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-27/src/main.rs b/listings/ch19-advanced-features/listing-19-27/src/main.rs new file mode 100755 index 0000000..91b2cf0 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-27/src/main.rs @@ -0,0 +1,13 @@ +fn add_one(x: i32) -> i32 { + x + 1 +} + +fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 { + f(arg) + f(arg) +} + +fn main() { + let answer = do_twice(add_one, 5); + + println!("The answer is: {}", answer); +} diff --git a/listings/ch19-advanced-features/listing-19-28/Cargo.lock b/listings/ch19-advanced-features/listing-19-28/Cargo.lock new file mode 100755 index 0000000..b2d9257 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-28/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "macros-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-28/Cargo.toml b/listings/ch19-advanced-features/listing-19-28/Cargo.toml new file mode 100755 index 0000000..9218091 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-28/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "macros-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-28/src/lib.rs b/listings/ch19-advanced-features/listing-19-28/src/lib.rs new file mode 100755 index 0000000..7c7c475 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-28/src/lib.rs @@ -0,0 +1,12 @@ +#[macro_export] +macro_rules! vec { + ( $( $x:expr ),* ) => { + { + let mut temp_vec = Vec::new(); + $( + temp_vec.push($x); + )* + temp_vec + } + }; +} diff --git a/listings/ch19-advanced-features/listing-19-30/Cargo.lock b/listings/ch19-advanced-features/listing-19-30/Cargo.lock new file mode 100755 index 0000000..39afcf2 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-30/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-30/Cargo.toml b/listings/ch19-advanced-features/listing-19-30/Cargo.toml new file mode 100755 index 0000000..c6fb920 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-30/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello_macro" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-30/src/main.rs b/listings/ch19-advanced-features/listing-19-30/src/main.rs new file mode 100755 index 0000000..468c30a --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-30/src/main.rs @@ -0,0 +1,9 @@ +use hello_macro::HelloMacro; +use hello_macro_derive::HelloMacro; + +#[derive(HelloMacro)] +struct Pancakes; + +fn main() { + Pancakes::hello_macro(); +} diff --git a/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.lock b/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.lock new file mode 100755 index 0000000..39afcf2 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.toml b/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.toml new file mode 100755 index 0000000..c6fb920 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello_macro" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.lock b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.lock new file mode 100755 index 0000000..9a38c8a --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.lock @@ -0,0 +1,46 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.toml b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.toml new file mode 100755 index 0000000..aa076ac --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +syn = "1.0" +quote = "1.0" diff --git a/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs new file mode 100755 index 0000000..4bcec44 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs @@ -0,0 +1,15 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use quote::quote; +use syn; + +#[proc_macro_derive(HelloMacro)] +pub fn hello_macro_derive(input: TokenStream) -> TokenStream { + // Construct a representation of Rust code as a syntax tree + // that we can manipulate + let ast = syn::parse(input).unwrap(); + + // Build the trait implementation + impl_hello_macro(&ast) +} diff --git a/listings/ch19-advanced-features/listing-19-31/hello_macro/src/lib.rs b/listings/ch19-advanced-features/listing-19-31/hello_macro/src/lib.rs new file mode 100755 index 0000000..e747931 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/src/lib.rs @@ -0,0 +1,3 @@ +pub trait HelloMacro { + fn hello_macro(); +} diff --git a/listings/ch19-advanced-features/listing-19-31/hello_macro/src/main.rs b/listings/ch19-advanced-features/listing-19-31/hello_macro/src/main.rs new file mode 100755 index 0000000..10b028b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/src/main.rs @@ -0,0 +1,13 @@ +use hello_macro::HelloMacro; + +struct Pancakes; + +impl HelloMacro for Pancakes { + fn hello_macro() { + println!("Hello, Macro! My name is Pancakes!"); + } +} + +fn main() { + Pancakes::hello_macro(); +} diff --git a/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.lock b/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.lock new file mode 100755 index 0000000..39afcf2 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.toml b/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.toml new file mode 100755 index 0000000..c6fb920 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello_macro" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.lock b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.lock new file mode 100755 index 0000000..9a38c8a --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.lock @@ -0,0 +1,46 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.toml b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.toml new file mode 100755 index 0000000..aa076ac --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +syn = "1.0" +quote = "1.0" diff --git a/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs new file mode 100755 index 0000000..591f0c3 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs @@ -0,0 +1,29 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use quote::quote; +use syn; + +#[proc_macro_derive(HelloMacro)] +pub fn hello_macro_derive(input: TokenStream) -> TokenStream { + // Construct a representation of Rust code as a syntax tree + // that we can manipulate + let ast = syn::parse(input).unwrap(); + + // Build the trait implementation + impl_hello_macro(&ast) +} + +// ANCHOR: here +fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream { + let name = &ast.ident; + let gen = quote! { + impl HelloMacro for #name { + fn hello_macro() { + println!("Hello, Macro! My name is {}!", stringify!(#name)); + } + } + }; + gen.into() +} +// ANCHOR_END: here diff --git a/listings/ch19-advanced-features/listing-19-33/hello_macro/src/lib.rs b/listings/ch19-advanced-features/listing-19-33/hello_macro/src/lib.rs new file mode 100755 index 0000000..e747931 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/src/lib.rs @@ -0,0 +1,3 @@ +pub trait HelloMacro { + fn hello_macro(); +} diff --git a/listings/ch19-advanced-features/listing-19-33/hello_macro/src/main.rs b/listings/ch19-advanced-features/listing-19-33/hello_macro/src/main.rs new file mode 100755 index 0000000..10b028b --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/src/main.rs @@ -0,0 +1,13 @@ +use hello_macro::HelloMacro; + +struct Pancakes; + +impl HelloMacro for Pancakes { + fn hello_macro() { + println!("Hello, Macro! My name is Pancakes!"); + } +} + +fn main() { + Pancakes::hello_macro(); +} diff --git a/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.toml b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-01-unsafe-fn/src/main.rs b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/src/main.rs new file mode 100755 index 0000000..21ecdbe --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + unsafe fn dangerous() {} + + unsafe { + dangerous(); + } + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.toml b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt new file mode 100755 index 0000000..0991f10 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt @@ -0,0 +1,18 @@ +$ cargo run + Compiling traits-example v0.1.0 (file:///projects/traits-example) +error[E0277]: `Point` doesn't implement `std::fmt::Display` + --> src/main.rs:20:6 + | +20 | impl OutlinePrint for Point {} + | ^^^^^^^^^^^^ `Point` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Point` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `OutlinePrint` + --> src/main.rs:3:21 + | +3 | trait OutlinePrint: fmt::Display { + | ^^^^^^^^^^^^ required by this bound in `OutlinePrint` + +For more information about this error, try `rustc --explain E0277`. +error: could not compile `traits-example` due to previous error diff --git a/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs new file mode 100755 index 0000000..a1e2fe4 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs @@ -0,0 +1,27 @@ +use std::fmt; + +trait OutlinePrint: fmt::Display { + fn outline_print(&self) { + let output = self.to_string(); + let len = output.len(); + println!("{}", "*".repeat(len + 4)); + println!("*{}*", " ".repeat(len + 2)); + println!("* {} *", output); + println!("*{}*", " ".repeat(len + 2)); + println!("{}", "*".repeat(len + 4)); + } +} + +// ANCHOR: here +struct Point { + x: i32, + y: i32, +} + +impl OutlinePrint for Point {} +// ANCHOR_END: here + +fn main() { + let p = Point { x: 1, y: 3 }; + p.outline_print(); +} diff --git a/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.toml b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs new file mode 100755 index 0000000..c7bbb6a --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs @@ -0,0 +1,33 @@ +trait OutlinePrint: fmt::Display { + fn outline_print(&self) { + let output = self.to_string(); + let len = output.len(); + println!("{}", "*".repeat(len + 4)); + println!("*{}*", " ".repeat(len + 2)); + println!("* {} *", output); + println!("*{}*", " ".repeat(len + 2)); + println!("{}", "*".repeat(len + 4)); + } +} + +struct Point { + x: i32, + y: i32, +} + +impl OutlinePrint for Point {} + +// ANCHOR: here +use std::fmt; + +impl fmt::Display for Point { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "({}, {})", self.x, self.y) + } +} +// ANCHOR_END: here + +fn main() { + let p = Point { x: 1, y: 3 }; + p.outline_print(); +} diff --git a/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.toml b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-04-kilometers-alias/src/main.rs b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/src/main.rs new file mode 100755 index 0000000..d3fe32e --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: there + // ANCHOR: here + type Kilometers = i32; + // ANCHOR_END: here + + let x: i32 = 5; + let y: Kilometers = 5; + + println!("x + y = {}", x + y); + // ANCHOR_END: there +} diff --git a/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock b/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.toml b/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-05-write-trait/src/lib.rs b/listings/ch19-advanced-features/no-listing-05-write-trait/src/lib.rs new file mode 100755 index 0000000..8300dcc --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-05-write-trait/src/lib.rs @@ -0,0 +1,10 @@ +use std::fmt; +use std::io::Error; + +pub trait Write { + fn write(&mut self, buf: &[u8]) -> Result; + fn flush(&mut self) -> Result<(), Error>; + + fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>; + fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Error>; +} diff --git a/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock b/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.toml b/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-06-result-alias/src/lib.rs b/listings/ch19-advanced-features/no-listing-06-result-alias/src/lib.rs new file mode 100755 index 0000000..5735599 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-06-result-alias/src/lib.rs @@ -0,0 +1,15 @@ +use std::fmt; + +// ANCHOR: here +type Result = std::result::Result; +// ANCHOR_END: here + +// ANCHOR: there +pub trait Write { + fn write(&mut self, buf: &[u8]) -> Result; + fn flush(&mut self) -> Result<()>; + + fn write_all(&mut self, buf: &[u8]) -> Result<()>; + fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<()>; +} +// ANCHOR_END: there diff --git a/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock b/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock new file mode 100755 index 0000000..b1977d0 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "traits-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.toml b/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.toml new file mode 100755 index 0000000..52395a5 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "traits-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-07-never-type/src/lib.rs b/listings/ch19-advanced-features/no-listing-07-never-type/src/lib.rs new file mode 100755 index 0000000..f0f7aca --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-07-never-type/src/lib.rs @@ -0,0 +1,8 @@ +// ANCHOR: here +fn bar() -> ! { + // --snip-- + // ANCHOR_END: here + panic!(); + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.toml b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs new file mode 100755 index 0000000..6d56008 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let guess = "3"; + // ANCHOR: here + let guess = match guess.trim().parse() { + Ok(_) => 5, + Err(_) => "hello", + }; + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.toml b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs new file mode 100755 index 0000000..aa4f937 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs @@ -0,0 +1,17 @@ +enum Option { + Some(T), + None, +} + +use crate::Option::*; + +// ANCHOR: here +impl Option { + pub fn unwrap(self) -> T { + match self { + Some(val) => val, + None => panic!("called `Option::unwrap()` on a `None` value"), + } + } +} +// ANCHOR_END: here diff --git a/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.toml b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-10-loop-returns-never/src/main.rs b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/src/main.rs new file mode 100755 index 0000000..e776891 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + print!("forever "); + + loop { + print!("and ever "); + } + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock b/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.toml b/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs b/listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs new file mode 100755 index 0000000..075d511 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + // ANCHOR: here + let s1: str = "Hello there!"; + let s2: str = "How's it going?"; + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.toml b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/src/lib.rs b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/src/lib.rs new file mode 100755 index 0000000..69186dd --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/src/lib.rs @@ -0,0 +1,3 @@ +fn generic(t: T) { + // --snip-- +} diff --git a/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.toml b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/src/lib.rs b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/src/lib.rs new file mode 100755 index 0000000..c2d00e2 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/src/lib.rs @@ -0,0 +1,3 @@ +fn generic(t: T) { + // --snip-- +} diff --git a/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock new file mode 100755 index 0000000..c0c98a7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "types-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.toml b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.toml new file mode 100755 index 0000000..a2ae20c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "types-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/src/lib.rs b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/src/lib.rs new file mode 100755 index 0000000..e472226 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/src/lib.rs @@ -0,0 +1,3 @@ +fn generic(t: &T) { + // --snip-- +} diff --git a/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.lock b/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.lock new file mode 100755 index 0000000..b2327c7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.toml b/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.toml new file mode 100755 index 0000000..b196f35 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-15-map-closure/src/main.rs b/listings/ch19-advanced-features/no-listing-15-map-closure/src/main.rs new file mode 100755 index 0000000..b4fcf7e --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-15-map-closure/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + let list_of_numbers = vec![1, 2, 3]; + let list_of_strings: Vec = + list_of_numbers.iter().map(|i| i.to_string()).collect(); + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock b/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock new file mode 100755 index 0000000..b2327c7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.toml b/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.toml new file mode 100755 index 0000000..b196f35 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-16-map-function/src/main.rs b/listings/ch19-advanced-features/no-listing-16-map-function/src/main.rs new file mode 100755 index 0000000..dff20fe --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-16-map-function/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + let list_of_numbers = vec![1, 2, 3]; + let list_of_strings: Vec = + list_of_numbers.iter().map(ToString::to_string).collect(); + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock b/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock new file mode 100755 index 0000000..b2327c7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.toml b/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.toml new file mode 100755 index 0000000..b196f35 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs b/listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs new file mode 100755 index 0000000..60fb730 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + enum Status { + Value(u32), + Stop, + } + + let list_of_statuses: Vec = (0u32..20).map(Status::Value).collect(); + // ANCHOR_END: here +} diff --git a/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock b/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock new file mode 100755 index 0000000..b2327c7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.toml b/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.toml new file mode 100755 index 0000000..b196f35 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt b/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt new file mode 100755 index 0000000..d6fffc9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt @@ -0,0 +1,16 @@ +$ cargo build + Compiling functions-example v0.1.0 (file:///projects/functions-example) +error[E0746]: return type cannot have an unboxed trait object + --> src/lib.rs:1:25 + | +1 | fn returns_closure() -> dyn Fn(i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: use `impl Fn(i32) -> i32` as the return type, as all return paths are of type `[closure@src/lib.rs:2:5: 2:14]`, which implements `Fn(i32) -> i32` + | +1 | fn returns_closure() -> impl Fn(i32) -> i32 { + | ~~~~~~~~~~~~~~~~~~~ + +For more information about this error, try `rustc --explain E0746`. +error: could not compile `functions-example` due to previous error diff --git a/listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs b/listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs new file mode 100755 index 0000000..d699ac3 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs @@ -0,0 +1,3 @@ +fn returns_closure() -> dyn Fn(i32) -> i32 { + |x| x + 1 +} diff --git a/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock new file mode 100755 index 0000000..b2327c7 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "functions-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml new file mode 100755 index 0000000..b196f35 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "functions-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/src/lib.rs b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/src/lib.rs new file mode 100755 index 0000000..b114077 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/src/lib.rs @@ -0,0 +1,3 @@ +fn returns_closure() -> Box i32> { + Box::new(|x| x + 1) +} diff --git a/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock new file mode 100755 index 0000000..39afcf2 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.toml b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.toml new file mode 100755 index 0000000..c6fb920 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello_macro" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs new file mode 100755 index 0000000..e747931 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs @@ -0,0 +1,3 @@ +pub trait HelloMacro { + fn hello_macro(); +} diff --git a/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.lock b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.lock new file mode 100755 index 0000000..881cd3f --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.lock @@ -0,0 +1,13 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro" +version = "0.1.0" + +[[package]] +name = "pancakes" +version = "0.1.0" +dependencies = [ + "hello_macro 0.1.0", +] + diff --git a/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.toml b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.toml new file mode 100755 index 0000000..3ad9108 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "pancakes" +version = "0.1.0" +edition = "2021" + +[dependencies] +hello_macro = { path = "../hello_macro" } \ No newline at end of file diff --git a/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs new file mode 100755 index 0000000..10b028b --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs @@ -0,0 +1,13 @@ +use hello_macro::HelloMacro; + +struct Pancakes; + +impl HelloMacro for Pancakes { + fn hello_macro() { + println!("Hello, Macro! My name is Pancakes!"); + } +} + +fn main() { + Pancakes::hello_macro(); +} diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock new file mode 100755 index 0000000..39afcf2 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.toml b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.toml new file mode 100755 index 0000000..c6fb920 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello_macro" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.lock b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.lock new file mode 100755 index 0000000..9a38c8a --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.lock @@ -0,0 +1,46 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.toml b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.toml new file mode 100755 index 0000000..aa076ac --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +syn = "1.0" +quote = "1.0" diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/src/lib.rs b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/src/lib.rs new file mode 100755 index 0000000..7a3279d --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/src/lib.rs @@ -0,0 +1,27 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use quote::quote; +use syn; + +#[proc_macro_derive(HelloMacro)] +pub fn hello_macro_derive(input: TokenStream) -> TokenStream { + // Construct a representation of Rust code as a syntax tree + // that we can manipulate + let ast = syn::parse(input).unwrap(); + + // Build the trait implementation + impl_hello_macro(&ast) +} + +fn impl_hello_macro(ast: &syn::DeriveInput) -> TokenStream { + let name = &ast.ident; + let gen = quote! { + impl HelloMacro for #name { + fn hello_macro() { + println!("Hello, Macro! My name is {}!", stringify!(#name)); + } + } + }; + gen.into() +} diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/lib.rs b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/lib.rs new file mode 100755 index 0000000..e747931 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/lib.rs @@ -0,0 +1,3 @@ +pub trait HelloMacro { + fn hello_macro(); +} diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/main.rs b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/main.rs new file mode 100755 index 0000000..10b028b --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/main.rs @@ -0,0 +1,13 @@ +use hello_macro::HelloMacro; + +struct Pancakes; + +impl HelloMacro for Pancakes { + fn hello_macro() { + println!("Hello, Macro! My name is Pancakes!"); + } +} + +fn main() { + Pancakes::hello_macro(); +} diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.lock b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.lock new file mode 100755 index 0000000..dee23ec --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.lock @@ -0,0 +1,58 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "hello_macro" +version = "0.1.0" + +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pancakes" +version = "0.1.0" +dependencies = [ + "hello_macro 0.1.0", + "hello_macro_derive 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.toml b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.toml new file mode 100755 index 0000000..cb3a98c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "pancakes" +version = "0.1.0" +edition = "2021" + +[dependencies] +hello_macro = { path = "../hello_macro" } +hello_macro_derive = { path = "../hello_macro/hello_macro_derive" } diff --git a/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/src/main.rs b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/src/main.rs new file mode 100755 index 0000000..468c30a --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/src/main.rs @@ -0,0 +1,9 @@ +use hello_macro::HelloMacro; +use hello_macro_derive::HelloMacro; + +#[derive(HelloMacro)] +struct Pancakes; + +fn main() { + Pancakes::hello_macro(); +} diff --git a/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock b/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock new file mode 100755 index 0000000..497817b --- /dev/null +++ b/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "unsafe-example" +version = "0.1.0" + diff --git a/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.toml b/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.toml new file mode 100755 index 0000000..3e8a292 --- /dev/null +++ b/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt b/listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt new file mode 100755 index 0000000..5886bc6 --- /dev/null +++ b/listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt @@ -0,0 +1,12 @@ +$ cargo run + Compiling unsafe-example v0.1.0 (file:///projects/unsafe-example) +error[E0133]: call to unsafe function is unsafe and requires unsafe function or block + --> src/main.rs:4:5 + | +4 | dangerous(); + | ^^^^^^^^^^^ call to unsafe function + | + = note: consult the function's documentation for information on how to avoid undefined behavior + +For more information about this error, try `rustc --explain E0133`. +error: could not compile `unsafe-example` due to previous error diff --git a/listings/ch19-advanced-features/output-only-01-missing-unsafe/src/main.rs b/listings/ch19-advanced-features/output-only-01-missing-unsafe/src/main.rs new file mode 100755 index 0000000..01305be --- /dev/null +++ b/listings/ch19-advanced-features/output-only-01-missing-unsafe/src/main.rs @@ -0,0 +1,7 @@ +fn main() { + // ANCHOR: here + unsafe fn dangerous() {} + + dangerous(); + // ANCHOR_END: here +} diff --git a/listings/ch20-web-server/listing-20-01/Cargo.lock b/listings/ch20-web-server/listing-20-01/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-01/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-01/Cargo.toml b/listings/ch20-web-server/listing-20-01/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-01/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-01/src/main.rs b/listings/ch20-web-server/listing-20-01/src/main.rs new file mode 100755 index 0000000..d868c3e --- /dev/null +++ b/listings/ch20-web-server/listing-20-01/src/main.rs @@ -0,0 +1,11 @@ +use std::net::TcpListener; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + println!("Connection established!"); + } +} diff --git a/listings/ch20-web-server/listing-20-02/Cargo.lock b/listings/ch20-web-server/listing-20-02/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-02/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-02/Cargo.toml b/listings/ch20-web-server/listing-20-02/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-02/src/main.rs b/listings/ch20-web-server/listing-20-02/src/main.rs new file mode 100755 index 0000000..2e68f2f --- /dev/null +++ b/listings/ch20-web-server/listing-20-02/src/main.rs @@ -0,0 +1,21 @@ +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + + stream.read(&mut buffer).unwrap(); + + println!("Request: {}", String::from_utf8_lossy(&buffer[..])); +} diff --git a/listings/ch20-web-server/listing-20-03/Cargo.lock b/listings/ch20-web-server/listing-20-03/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-03/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-03/Cargo.toml b/listings/ch20-web-server/listing-20-03/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-03/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-03/src/main.rs b/listings/ch20-web-server/listing-20-03/src/main.rs new file mode 100755 index 0000000..afa579a --- /dev/null +++ b/listings/ch20-web-server/listing-20-03/src/main.rs @@ -0,0 +1,26 @@ +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +// ANCHOR: here +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + + stream.read(&mut buffer).unwrap(); + + let response = "HTTP/1.1 200 OK\r\n\r\n"; + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-04/Cargo.lock b/listings/ch20-web-server/listing-20-04/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-04/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-04/Cargo.toml b/listings/ch20-web-server/listing-20-04/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-04/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-04/hello.html b/listings/ch20-web-server/listing-20-04/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-04/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-04/src/main.rs b/listings/ch20-web-server/listing-20-04/src/main.rs new file mode 100755 index 0000000..818eac9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-04/src/main.rs @@ -0,0 +1,24 @@ +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + + stream.read(&mut buffer).unwrap(); + + let response = "HTTP/1.1 200 OK\r\n\r\n"; + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-05/Cargo.lock b/listings/ch20-web-server/listing-20-05/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-05/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-05/Cargo.toml b/listings/ch20-web-server/listing-20-05/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-05/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-05/hello.html b/listings/ch20-web-server/listing-20-05/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-05/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-05/src/main.rs b/listings/ch20-web-server/listing-20-05/src/main.rs new file mode 100755 index 0000000..d20417c --- /dev/null +++ b/listings/ch20-web-server/listing-20-05/src/main.rs @@ -0,0 +1,36 @@ +// ANCHOR: here +use std::fs; +// --snip-- + +// ANCHOR_END: here +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +// ANCHOR: here +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let contents = fs::read_to_string("hello.html").unwrap(); + + let response = format!( + "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-06/Cargo.lock b/listings/ch20-web-server/listing-20-06/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-06/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-06/Cargo.toml b/listings/ch20-web-server/listing-20-06/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-06/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-06/hello.html b/listings/ch20-web-server/listing-20-06/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-06/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-06/src/main.rs b/listings/ch20-web-server/listing-20-06/src/main.rs new file mode 100755 index 0000000..8353244 --- /dev/null +++ b/listings/ch20-web-server/listing-20-06/src/main.rs @@ -0,0 +1,40 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +// ANCHOR: here +// --snip-- + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + + if buffer.starts_with(get) { + let contents = fs::read_to_string("hello.html").unwrap(); + + let response = format!( + "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + } else { + // some other request + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-07/Cargo.lock b/listings/ch20-web-server/listing-20-07/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-07/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-07/Cargo.toml b/listings/ch20-web-server/listing-20-07/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-07/hello.html b/listings/ch20-web-server/listing-20-07/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-07/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-07/src/main.rs b/listings/ch20-web-server/listing-20-07/src/main.rs new file mode 100755 index 0000000..4d19e04 --- /dev/null +++ b/listings/ch20-web-server/listing-20-07/src/main.rs @@ -0,0 +1,50 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + + if buffer.starts_with(get) { + let contents = fs::read_to_string("hello.html").unwrap(); + + let response = format!( + "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + // ANCHOR: here + // --snip-- + } else { + let status_line = "HTTP/1.1 404 NOT FOUND"; + let contents = fs::read_to_string("404.html").unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + } + // ANCHOR_END: here +} diff --git a/listings/ch20-web-server/listing-20-08/404.html b/listings/ch20-web-server/listing-20-08/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-08/Cargo.lock b/listings/ch20-web-server/listing-20-08/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-08/Cargo.toml b/listings/ch20-web-server/listing-20-08/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-08/hello.html b/listings/ch20-web-server/listing-20-08/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-08/src/main.rs b/listings/ch20-web-server/listing-20-08/src/main.rs new file mode 100755 index 0000000..6dfaa97 --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/src/main.rs @@ -0,0 +1,47 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + + if buffer.starts_with(get) { + let contents = fs::read_to_string("hello.html").unwrap(); + + let response = format!( + "HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + } else { + let status_line = "HTTP/1.1 404 NOT FOUND"; + let contents = fs::read_to_string("404.html").unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + } +} diff --git a/listings/ch20-web-server/listing-20-09/404.html b/listings/ch20-web-server/listing-20-09/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-09/Cargo.lock b/listings/ch20-web-server/listing-20-09/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-09/Cargo.toml b/listings/ch20-web-server/listing-20-09/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-09/hello.html b/listings/ch20-web-server/listing-20-09/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-09/src/main.rs b/listings/ch20-web-server/listing-20-09/src/main.rs new file mode 100755 index 0000000..e2f2f9f --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/src/main.rs @@ -0,0 +1,47 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} + +// ANCHOR: here +// --snip-- + +fn handle_connection(mut stream: TcpStream) { + // --snip-- + + // ANCHOR_END: here + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + + // ANCHOR: here + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-10/404.html b/listings/ch20-web-server/listing-20-10/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-10/Cargo.lock b/listings/ch20-web-server/listing-20-10/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-10/Cargo.toml b/listings/ch20-web-server/listing-20-10/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-10/hello.html b/listings/ch20-web-server/listing-20-10/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-10/src/main.rs b/listings/ch20-web-server/listing-20-10/src/main.rs new file mode 100755 index 0000000..c4361e5 --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/src/main.rs @@ -0,0 +1,58 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +// ANCHOR: here +use std::thread; +use std::time::Duration; +// --snip-- +// ANCHOR_END: here + +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + handle_connection(stream); + } +} +// ANCHOR: here + +fn handle_connection(mut stream: TcpStream) { + // --snip-- + + // ANCHOR_END: here + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + // ANCHOR: here + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + // --snip-- + // ANCHOR_END: here + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-11/404.html b/listings/ch20-web-server/listing-20-11/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-11/Cargo.lock b/listings/ch20-web-server/listing-20-11/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-11/Cargo.toml b/listings/ch20-web-server/listing-20-11/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-11/hello.html b/listings/ch20-web-server/listing-20-11/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-11/src/main.rs b/listings/ch20-web-server/listing-20-11/src/main.rs new file mode 100755 index 0000000..bf88f94 --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/src/main.rs @@ -0,0 +1,49 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::time::Duration; + +// ANCHOR: here +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + + for stream in listener.incoming() { + let stream = stream.unwrap(); + + thread::spawn(|| { + handle_connection(stream); + }); + } +} +// ANCHOR_END: here + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-12/404.html b/listings/ch20-web-server/listing-20-12/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-12/Cargo.lock b/listings/ch20-web-server/listing-20-12/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-12/Cargo.toml b/listings/ch20-web-server/listing-20-12/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-12/hello.html b/listings/ch20-web-server/listing-20-12/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-12/output.txt b/listings/ch20-web-server/listing-20-12/output.txt new file mode 100755 index 0000000..d320061 --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/output.txt @@ -0,0 +1,10 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0433]: failed to resolve: use of undeclared type `ThreadPool` + --> src/main.rs:10:16 + | +10 | let pool = ThreadPool::new(4); + | ^^^^^^^^^^ use of undeclared type `ThreadPool` + +For more information about this error, try `rustc --explain E0433`. +error: could not compile `hello` due to previous error diff --git a/listings/ch20-web-server/listing-20-12/src/main.rs b/listings/ch20-web-server/listing-20-12/src/main.rs new file mode 100755 index 0000000..ff0fd45 --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/src/main.rs @@ -0,0 +1,50 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::time::Duration; + +// ANCHOR: here +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); + }); + } +} +// ANCHOR_END: here + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-13/404.html b/listings/ch20-web-server/listing-20-13/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-13/Cargo.lock b/listings/ch20-web-server/listing-20-13/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-13/Cargo.toml b/listings/ch20-web-server/listing-20-13/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-13/hello.html b/listings/ch20-web-server/listing-20-13/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-13/src/bin/main.rs b/listings/ch20-web-server/listing-20-13/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-13/src/lib.rs b/listings/ch20-web-server/listing-20-13/src/lib.rs new file mode 100755 index 0000000..e60c902 --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/src/lib.rs @@ -0,0 +1,28 @@ +pub struct ThreadPool; + +// ANCHOR: here +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); + + ThreadPool + } + + // --snip-- + // ANCHOR_END: here + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + } + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-14/404.html b/listings/ch20-web-server/listing-20-14/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-14/Cargo.lock b/listings/ch20-web-server/listing-20-14/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-14/Cargo.toml b/listings/ch20-web-server/listing-20-14/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-14/hello.html b/listings/ch20-web-server/listing-20-14/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-14/src/bin/main.rs b/listings/ch20-web-server/listing-20-14/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-14/src/lib.rs b/listings/ch20-web-server/listing-20-14/src/lib.rs new file mode 100755 index 0000000..509a62e --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/src/lib.rs @@ -0,0 +1,41 @@ +// ANCHOR: here +use std::thread; + +pub struct ThreadPool { + threads: Vec>, +} + +impl ThreadPool { + // --snip-- + // ANCHOR_END: here + /// 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. + // ANCHOR: here + pub fn new(size: usize) -> ThreadPool { + assert!(size > 0); + + let mut threads = Vec::with_capacity(size); + + for _ in 0..size { + // create some threads and store them in the vector + } + + ThreadPool { threads } + } + + // --snip-- + // ANCHOR_END: here + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + } + // ANCHOR: here +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-15/404.html b/listings/ch20-web-server/listing-20-15/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-15/Cargo.lock b/listings/ch20-web-server/listing-20-15/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-15/Cargo.toml b/listings/ch20-web-server/listing-20-15/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-15/hello.html b/listings/ch20-web-server/listing-20-15/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-15/src/bin/main.rs b/listings/ch20-web-server/listing-20-15/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-15/src/lib.rs b/listings/ch20-web-server/listing-20-15/src/lib.rs new file mode 100755 index 0000000..80a6eee --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/src/lib.rs @@ -0,0 +1,53 @@ +// ANCHOR: here +use std::thread; + +pub struct ThreadPool { + workers: Vec, +} + +impl ThreadPool { + // --snip-- + // ANCHOR_END: here + /// 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. + // ANCHOR: here + pub fn new(size: usize) -> ThreadPool { + assert!(size > 0); + + let mut workers = Vec::with_capacity(size); + + for id in 0..size { + workers.push(Worker::new(id)); + } + + ThreadPool { workers } + } + // --snip-- + // ANCHOR_END: here + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + } + // ANCHOR: here +} + +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} + +impl Worker { + fn new(id: usize) -> Worker { + let thread = thread::spawn(|| {}); + + Worker { id, thread } + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-16/404.html b/listings/ch20-web-server/listing-20-16/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-16/Cargo.lock b/listings/ch20-web-server/listing-20-16/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-16/Cargo.toml b/listings/ch20-web-server/listing-20-16/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-16/hello.html b/listings/ch20-web-server/listing-20-16/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-16/src/bin/main.rs b/listings/ch20-web-server/listing-20-16/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-16/src/lib.rs b/listings/ch20-web-server/listing-20-16/src/lib.rs new file mode 100755 index 0000000..02d20cb --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/src/lib.rs @@ -0,0 +1,60 @@ +use std::thread; +// ANCHOR: here +// --snip-- +use std::sync::mpsc; + +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +struct Job; + +impl ThreadPool { + // --snip-- + // ANCHOR_END: here + /// 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. + // ANCHOR: here + pub fn new(size: usize) -> ThreadPool { + assert!(size > 0); + + let (sender, receiver) = mpsc::channel(); + + let mut workers = Vec::with_capacity(size); + + for id in 0..size { + workers.push(Worker::new(id)); + } + + ThreadPool { workers, sender } + } + // --snip-- + // ANCHOR_END: here + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + } + // ANCHOR: here +} +// ANCHOR_END: here + +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} + +impl Worker { + fn new(id: usize) -> Worker { + let thread = thread::spawn(|| {}); + + Worker { id, thread } + } +} diff --git a/listings/ch20-web-server/listing-20-17/404.html b/listings/ch20-web-server/listing-20-17/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-17/Cargo.lock b/listings/ch20-web-server/listing-20-17/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-17/Cargo.toml b/listings/ch20-web-server/listing-20-17/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-17/hello.html b/listings/ch20-web-server/listing-20-17/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-17/output.txt b/listings/ch20-web-server/listing-20-17/output.txt new file mode 100755 index 0000000..da2301e --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/output.txt @@ -0,0 +1,13 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0382]: use of moved value: `receiver` + --> src/lib.rs:27:42 + | +22 | let (sender, receiver) = mpsc::channel(); + | -------- move occurs because `receiver` has type `std::sync::mpsc::Receiver`, which does not implement the `Copy` trait +... +27 | workers.push(Worker::new(id, receiver)); + | ^^^^^^^^ value moved here, in previous iteration of loop + +For more information about this error, try `rustc --explain E0382`. +error: could not compile `hello` due to previous error diff --git a/listings/ch20-web-server/listing-20-17/src/bin/main.rs b/listings/ch20-web-server/listing-20-17/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-17/src/lib.rs b/listings/ch20-web-server/listing-20-17/src/lib.rs new file mode 100755 index 0000000..f3ce7d0 --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/src/lib.rs @@ -0,0 +1,66 @@ +use std::sync::mpsc; +use std::thread; + +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +struct Job; + +// ANCHOR: here +impl ThreadPool { + // --snip-- + // ANCHOR_END: here + /// 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. + // ANCHOR: here + pub fn new(size: usize) -> ThreadPool { + assert!(size > 0); + + let (sender, receiver) = mpsc::channel(); + + let mut workers = Vec::with_capacity(size); + + for id in 0..size { + workers.push(Worker::new(id, receiver)); + } + + ThreadPool { workers, sender } + } + // --snip-- + // ANCHOR_END: here + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + } + // ANCHOR: here +} + +// --snip-- + +// ANCHOR_END: here + +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} + +// ANCHOR: here +impl Worker { + fn new(id: usize, receiver: mpsc::Receiver) -> Worker { + let thread = thread::spawn(|| { + receiver; + }); + + Worker { id, thread } + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-18/404.html b/listings/ch20-web-server/listing-20-18/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-18/Cargo.lock b/listings/ch20-web-server/listing-20-18/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-18/Cargo.toml b/listings/ch20-web-server/listing-20-18/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-18/hello.html b/listings/ch20-web-server/listing-20-18/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-18/src/bin/main.rs b/listings/ch20-web-server/listing-20-18/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-18/src/lib.rs b/listings/ch20-web-server/listing-20-18/src/lib.rs new file mode 100755 index 0000000..8197353 --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/src/lib.rs @@ -0,0 +1,76 @@ +use std::sync::mpsc; +use std::thread; +// ANCHOR: here +use std::sync::Arc; +use std::sync::Mutex; +// --snip-- + +// ANCHOR_END: here +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +struct Job; + +// ANCHOR: here +impl ThreadPool { + // --snip-- + // ANCHOR_END: here + /// 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. + // ANCHOR: here + 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 } + } + + // --snip-- + // ANCHOR_END: here + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + } + // ANCHOR: here +} + +// --snip-- + +// ANCHOR_END: here +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} + +// ANCHOR: here +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + // --snip-- + // ANCHOR_END: here + let thread = thread::spawn(|| { + receiver; + }); + + Worker { id, thread } + // ANCHOR: here + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-19/404.html b/listings/ch20-web-server/listing-20-19/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-19/Cargo.lock b/listings/ch20-web-server/listing-20-19/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-19/Cargo.toml b/listings/ch20-web-server/listing-20-19/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-19/hello.html b/listings/ch20-web-server/listing-20-19/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-19/src/bin/main.rs b/listings/ch20-web-server/listing-20-19/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-19/src/lib.rs b/listings/ch20-web-server/listing-20-19/src/lib.rs new file mode 100755 index 0000000..734d4c2 --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/src/lib.rs @@ -0,0 +1,69 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; + +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +// ANCHOR: here +// --snip-- + +type Job = Box; + +impl ThreadPool { + // --snip-- + // ANCHOR_END: here + /// 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 } + } + // ANCHOR: here + + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + let job = Box::new(f); + + self.sender.send(job).unwrap(); + } +} + +// --snip-- +// ANCHOR_END: here + +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(|| { + receiver; + }); + + Worker { id, thread } + } +} diff --git a/listings/ch20-web-server/listing-20-20/404.html b/listings/ch20-web-server/listing-20-20/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-20/Cargo.lock b/listings/ch20-web-server/listing-20-20/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-20/Cargo.toml b/listings/ch20-web-server/listing-20-20/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-20/hello.html b/listings/ch20-web-server/listing-20-20/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-20/src/bin/main.rs b/listings/ch20-web-server/listing-20-20/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-20/src/lib.rs b/listings/ch20-web-server/listing-20-20/src/lib.rs new file mode 100755 index 0000000..5fdc32e --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/src/lib.rs @@ -0,0 +1,68 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::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(); + } +} + +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} + +// ANCHOR: here +// --snip-- + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let job = receiver.lock().unwrap().recv().unwrap(); + + println!("Worker {} got a job; executing.", id); + + job(); + }); + + Worker { id, thread } + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-21/404.html b/listings/ch20-web-server/listing-20-21/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-21/Cargo.lock b/listings/ch20-web-server/listing-20-21/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-21/Cargo.toml b/listings/ch20-web-server/listing-20-21/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-21/hello.html b/listings/ch20-web-server/listing-20-21/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-21/src/bin/main.rs b/listings/ch20-web-server/listing-20-21/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-21/src/lib.rs b/listings/ch20-web-server/listing-20-21/src/lib.rs new file mode 100755 index 0000000..6bde524 --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/src/lib.rs @@ -0,0 +1,67 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::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(); + } +} + +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} +// ANCHOR: here +// --snip-- + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || { + while let Ok(job) = receiver.lock().unwrap().recv() { + println!("Worker {} got a job; executing.", id); + + job(); + } + }); + + Worker { id, thread } + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-22/404.html b/listings/ch20-web-server/listing-20-22/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-22/Cargo.lock b/listings/ch20-web-server/listing-20-22/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-22/Cargo.toml b/listings/ch20-web-server/listing-20-22/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-22/hello.html b/listings/ch20-web-server/listing-20-22/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-22/output.txt b/listings/ch20-web-server/listing-20-22/output.txt new file mode 100755 index 0000000..39801ac --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/output.txt @@ -0,0 +1,10 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0507]: cannot move out of `worker.thread` which is behind a mutable reference + --> src/lib.rs:52:13 + | +52 | worker.thread.join().unwrap(); + | ^^^^^^^^^^^^^ move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait + +For more information about this error, try `rustc --explain E0507`. +error: could not compile `hello` due to previous error diff --git a/listings/ch20-web-server/listing-20-22/src/bin/main.rs b/listings/ch20-web-server/listing-20-22/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-22/src/lib.rs b/listings/ch20-web-server/listing-20-22/src/lib.rs new file mode 100755 index 0000000..8242578 --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/src/lib.rs @@ -0,0 +1,76 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::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(); + } +} + +// ANCHOR: here +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_END: here + +struct Worker { + id: usize, + thread: thread::JoinHandle<()>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let job = receiver.lock().unwrap().recv().unwrap(); + + println!("Worker {} got a job; executing.", id); + + job(); + }); + + Worker { id, thread } + } +} diff --git a/listings/ch20-web-server/listing-20-23/404.html b/listings/ch20-web-server/listing-20-23/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-23/Cargo.lock b/listings/ch20-web-server/listing-20-23/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-23/Cargo.toml b/listings/ch20-web-server/listing-20-23/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-23/hello.html b/listings/ch20-web-server/listing-20-23/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-23/src/bin/main.rs b/listings/ch20-web-server/listing-20-23/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-23/src/lib.rs b/listings/ch20-web-server/listing-20-23/src/lib.rs new file mode 100755 index 0000000..6ccaee7 --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/src/lib.rs @@ -0,0 +1,107 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; + +// ANCHOR: here +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +// --snip-- + +// ANCHOR_END: here +type Job = Box; + +enum Message { + NewJob(Job), + Terminate, +} + +// ANCHOR: here +impl ThreadPool { + // --snip-- + + // ANCHOR_END: here + /// 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 } + } + + // ANCHOR: here + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + let job = Box::new(f); + + self.sender.send(Message::NewJob(job)).unwrap(); + } +} + +// --snip-- + +// ANCHOR_END: here +impl Drop for ThreadPool { + fn drop(&mut self) { + for worker in &mut self.workers { + println!("Shutting down worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} + +struct Worker { + id: usize, + thread: Option>, +} + +// ANCHOR: here +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let message = receiver.lock().unwrap().recv().unwrap(); + + match message { + Message::NewJob(job) => { + println!("Worker {} got a job; executing.", id); + + job(); + } + Message::Terminate => { + println!("Worker {} was told to terminate.", id); + + break; + } + } + }); + + Worker { + id, + thread: Some(thread), + } + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/listing-20-24/404.html b/listings/ch20-web-server/listing-20-24/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-24/Cargo.lock b/listings/ch20-web-server/listing-20-24/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-24/Cargo.toml b/listings/ch20-web-server/listing-20-24/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-24/hello.html b/listings/ch20-web-server/listing-20-24/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-24/src/bin/main.rs b/listings/ch20-web-server/listing-20-24/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-24/src/lib.rs b/listings/ch20-web-server/listing-20-24/src/lib.rs new file mode 100755 index 0000000..747bff2 --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/src/lib.rs @@ -0,0 +1,103 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; + +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +type Job = Box; + +enum Message { + NewJob(Job), + Terminate, +} + +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(Message::NewJob(job)).unwrap(); + } +} + +// ANCHOR: here +impl Drop for ThreadPool { + fn drop(&mut self) { + println!("Sending terminate message to all workers."); + + for _ in &self.workers { + self.sender.send(Message::Terminate).unwrap(); + } + + println!("Shutting down all workers."); + + for worker in &mut self.workers { + println!("Shutting down worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} +// ANCHOR_END: here + +struct Worker { + id: usize, + thread: Option>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let message = receiver.lock().unwrap().recv().unwrap(); + + match message { + Message::NewJob(job) => { + println!("Worker {} got a job; executing.", id); + + job(); + } + Message::Terminate => { + println!("Worker {} was told to terminate.", id); + + break; + } + } + }); + + Worker { + id, + thread: Some(thread), + } + } +} diff --git a/listings/ch20-web-server/listing-20-25/404.html b/listings/ch20-web-server/listing-20-25/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/listing-20-25/Cargo.lock b/listings/ch20-web-server/listing-20-25/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/Cargo.lock @@ -0,0 +1,6 @@ +# 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/listing-20-25/Cargo.toml b/listings/ch20-web-server/listing-20-25/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/listing-20-25/hello.html b/listings/ch20-web-server/listing-20-25/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/listing-20-25/src/bin/main.rs b/listings/ch20-web-server/listing-20-25/src/bin/main.rs new file mode 100755 index 0000000..3b314bc --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/src/bin/main.rs @@ -0,0 +1,53 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::time::Duration; + +// ANCHOR: here +fn main() { + let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); + let pool = ThreadPool::new(4); + + for stream in listener.incoming().take(2) { + let stream = stream.unwrap(); + + pool.execute(|| { + handle_connection(stream); + }); + } + + println!("Shutting down."); +} +// ANCHOR_END: here + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/listing-20-25/src/lib.rs b/listings/ch20-web-server/listing-20-25/src/lib.rs new file mode 100755 index 0000000..68f4263 --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/src/lib.rs @@ -0,0 +1,101 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; + +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +type Job = Box; + +enum Message { + NewJob(Job), + Terminate, +} + +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(Message::NewJob(job)).unwrap(); + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + println!("Sending terminate message to all workers."); + + for _ in &self.workers { + self.sender.send(Message::Terminate).unwrap(); + } + + println!("Shutting down all workers."); + + for worker in &mut self.workers { + println!("Shutting down worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} + +struct Worker { + id: usize, + thread: Option>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let message = receiver.lock().unwrap().recv().unwrap(); + + match message { + Message::NewJob(job) => { + println!("Worker {} got a job; executing.", id); + + job(); + } + Message::Terminate => { + println!("Worker {} was told to terminate.", id); + + break; + } + } + }); + + Worker { + id, + thread: Some(thread), + } + } +} diff --git a/listings/ch20-web-server/no-listing-01-define-threadpool-struct/404.html b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock @@ -0,0 +1,6 @@ +# 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-01-define-threadpool-struct/Cargo.toml b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/no-listing-01-define-threadpool-struct/hello.html b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt new file mode 100755 index 0000000..4cc1d13 --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt @@ -0,0 +1,10 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0599]: no function or associated item named `new` found for struct `ThreadPool` in the current scope + --> src/bin/main.rs:11:28 + | +11 | let pool = ThreadPool::new(4); + | ^^^ function or associated item not found in `ThreadPool` + +For more information about this error, try `rustc --explain E0599`. +error: could not compile `hello` due to previous error diff --git a/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs new file mode 100755 index 0000000..d2b8c88 --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs @@ -0,0 +1,51 @@ +// ANCHOR: here +use hello::ThreadPool; +// ANCHOR_END: here +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/lib.rs b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/lib.rs new file mode 100755 index 0000000..7312e29 --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/lib.rs @@ -0,0 +1 @@ +pub struct ThreadPool; diff --git a/listings/ch20-web-server/no-listing-02-impl-threadpool-new/404.html b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock @@ -0,0 +1,6 @@ +# 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-02-impl-threadpool-new/Cargo.toml b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/no-listing-02-impl-threadpool-new/hello.html b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt new file mode 100755 index 0000000..72d4cd9 --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt @@ -0,0 +1,10 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0599]: no method named `execute` found for struct `ThreadPool` in the current scope + --> src/bin/main.rs:16:14 + | +16 | pool.execute(|| { + | ^^^^^^^ method not found in `ThreadPool` + +For more information about this error, try `rustc --explain E0599`. +error: could not compile `hello` due to previous error diff --git a/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/bin/main.rs b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs new file mode 100755 index 0000000..f0e1890 --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs @@ -0,0 +1,7 @@ +pub struct ThreadPool; + +impl ThreadPool { + pub fn new(size: usize) -> ThreadPool { + ThreadPool + } +} diff --git a/listings/ch20-web-server/no-listing-03-define-execute/404.html b/listings/ch20-web-server/no-listing-03-define-execute/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock b/listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock @@ -0,0 +1,6 @@ +# 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-03-define-execute/Cargo.toml b/listings/ch20-web-server/no-listing-03-define-execute/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/no-listing-03-define-execute/hello.html b/listings/ch20-web-server/no-listing-03-define-execute/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/no-listing-03-define-execute/output.txt b/listings/ch20-web-server/no-listing-03-define-execute/output.txt new file mode 100755 index 0000000..dc76c43 --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/output.txt @@ -0,0 +1,3 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) + Finished dev [unoptimized + debuginfo] target(s) in 0.24s diff --git a/listings/ch20-web-server/no-listing-03-define-execute/src/bin/main.rs b/listings/ch20-web-server/no-listing-03-define-execute/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs b/listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs new file mode 100755 index 0000000..1321ab8 --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs @@ -0,0 +1,18 @@ +pub struct ThreadPool; + +// ANCHOR: here +impl ThreadPool { + // --snip-- + // ANCHOR_END: here + pub fn new(size: usize) -> ThreadPool { + ThreadPool + } + + // ANCHOR: here + pub fn execute(&self, f: F) + where + F: FnOnce() + Send + 'static, + { + } +} +// ANCHOR_END: here 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 new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/404.html @@ -0,0 +1,11 @@ + + + + + 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 new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock @@ -0,0 +1,6 @@ +# 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 new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.toml @@ -0,0 +1,6 @@ +[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 new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/hello.html @@ -0,0 +1,11 @@ + + + + + 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 new file mode 100755 index 0000000..21c726c --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt @@ -0,0 +1,24 @@ +$ 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, 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/bin/main.rs b/listings/ch20-web-server/no-listing-04-update-worker-definition/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} 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 new file mode 100755 index 0000000..1098330 --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs @@ -0,0 +1,76 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::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 {} got a job; executing.", id); + + job(); + }); + + Worker { id, thread } + } +} 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 new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/404.html @@ -0,0 +1,11 @@ + + + + + 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 new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock @@ -0,0 +1,6 @@ +# 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 new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.toml @@ -0,0 +1,6 @@ +[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 new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/no-listing-05-fix-worker-new/src/bin/main.rs b/listings/ch20-web-server/no-listing-05-fix-worker-new/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} 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 new file mode 100755 index 0000000..6bef23a --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs @@ -0,0 +1,83 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::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 {} got a job; executing.", id); + + job(); + }); + + // ANCHOR: here + Worker { + id, + thread: Some(thread), + } + } +} +// ANCHOR_END: here diff --git a/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/404.html b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock @@ -0,0 +1,6 @@ +# 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-06-fix-threadpool-drop/Cargo.toml b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/hello.html b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/bin/main.rs b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().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 new file mode 100755 index 0000000..d5b38a6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs @@ -0,0 +1,81 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::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(); + } +} + +// ANCHOR: here +impl Drop for ThreadPool { + fn drop(&mut self) { + for worker in &mut self.workers { + println!("Shutting down worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} +// ANCHOR_END: here + +struct Worker { + id: usize, + thread: Option>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let job = receiver.lock().unwrap().recv().unwrap(); + + println!("Worker {} got a job; executing.", id); + + job(); + }); + + Worker { + id, + thread: Some(thread), + } + } +} diff --git a/listings/ch20-web-server/no-listing-07-define-message-enum/404.html b/listings/ch20-web-server/no-listing-07-define-message-enum/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.lock b/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.lock @@ -0,0 +1,6 @@ +# 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-07-define-message-enum/Cargo.toml b/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/no-listing-07-define-message-enum/hello.html b/listings/ch20-web-server/no-listing-07-define-message-enum/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/no-listing-07-define-message-enum/src/bin/main.rs b/listings/ch20-web-server/no-listing-07-define-message-enum/src/bin/main.rs new file mode 100755 index 0000000..2078ca9 --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/src/bin/main.rs @@ -0,0 +1,49 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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 mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/no-listing-07-define-message-enum/src/lib.rs b/listings/ch20-web-server/no-listing-07-define-message-enum/src/lib.rs new file mode 100755 index 0000000..46fb5f1 --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/src/lib.rs @@ -0,0 +1,86 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; + +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +type Job = Box; + +// ANCHOR: here +enum Message { + NewJob(Job), + Terminate, +} +// ANCHOR_END: here + +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); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} + +struct Worker { + id: usize, + thread: Option>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let job = receiver.lock().unwrap().recv().unwrap(); + + println!("Worker {} got a job; executing.", id); + + job(); + }); + + Worker { + id, + thread: Some(thread), + } + } +} diff --git a/listings/ch20-web-server/no-listing-08-final-code/404.html b/listings/ch20-web-server/no-listing-08-final-code/404.html new file mode 100755 index 0000000..88d8e91 --- /dev/null +++ b/listings/ch20-web-server/no-listing-08-final-code/404.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Oops!

+

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

+ + diff --git a/listings/ch20-web-server/no-listing-08-final-code/Cargo.lock b/listings/ch20-web-server/no-listing-08-final-code/Cargo.lock new file mode 100755 index 0000000..f2d069f --- /dev/null +++ b/listings/ch20-web-server/no-listing-08-final-code/Cargo.lock @@ -0,0 +1,6 @@ +# 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-08-final-code/Cargo.toml b/listings/ch20-web-server/no-listing-08-final-code/Cargo.toml new file mode 100755 index 0000000..fe61947 --- /dev/null +++ b/listings/ch20-web-server/no-listing-08-final-code/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "hello" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/listings/ch20-web-server/no-listing-08-final-code/hello.html b/listings/ch20-web-server/no-listing-08-final-code/hello.html new file mode 100755 index 0000000..fe442d6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-08-final-code/hello.html @@ -0,0 +1,11 @@ + + + + + Hello! + + +

Hello!

+

Hi from Rust

+ + diff --git a/listings/ch20-web-server/no-listing-08-final-code/src/bin/main.rs b/listings/ch20-web-server/no-listing-08-final-code/src/bin/main.rs new file mode 100755 index 0000000..d3f8754 --- /dev/null +++ b/listings/ch20-web-server/no-listing-08-final-code/src/bin/main.rs @@ -0,0 +1,51 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpListener; +use std::net::TcpStream; +use std::thread; +use std::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); + }); + } + + println!("Shutting down."); +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 1024]; + stream.read(&mut buffer).unwrap(); + + let get = b"GET / HTTP/1.1\r\n"; + let sleep = b"GET /sleep HTTP/1.1\r\n"; + + let (status_line, filename) = if buffer.starts_with(get) { + ("HTTP/1.1 200 OK", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!( + "{}\r\nContent-Length: {}\r\n\r\n{}", + status_line, + contents.len(), + contents + ); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} diff --git a/listings/ch20-web-server/no-listing-08-final-code/src/lib.rs b/listings/ch20-web-server/no-listing-08-final-code/src/lib.rs new file mode 100755 index 0000000..68f4263 --- /dev/null +++ b/listings/ch20-web-server/no-listing-08-final-code/src/lib.rs @@ -0,0 +1,101 @@ +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; + +pub struct ThreadPool { + workers: Vec, + sender: mpsc::Sender, +} + +type Job = Box; + +enum Message { + NewJob(Job), + Terminate, +} + +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(Message::NewJob(job)).unwrap(); + } +} + +impl Drop for ThreadPool { + fn drop(&mut self) { + println!("Sending terminate message to all workers."); + + for _ in &self.workers { + self.sender.send(Message::Terminate).unwrap(); + } + + println!("Shutting down all workers."); + + for worker in &mut self.workers { + println!("Shutting down worker {}", worker.id); + + if let Some(thread) = worker.thread.take() { + thread.join().unwrap(); + } + } + } +} + +struct Worker { + id: usize, + thread: Option>, +} + +impl Worker { + fn new(id: usize, receiver: Arc>>) -> Worker { + let thread = thread::spawn(move || loop { + let message = receiver.lock().unwrap().recv().unwrap(); + + match message { + Message::NewJob(job) => { + println!("Worker {} got a job; executing.", id); + + job(); + } + Message::Terminate => { + println!("Worker {} was told to terminate.", id); + + break; + } + } + }); + + Worker { + id, + thread: Some(thread), + } + } +} diff --git a/src/ch00-00-introduction.md b/src/ch00-00-introduction.md index 6e3b56f..4da1777 100644 --- a/src/ch00-00-introduction.md +++ b/src/ch00-00-introduction.md @@ -2,7 +2,7 @@ > [ch00-00-introduction.md](https://github.com/rust-lang/book/blob/master/src/ch00-00-introduction.md) >
-> commit 0aa307c7d79d2cbf83cdf5d47780b2904e9cb03f +> commit 578591a3db98bc645aae4bcc2eed85db458a4e24 > 注意:本书的版本与出版的 [The Rust Programming Language][nsprust] > 和电子版的 [No Starch Press][nsp] 一致 @@ -82,10 +82,10 @@ Rust 语言也希望能支持很多其他用户,这里提及的只是最大的 | Ferris | 意义 | |------------------------------------------------------------------------|--------------------------------------------------| -| | 这些代码不能编译! | -| | 这些代码会 panic! | -| | 这些代码块包含不安全(unsafe)代码。 | -| | 这些代码不会产生期望的行为。 | +| does not compile | 这些代码不能编译! | +| panic | 这些代码会 panic! | +| unsafe | 这些代码块包含不安全(unsafe)代码。 | +| not desired behavior | 这些代码不会产生期望的行为。 | 在大部分情况,我们会指引你将任何不能编译的代码纠正为正确版本。 @@ -93,7 +93,7 @@ Rust 语言也希望能支持很多其他用户,这里提及的只是最大的 生成本书的源码可以在 [GitHub][book] 上找到。 -[book]: https://github.com/rust-lang/book/tree/master/src +[book]: https://github.com/rust-lang/book/tree/main/src > 译者注:本译本的 [GitHub 仓库][trpl-zh-cn],欢迎 Issue 和 PR :) diff --git a/src/ch01-01-installation.md b/src/ch01-01-installation.md index 164ebfa..688df40 100644 --- a/src/ch01-01-installation.md +++ b/src/ch01-01-installation.md @@ -1,11 +1,13 @@ ## 安装 > [ch01-01-installation.md](https://github.com/rust-lang/book/blob/master/src/ch01-01-installation.md)
-> commit bad683bb7dcd06ef7f5f83bad3a25b1706b7b230 +> commit aa6f28089364b148bbc6baddd59a2625dcc4dfba 第一步是安装 Rust。我们会通过 `rustup` 下载 Rust,这是一个管理 Rust 版本和相关工具的命令行工具。下载时需要联网。 -> 注意:如果你出于某些理由倾向于不使用 `rustup`,请到 [Rust 安装页面](https://www.rust-lang.org/install.html) 查看其它安装选项。 +> 注意:如果你出于某些理由倾向于不使用 `rustup`,请到 [其他 Rust 安装方式页面][otherinstall] 查看其它安装选项。 + +[otherinstall]: https://forge.rust-lang.org/infra/other-installation-methods.html 接下来的步骤会安装最新的稳定版 Rust 编译器。Rust 的稳定性确保本书所有示例在最新版本的 Rust 中能够继续编译。不同版本的输出可能略有不同,因为 Rust 经常改进错误信息和警告。也就是说,任何通过这些步骤安装的最新稳定版 Rust,都应该能正常运行本书中的内容。 @@ -17,7 +19,7 @@ 如果你使用 Linux 或 macOS,打开终端并输入如下命令: -```text +```console $ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh ``` @@ -27,7 +29,15 @@ $ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh Rust is installed now. Great! ``` -另外,你需要一个某种类型的链接器(linker)。很有可能已经安装,不过当你尝试编译 Rust 程序时,却有错误指出无法执行链接器,这意味着你的系统上没有安装链接器,你需要自行安装一个。C 编译器通常带有正确的链接器。请查看你使用平台的文档,了解如何安装 C 编译器。并且,一些常用的 Rust 包依赖 C 代码,也需要安装 C 编译器。因此现在安装一个是值得的。 +另外,你还需要一个链接器(linker),这是一个 Rust 用来将其编译输出链接成一个(可执行)文件的程序。你很有可能已经安装了。如果你遇到了链接器错误,则应该安装一个 C 编译器(compiler),它通常会包含一个链接器。并且,一些常用的 Rust 包依赖 C 代码,也需要安装 C 编译器。因此现在安装一个是值得的。 + +在 macOS 上,运行如下来获取一个 C 编译器: + +```console +$ xcode-select --install +``` + +Linux 用户通常需要根据发行版(distribution)文档安装 GCC 或 Clang。比如,如果你使用 Ubuntu,可以安装 `build-essential` 包。 ### 在 Windows 上安装 `rustup` @@ -42,13 +52,13 @@ Rust is installed now. Great! 通过 `rustup` 安装了 Rust 之后,很容易更新到最新版本。在 shell 中运行如下更新脚本: -```text +```console $ rustup update ``` 为了卸载 Rust 和 `rustup`,在 shell 中运行如下卸载脚本: -```text +```console $ rustup self uninstall ``` @@ -56,7 +66,7 @@ $ rustup self uninstall 要检查是否正确安装了 Rust,打开 shell 并运行如下行: -```text +```console $ rustc --version ``` diff --git a/src/ch01-02-hello-world.md b/src/ch01-02-hello-world.md index 708e36c..74382ee 100644 --- a/src/ch01-02-hello-world.md +++ b/src/ch01-02-hello-world.md @@ -2,7 +2,7 @@ > [ch01-02-hello-world.md](https://github.com/rust-lang/book/blob/master/src/ch01-02-hello-world.md) >
-> commit f63a103270ec8416899675a9cdb1c5cf6d77a498 +> commit 9c0fa2714859738ff73cbbb829592e4c037d7e46 既然安装好了 Rust,我们来编写第一个 Rust 程序。当学习一门新语言的时候,使用该语言在屏幕上打印 `Hello, world!` 是一项传统,我们将沿用这一传统! @@ -16,7 +16,7 @@ 对于 Linux、macOS 和 Windows PowerShell,输入: -```text +```console $ mkdir ~/projects $ cd ~/projects $ mkdir hello_world @@ -50,7 +50,7 @@ fn main() { 保存文件,并回到终端窗口。在 Linux 或 macOS 上,输入如下命令,编译并运行文件: -```text +```console $ rustc main.rs $ ./main Hello, world! @@ -82,7 +82,7 @@ fn main() { 还须注意,函数体被包裹在花括号中,`{}`。Rust 要求所有函数体都要用花括号包裹起来。一般来说,将左花括号与函数声明置于同一行并以空格分隔,是良好的代码风格。 -在编写本书的时候,一个叫做 `rustfmt` 的自动格式化工具正在开发中。如果你希望在 Rust 项目中保持一种标准风格,`rustfmt` 会将代码格式化为特定的风格。Rust 团队计划最终将该工具包含在标准 Rust 发行版中,就像 `rustc`。所以根据你阅读本书的时间,它可能已经安装到你的电脑中了!检查在线文档以了解更多细节。 +如果你希望在 Rust 项目中保持一种标准风格,`rustfmt` 会将代码格式化为特定的风格。Rust 团队已经将该工具包含在标准 Rust 发行版中,就像 `rustc`,所以它已经安装到你的电脑中了!检查在线文档以了解更多细节。 在 `main()` 函数中是如下代码: @@ -92,7 +92,7 @@ fn main() { 这行代码完成这个简单程序的所有工作:在屏幕上打印文本。这里有四个重要的细节需要注意。首先 Rust 的缩进风格使用 4 个空格,而不是 1 个制表符(tab)。 -第二,`println!` 调用了一个 Rust 宏(macro)。如果是调用函数,则应输入 `println`(没有`!`)。我们将在第十九章详细讨论宏。现在你只需记住,当看到符号 `!` 的时候,就意味着调用的是宏而不是普通函数。 +第二,`println!` 调用了一个 Rust 宏(macro)。如果是调用函数,则应输入 `println`(没有`!`)。我们将在第十九章详细讨论宏。现在你只需记住,当看到符号 `!` 的时候,就意味着调用的是宏而不是普通函数,并且宏并不总是和函数遵守同样的规则。 第三,`"Hello, world!"` 是一个字符串。我们把这个字符串作为一个参数传递给 `println!`,字符串将被打印到屏幕上。 @@ -104,7 +104,7 @@ fn main() { 在运行 Rust 程序之前,必须先使用 Rust 编译器编译它,即输入 `rustc` 命令并传入源文件名称,如下: -```text +```console $ rustc main.rs ``` @@ -112,7 +112,7 @@ $ rustc main.rs 在 Linux、macOS 或 Windows 的 PowerShell 上,在 shell 中输入 `ls` 命令可以看见这个可执行文件。在 Linux 和 macOS,你会看到两个文件。在 Windows PowerShell 中,你会看到同使用 CMD 相同的三个文件。 -```text +```console $ ls main main.rs ``` @@ -128,7 +128,7 @@ main.rs 这展示了扩展名为 *.rs* 的源文件、可执行文件(在 Windows 下是 *main.exe*,其它平台是 *main*),以及当使用 CMD 时会有一个包含调试信息、扩展名为 *.pdb* 的文件。从这里开始运行 *main* 或 *main.exe* 文件,如下: -```text +```console $ ./main # Windows 是 .\main.exe ``` diff --git a/src/ch01-03-hello-cargo.md b/src/ch01-03-hello-cargo.md index f169476..6297ade 100644 --- a/src/ch01-03-hello-cargo.md +++ b/src/ch01-03-hello-cargo.md @@ -2,7 +2,7 @@ > [ch01-03-hello-cargo.md](https://github.com/rust-lang/book/blob/master/src/ch01-03-hello-cargo.md) >
-> commit f63a103270ec8416899675a9cdb1c5cf6d77a498 +> commit bcab8b5f5f520a40985783082d99fbe841adf649 Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库。(我们把代码所需要的库叫做 **依赖**(*dependencies*))。 @@ -10,7 +10,7 @@ Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Ca 由于绝大多数 Rust 项目使用 Cargo,本书接下来的部分假设你也使用 Cargo。如果使用 [“安装”][installation] 部分介绍的官方安装包的话,则自带了 Cargo。如果通过其他方式安装的话,可以在终端输入如下命令检查是否安装了 Cargo: -```text +```console $ cargo --version ``` @@ -20,14 +20,16 @@ $ cargo --version 我们使用 Cargo 创建一个新项目,然后看看与上面的 Hello, world! 项目有什么不同。回到 *projects* 目录(或者你存放代码的目录)。接着,可在任何操作系统下运行以下命令: -```text +```console $ cargo new hello_cargo $ cd hello_cargo ``` 第一行命令新建了名为 *hello_cargo* 的目录。我们将项目命名为 *hello_cargo*,同时 Cargo 在一个同名目录中创建项目文件。 -进入 *hello_cargo* 目录并列出文件。将会看到 Cargo 生成了两个文件和一个目录:一个 *Cargo.toml* 文件,一个 *src* 目录,以及位于 *src* 目录中的 *main.rs* 文件。它也在 *hello_cargo* 目录初始化了一个 git 仓库,以及一个 *.gitignore* 文件。 +进入 *hello_cargo* 目录并列出文件。将会看到 Cargo 生成了两个文件和一个目录:一个 *Cargo.toml* 文件,一个 *src* 目录,以及位于 *src* 目录中的 *main.rs* 文件。 + +这也会在 *hello_cargo* 目录初始化了一个 git 仓库,以及一个 *.gitignore* 文件。如果在一个已经存在的 git 仓库中运行 `cargo new`,则这些 git 相关文件则不会生成;可以通过运行 `cargo new --vcs=git` 来覆盖这些行为。 > 注意:Git 是一个常用的版本控制系统(version control system, VCS)。可以通过 `--vcs` 参数使 `cargo new` 切换到其它版本控制系统(VCS),或者不使用 VCS。运行 `cargo new --help` 参看可用的选项。 @@ -39,8 +41,7 @@ $ cd hello_cargo [package] name = "hello_cargo" version = "0.1.0" -authors = ["Your Name "] -edition = "2018" +edition = "2021" [dependencies] ``` @@ -49,11 +50,11 @@ edition = "2018" 这个文件使用 [*TOML*][toml] (*Tom's Obvious, Minimal Language*) 格式,这是 Cargo 配置文件的格式。 -[toml]: https://github.com/toml-lang/toml +[toml]: https://toml.io 第一行,`[package]`,是一个片段(section)标题,表明下面的语句用来配置一个包。随着我们在这个文件增加更多的信息,还将增加其他片段(section)。 -接下来的四行设置了 Cargo 编译程序所需的配置:项目的名称、版本、作者以及要使用的 Rust 版本。Cargo 从环境中获取你的名字和 email 信息,所以如果这些信息不正确,请修改并保存此文件。附录 E 会介绍 `edition` 的值。 +接下来的三行设置了 Cargo 编译程序所需的配置:项目的名称、项目的版本以及要使用的 Rust 版本。[附录 E][appendix-e] 会介绍 `edition` 的值。 最后一行,`[dependencies]`,是罗列项目依赖的片段的开始。在 Rust 中,代码包被称为 *crates*。这个项目并不需要其他的 crate,不过在第二章的第一个项目会用到依赖,那时会用得上这个片段。 @@ -77,7 +78,7 @@ Cargo 期望源文件存放在 *src* 目录中。项目根目录只存放 README 现在让我们看看通过 Cargo 构建和运行 “Hello, world!” 程序有什么不同!在 *hello_cargo* 目录下,输入下面的命令来构建项目: -```text +```console $ cargo build Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo) Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs @@ -85,7 +86,7 @@ $ cargo build 这个命令会创建一个可执行文件 *target/debug/hello_cargo* (在 Windows 上是 *target\debug\hello_cargo.exe*),而不是放在目前目录下。可以通过这个命令运行可执行文件: -```text +```console $ ./target/debug/hello_cargo # 或者在 Windows 下为 .\target\debug\hello_cargo.exe Hello, world! ``` @@ -94,7 +95,7 @@ Hello, world! 我们刚刚使用 `cargo build` 构建了项目,并使用 `./target/debug/hello_cargo` 运行了程序,也可以使用 `cargo run` 在一个命令中同时编译并运行生成的可执行文件: -```text +```console $ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs Running `target/debug/hello_cargo` @@ -103,7 +104,7 @@ Hello, world! 注意这一次并没有出现表明 Cargo 正在编译 `hello_cargo` 的输出。Cargo 发现文件并没有被改变,就直接运行了二进制文件。如果修改了源文件的话,Cargo 会在运行之前重新构建项目,并会出现像这样的输出: -```text +```console $ cargo run Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo) Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs @@ -113,7 +114,7 @@ Hello, world! Cargo 还提供了一个叫 `cargo check` 的命令。该命令快速检查代码确保其可以编译,但并不产生可执行文件: -```text +```console $ cargo check Checking hello_cargo v0.1.0 (file:///projects/hello_cargo) Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs @@ -123,8 +124,9 @@ $ cargo check 我们回顾下已学习的 Cargo 内容: -* 可以使用 `cargo build` 或 `cargo check` 构建项目。 +* 可以使用 `cargo build` 构建项目。 * 可以使用 `cargo run` 一步构建并运行项目。 +* 可以使用 `cargo check` 在不生成二进制文件的情况下构建项目来检查错误。 * 有别于将构建结果放在与源码相同的目录,Cargo 会将其放到 *target/debug* 目录。 使用 Cargo 的一个额外的优点是,不管你使用什么操作系统,其命令都是一样的。所以从现在开始本书将不再为 Linux 和 macOS 以及 Windows 提供相应的命令。 @@ -139,8 +141,8 @@ $ cargo check 即便 `hello_cargo` 项目十分简单,它现在也使用了很多在你之后的 Rust 生涯将会用到的实用工具。其实,要在任何已存在的项目上工作时,可以使用如下命令通过 Git 检出代码,移动到该项目目录并构建: -```text -$ git clone someurl.com/someproject +```console +$ git clone clone example.org/someproject $ cd someproject $ cargo build ``` @@ -162,3 +164,4 @@ $ cargo build 是时候通过构建更实质性的程序来熟悉读写 Rust 代码了。所以在第二章我们会构建一个猜猜看游戏程序。如果你更愿意从学习 Rust 常用的编程概念开始,请阅读第三章,接着再回到第二章。 [installation]: ch01-01-installation.html#installation +[appendix-e]: appendix-05-editions.html diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 44ea379..c956e2c 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -1,85 +1,57 @@ # 编写 猜猜看 游戏 -> [ch02-00-guessing-game-tutorial.md](https://github.com/rust-lang/book/blob/master/src/ch02-00-guessing-game-tutorial.md) ->
-> commit c427a676393d001edc82f1a54a3b8026abcf9690 +> [ch02-00-guessing-game-tutorial.md](https://github.com/rust-lang/book/blob/master/src/ch02-00-guessing-game-tutorial.md) >
+> commit d68d96576b705fcff7aa6341a9840f4de3c0ca0c -让我们一起动手完成一个项目,来快速上手 Rust!本章将介绍 Rust 中一些常用概念,并通过真实的程序来展示如何运用它们。你将会学到 `let`、`match`、方法、关联函数、外部 crate 等知识!后续章节会深入探讨这些概念的细节。在这一章,我们将做基础练习。 +让我们一起动手完成一个项目,来快速上手 Rust!本章将介绍 Rust 中一些常用概念,并通过真实的程序来展示如何运用它们。你将会学到 `let`、`match`、方法(method)、关联函数(associated function)、使用外部 crate 等知识!后续章节会深入探讨这些概念的细节。在这一章,我们将练习基础内容。 我们会实现一个经典的新手编程问题:猜猜看游戏。它是这么工作的:程序将会随机生成一个 1 到 100 之间的随机整数。接着它会请玩家猜一个数并输入,然后提示猜测是大了还是小了。如果猜对了,它会打印祝贺信息并退出。 ## 准备一个新项目 -要创建一个新项目,进入第一章中创建的 *projects* 目录,使用 Cargo 新建一个项目,如下: +要创建一个新项目,进入第一章中创建的 _projects_ 目录,使用 Cargo 新建一个项目,如下: -```text +```console $ cargo new guessing_game $ cd guessing_game ``` 第一个命令,`cargo new`,它获取项目的名称(`guessing_game`)作为第一个参数。第二个命令进入到新创建的项目目录。 -看看生成的 *Cargo.toml* 文件: +看看生成的 _Cargo.toml_ 文件: 文件名: Cargo.toml ```toml -[package] -name = "guessing_game" -version = "0.1.0" -authors = ["Your Name "] -edition = "2018" - -[dependencies] +{{#include ../listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.toml}} ``` -如果 Cargo 从环境中获取的开发者信息不正确,修改这个文件并再次保存。 - -正如第一章那样,`cargo new` 生成了一个 “Hello, world!” 程序。查看 *src/main.rs* 文件: +正如第一章那样,`cargo new` 生成了一个 “Hello, world!” 程序。查看 _src/main.rs_ 文件: 文件名: src/main.rs ```rust -fn main() { - println!("Hello, world!"); -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs}} ``` 现在使用 `cargo run` 命令,一步完成 “Hello, world!” 程序的编译和运行: -```text -$ cargo run - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 1.50 secs - Running `target/debug/guessing_game` -Hello, world! +```console +{{#include ../listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt}} ``` 当你需要在项目中快速迭代时,`run` 命令就能派上用场,正如我们在这个游戏项目中做的,在下一次迭代之前快速测试每一次迭代。 -重新打开 *src/main.rs* 文件。我们将会在这个文件中编写全部的代码。 +重新打开 _src/main.rs_ 文件。我们将会在这个文件中编写全部的代码。 ## 处理一次猜测 -猜猜看程序的第一部分请求和处理用户输入,并检查输入是否符合预期的格式。首先,允许玩家输入猜测。在 *src/main.rs* 中输入示例 2-1 中的代码。 +猜猜看程序的第一部分请求和处理用户输入,并检查输入是否符合预期的格式。首先,允许玩家输入猜测。在 _src/main.rs_ 中输入示例 2-1 中的代码。 文件名: src/main.rs ```rust,ignore -use std::io; - -fn main() { - println!("Guess the number!"); - - println!("Please input your guess."); - - let mut guess = String::new(); - - io::stdin().read_line(&mut guess) - .expect("Failed to read line"); - - println!("You guessed: {}", guess); -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:all}} ``` 示例 2-1:获取用户猜测并打印的代码 @@ -87,138 +59,114 @@ fn main() { 这些代码包含很多信息,我们一行一行地过一遍。为了获取用户输入并打印结果作为输出,我们需要将 `io`(输入/输出)库引入当前作用域。`io` 库来自于标准库(也被称为 `std`): ```rust,ignore -use std::io; +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:io}} ``` -默认情况下,Rust 将 [*prelude*][prelude] 模块中少量的类型引入到每个程序的作用域中。如果需要的类型不在 prelude 中,你必须使用 `use` 语句显式地将其引入作用域。`std::io` 库提供很多有用的功能,包括接收用户输入的功能。 +默认情况下,Rust 将 [_prelude_][prelude] 模块中少量的类型引入到每个程序的作用域中。如果需要的类型不在 prelude 中,你必须使用 `use` 语句显式地将其引入作用域。`std::io` 库提供很多有用的功能,包括接收用户输入的功能。 [prelude]: https://doc.rust-lang.org/std/prelude/index.html 如第一章所提及,`main` 函数是程序的入口点: ```rust,ignore -fn main() { +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:main}} ``` -`fn` 语法声明了一个新函数,`()` 表明没有参数,`{` 作为函数体的开始。 +`fn` 语法声明了一个新函数,小括号 `()` 表明没有参数,大括号 `{` 作为函数体的开始。 第一章也提及了 `println!` 是一个在屏幕上打印字符串的宏: ```rust,ignore -println!("Guess the number!"); - -println!("Please input your guess."); +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:print}} ``` 这些代码仅仅打印提示,介绍游戏的内容然后请求用户输入。 ### 使用变量储存值 -接下来,创建一个储存用户输入的地方,像这样: +接下来,创建一个 **变量**(_variable_)来储存用户输入,像这样: ```rust,ignore -let mut guess = String::new(); +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:string}} ``` -现在程序开始变得有意思了!这一小行代码发生了很多事。注意这是一个 `let` 语句,用来创建 **变量**(*variable*)。这里是另外一个例子: +现在程序开始变得有意思了!这一小行代码发生了很多事。我们使用 `let` 语句来创建变量。这里是另外一个例子: ```rust,ignore -let foo = bar; +let apples = 5; ``` 这行代码新建了一个叫做 `foo` 的变量并把它绑定到值 `bar` 上。在 Rust 中,变量默认是不可变的。我们将会在第三章的 [“变量与可变性”][variables-and-mutability] 部分详细讨论这个概念。下面的例子展示了如何在变量名前使用 `mut` 来使一个变量可变: ```rust,ignore -let foo = 5; // 不可变 -let mut bar = 5; // 可变 +let apples = 5; // 不可变 +let mut bananas = 5; // 可变 ``` -> 注意:`//` 语法开始一个注释,持续到行尾。Rust 忽略注释中的所有内容,第三章将会详细介绍注释。 +> 注意:`//` 语法开始一个注释,持续到行尾。Rust 忽略注释中的所有内容,[第三章][comments]将会详细介绍注释。 让我们回到猜猜看程序中。现在我们知道了 `let mut guess` 会引入一个叫做 `guess` 的可变变量。等号(`=`)的右边是 `guess` 所绑定的值,它是 `String::new` 的结果,这个函数会返回一个 `String` 的新实例。[`String`][string] 是一个标准库提供的字符串类型,它是 UTF-8 编码的可增长文本块。 -[string]: https://doc.rust-lang.org/std/string/struct.String.html - -`::new` 那一行的 `::` 语法表明 `new` 是 `String` 类型的一个 **关联函数**(*associated function*)。关联函数是针对类型实现的,在这个例子中是 `String`,而不是 `String` 的某个特定实例。一些语言中把它称为 **静态方法**(*static method*)。 +`::new` 那一行的 `::` 语法表明 `new` 是 `String` 类型的一个 **关联函数**(_associated function_)。关联函数是针对类型实现的,在这个例子中是 `String`,而不是 `String` 的某个特定实例。一些语言中把它称为 **静态方法**(_static method_)。 `new` 函数创建了一个新的空字符串,你会发现很多类型上有 `new` 函数,因为它是创建类型实例的惯用函数名。 总结一下,`let mut guess = String::new();` 这一行创建了一个可变变量,当前它绑定到一个新的 `String` 空实例上。 +### 接收用户输入 + 回忆一下,我们在程序的第一行使用 `use std::io;` 从标准库中引入了输入/输出功能。现在调用 `io` 库中的函数 `stdin`: ```rust,ignore -io::stdin().read_line(&mut guess) - .expect("Failed to read line"); +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:read}} ``` 如果程序的开头没有 `use std::io` 这一行,可以把函数调用写成 `std::io::stdin`。`stdin` 函数返回一个 [`std::io::Stdin`][iostdin] 的实例,这代表终端标准输入句柄的类型。 -[iostdin]: https://doc.rust-lang.org/std/io/struct.Stdin.html +代码的下一部分,`.read_line(&mut guess)`,调用 [`read_line`][read_line] 方法从标准输入句柄获取用户输入。我们还将 `&mut guess` 作为参数传递给 `read_line()` 函数,让其将用户输入储存到这个字符串中。`read_line` 的工作是,无论用户在标准输入中键入什么内容,都将其追加(不会覆盖其原有内容)到一个字符串中,因此它需要字符串作为参数。这个字符串参数应该是可变的,以便 `read_line` 将用户输入附加上去。 -代码的下一部分,`.read_line(&mut guess)`,调用 [`read_line`][read_line] 方法从标准输入句柄获取用户输入。我们还向 `read_line()` 传递了一个参数:`&mut guess`。 - -[read_line]: https://doc.rust-lang.org/std/io/struct.Stdin.html#method.read_line - -`read_line` 的工作是,无论用户在标准输入中键入什么内容,都将其存入一个字符串中,因此它需要字符串作为参数。这个字符串参数应该是可变的,以便 `read_line` 将用户输入附加上去。 - -`&` 表示这个参数是一个 **引用**(*reference*),它允许多处代码访问同一处数据,而无需在内存中多次拷贝。引用是一个复杂的特性,Rust 的一个主要优势就是安全而简单的操纵引用。完成当前程序并不需要了解如此多细节。现在,我们只需知道它像变量一样,默认是不可变的。因此,需要写成 `&mut guess` 来使其可变,而不是 `&guess`。(第四章会更全面的解释引用。) +`&` 表示这个参数是一个 **引用**(_reference_),它允许多处代码访问同一处数据,而无需在内存中多次拷贝。引用是一个复杂的特性,Rust 的一个主要优势就是安全而简单的操纵引用。完成当前程序并不需要了解如此多细节。现在,我们只需知道它像变量一样,默认是不可变的。因此,需要写成 `&mut guess` 来使其可变,而不是 `&guess`。(第四章会更全面的解释引用。) ### 使用 `Result` 类型来处理潜在的错误 我们还没有完全分析完这行代码。虽然这是单独一行代码,但它是逻辑行(虽然换行了但仍是语句)的一部分。后一部分是这个方法: ```rust,ignore -.expect("Failed to read line"); +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:expect}} ``` -当使用 `.foo()` 语法调用方法时,通过换行加缩进来把长行拆开是明智的。我们完全可以这样写: +我们也可以将代码这样写: ```rust,ignore io::stdin().read_line(&mut guess).expect("Failed to read line"); ``` -不过,过长的行难以阅读,所以最好拆开来写,两个方法调用占两行。现在来看看这行代码干了什么。 +不过,过长的代码行难以阅读,所以最好拆开来写。通常来说,当使用 `.method_name()` 语法调用方法时引入换行符和空格将长的代码行拆开是明智的。现在来看看这行代码干了什么。 -之前提到了 `read_line` 将用户输入附加到传递给它的字符串中,不过它也返回一个值——在这个例子中是 [`io::Result`][ioresult]。Rust 标准库中有很多叫做 `Result` 的类型:一个通用的 [`Result`][result] 以及在子模块中的特化版本,比如 `io::Result`。 +之前提到了 `read_line` 将用户输入附加到传递给它的字符串中,不过它也返回一个值 —— 在这个例子中是 [`io::Result`][ioresult]。Rust 标准库中有很多叫做 `Result` 的类型:一个泛型 [`Result`][result] 以及在子模块中的特化版本,比如 `io::Result`。`Result` 类型是 [_枚举_(_enumerations_)][enums],通常也写作 _enums_。枚举类型持有固定集合的值,这些值被称为枚举的 **成员**(_variants_)。枚举通常和 `match` 一同使用,这是一个便于根据条件执行时枚举的不同成员值来执行不同代码块的条件语句。 -[ioresult]: https://doc.rust-lang.org/std/io/type.Result.html -[result]: https://doc.rust-lang.org/std/result/enum.Result.html - -`Result` 类型是 [*枚举*(*enumerations*)][enums],通常也写作 *enums*。枚举类型持有固定集合的值,这些值被称为枚举的 **成员**(*variants*)。第六章将介绍枚举的更多细节。 - -[enums]: ch06-00-enums.html +第六章将介绍枚举的更多细节。这里的 `Result` 类型将用来编码错误处理的信息。 `Result` 的成员是 `Ok` 和 `Err`,`Ok` 成员表示操作成功,内部包含成功时产生的值。`Err` 成员则意味着操作失败,并且包含失败的前因后果。 这些 `Result` 类型的作用是编码错误处理信息。`Result` 类型的值,像其他类型一样,拥有定义于其上的方法。`io::Result` 的实例拥有 [`expect` 方法][expect]。如果 `io::Result` 实例的值是 `Err`,`expect` 会导致程序崩溃,并显示当做参数传递给 `expect` 的信息。如果 `read_line` 方法返回 `Err`,则可能是来源于底层操作系统错误的结果。如果 `io::Result` 实例的值是 `Ok`,`expect` 会获取 `Ok` 中的值并原样返回。在本例中,这个值是用户输入到标准输入中的字节数。 -[expect]: https://doc.rust-lang.org/std/result/enum.Result.html#method.expect - 如果不调用 `expect`,程序也能编译,不过会出现一个警告: -```text -$ cargo build - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) -warning: unused `std::result::Result` which must be used - --> src/main.rs:10:5 - | -10 | io::stdin().read_line(&mut guess); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: #[warn(unused_must_use)] on by default +```console +{{#include ../listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt}} ``` Rust 警告我们没有使用 `read_line` 的返回值 `Result`,说明有一个可能的错误没有处理。 -消除警告的正确做法是实际编写错误处理代码,不过由于我们就是希望程序在出现问题时立即崩溃,所以直接使用 `expect`。第九章会学习如何从错误中恢复。 +消除警告的正确做法是实际去编写错误处理代码,不过由于我们就是希望程序在出现问题时立即崩溃,所以直接使用 `expect`。[第九章][recover] 会学习如何从错误中恢复。 ### 使用 `println!` 占位符打印值 除了位于结尾的大括号,目前为止就只有这一行代码值得讨论一下了,就是这一行: ```rust,ignore -println!("You guessed: {}", guess); +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs:print_guess}} ``` 这行代码打印存储用户输入的字符串。第一个参数是格式化字符串,里面的 `{}` 是预留在特定位置的占位符。使用 `{}` 也可以打印多个值:第一对 `{}` 使用格式化字符串之后的第一个值,第二对则使用第二个值,依此类推。调用一次 `println!` 打印多个值看起来像这样: @@ -236,10 +184,10 @@ println!("x = {} and y = {}", x, y); 让我们来测试下猜猜看游戏的第一部分。使用 `cargo run` 运行: -```text +```console $ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs + Finished dev [unoptimized + debuginfo] target(s) in 6.44s Running `target/debug/guessing_game` Guess the number! Please input your guess. @@ -253,135 +201,107 @@ You guessed: 6 接下来,需要生成一个秘密数字,好让用户来猜。秘密数字应该每次都不同,这样重复玩才不会乏味;范围应该在 1 到 100 之间,这样才不会太困难。Rust 标准库中尚未包含随机数功能。然而,Rust 团队还是提供了一个 [`rand` crate][randcrate]。 -[randcrate]: https://crates.io/crates/rand - ### 使用 crate 来增加更多功能 -记住,*crate* 是一个 Rust 代码包。我们正在构建的项目是一个 **二进制 crate**,它生成一个可执行文件。 `rand` crate 是一个 **库 crate**,库 crate 可以包含任意能被其他程序使用的代码。 +记住,_crate_ 是一个 Rust 代码包。我们正在构建的项目是一个 **二进制 crate**,它生成一个可执行文件。 `rand` crate 是一个 **库 crate**,库 crate 可以包含任意能被其他程序使用的代码。 -Cargo 对外部 crate 的运用是其真正闪光的地方。在我们使用 `rand` 编写代码之前,需要修改 *Cargo.toml* 文件,引入一个 `rand` 依赖。现在打开这个文件并在底部的 `[dependencies]` 片段标题之下添加: +Cargo 对外部 crate 的运用是其真正闪光的地方。在我们使用 `rand` 编写代码之前,需要修改 _Cargo.toml_ 文件,引入一个 `rand` 依赖。现在打开这个文件并在底部的 `[dependencies]` 片段标题之下添加如下内容。请确保指定完全如下的 `rand`,包括版本号,否则本章的示例代码可能无法工作。 文件名: Cargo.toml ```toml -[dependencies] - -rand = "0.5.5" +{{#include ../listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml:9:}} ``` -在 *Cargo.toml* 文件中,标题以及之后的内容属同一个片段,直到遇到下一个标题才开始新的片段。`[dependencies]` 片段告诉 Cargo 本项目依赖了哪些外部 crate 及其版本。本例中,我们使用语义化版本 `0.5.5` 来指定 `rand` crate。Cargo 理解[语义化版本(Semantic Versioning)][semver](有时也称为 *SemVer*),这是一种定义版本号的标准。`0.5.5` 事实上是 `^0.5.5` 的简写,它表示 “任何与 0.5.5 版本公有 API 相兼容的版本”。 - -[semver]: http://semver.org +在 _Cargo.toml_ 文件中,标题以及之后的内容属同一个片段,直到遇到下一个标题才开始新的片段。`[dependencies]` 片段告诉 Cargo 本项目依赖了哪些外部 crate 及其版本。本例中,我们使用语义化版本 `0.8.3` 来指定 `rand` crate。Cargo 理解 [语义化版本(Semantic Versioning)][semver](有时也称为 _SemVer_),这是一种定义版本号的标准。`0.8.3` 事实上是 `^0.8.3` 的简写,它表示任何至少是 `0.8.3` 但小于 `0.9.0` 的版本。Cargo 认为这些版本与 `0.8.3` 版本的公有 API 相兼容,这样的版本指定确保了我们可以获取能使本章代码编译的最新的补丁(patch)版本。任何大于等于 `0.9.0` 的版本不能保证和接下来的示例采用了相同的 API。 现在,不修改任何代码,构建项目,如示例 2-2 所示: -```text +```console $ cargo build Updating crates.io index - Downloaded rand v0.5.5 - Downloaded libc v0.2.62 - Downloaded rand_core v0.2.2 - Downloaded rand_core v0.3.1 - Downloaded rand_core v0.4.2 - Compiling rand_core v0.4.2 - Compiling libc v0.2.62 - Compiling rand_core v0.3.1 - Compiling rand_core v0.2.2 - Compiling rand v0.5.5 + Downloaded rand v0.8.3 + Downloaded libc v0.2.86 + Downloaded getrandom v0.2.2 + Downloaded cfg-if v1.0.0 + Downloaded ppv-lite86 v0.2.10 + Downloaded rand_chacha v0.3.0 + Downloaded rand_core v0.6.2 + Compiling rand_core v0.6.2 + Compiling libc v0.2.86 + Compiling getrandom v0.2.2 + Compiling cfg-if v1.0.0 + Compiling ppv-lite86 v0.2.10 + Compiling rand_chacha v0.3.0 + Compiling rand v0.8.3 Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53 s + Finished dev [unoptimized + debuginfo] target(s) in 2.53s ``` 示例 2-2: 将 rand crate 添加为依赖之后运行 `cargo build` 的输出 可能会出现不同的版本号(多亏了语义化版本,它们与代码是兼容的!),同时显示顺序也可能会有所不同。 -现在我们有了一个外部依赖,Cargo 从 *registry* 上获取所有包的最新版本信息,这是一份来自 [Crates.io][cratesio] 的数据拷贝。Crates.io 是 Rust 生态环境中的开发者们向他人贡献 Rust 开源项目的地方。 - -[cratesio]: https://crates.io +现在我们有了一个外部依赖,Cargo 从 _registry_ 上获取所有包的最新版本信息,这是一份来自 [Crates.io][cratesio] 的数据拷贝。Crates.io 是 Rust 生态环境中的开发者们向他人贡献 Rust 开源项目的地方。 在更新完 registry 后,Cargo 检查 `[dependencies]` 片段并下载缺失的 crate 。本例中,虽然只声明了 `rand` 一个依赖,然而 Cargo 还是额外获取了 `libc` 和 `rand_core` 的拷贝,因为 `rand` 依赖 `libc` 和 `rand_core` 来正常工作。下载完成后,Rust 编译依赖,然后使用这些依赖编译项目。 -如果不做任何修改,立刻再次运行 `cargo build`,则不会看到任何除了 `Finished` 行之外的输出。Cargo 知道它已经下载并编译了依赖,同时 *Cargo.toml* 文件也没有变动。Cargo 还知道代码也没有任何修改,所以它不会重新编译代码。因为无事可做,它简单的退出了。 +如果不做任何修改,立刻再次运行 `cargo build`,则不会看到任何除了 `Finished` 行之外的输出。Cargo 知道它已经下载并编译了依赖,同时 _Cargo.toml_ 文件也没有变动。Cargo 还知道代码也没有任何修改,所以它不会重新编译代码。因为无事可做,它简单的退出了。 -如果打开 *src/main.rs* 文件,做一些无关紧要的修改,保存并再次构建,则会出现两行输出: +如果打开 _src/main.rs_ 文件,做一些无关紧要的修改,保存并再次构建,则会出现两行输出: -```text +```console $ cargo build Compiling guessing_game v0.1.0 (file:///projects/guessing_game) Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs ``` -这一行表示 Cargo 只针对 *src/main.rs* 文件的微小修改而更新构建。依赖没有变化,所以 Cargo 知道它可以复用已经为此下载并编译的代码。它只是重新构建了部分(项目)代码。 +这一行表示 Cargo 只针对 _src/main.rs_ 文件的微小修改而更新构建。依赖没有变化,所以 Cargo 知道它可以复用已经为此下载并编译的代码。它只是重新构建了部分(项目)代码。 -#### *Cargo.lock* 文件确保构建是可重现的 +#### _Cargo.lock_ 文件确保构建是可重现的 -Cargo 有一个机制来确保任何人在任何时候重新构建代码,都会产生相同的结果:Cargo 只会使用你指定的依赖版本,除非你又手动指定了别的。例如,如果下周 `rand` crate 的 `0.5.6` 版本出来了,它修复了一个重要的 bug,同时也含有一个会破坏代码运行的缺陷,这时会发生什么呢? +Cargo 有一个机制来确保任何人在任何时候重新构建代码,都会产生相同的结果:Cargo 只会使用你指定的依赖版本,除非你又手动指定了别的。例如,如果下周 `rand` crate 的 `0.8.4` 版本出来了,它修复了一个重要的 bug,同时也含有一个会破坏代码运行的缺陷,这时会发生什么呢?这个问题的答案是 _Cargo.lock_ 文件。它在第一次运行 `cargo build` 时创建,并放在 _guessing_game_ 目录。 -这个问题的答案是 *Cargo.lock* 文件。它在第一次运行 `cargo build` 时创建,并放在 *guessing_game* 目录。当第一次构建项目时,Cargo 计算出所有符合要求的依赖版本并写入 *Cargo.lock* 文件。当将来构建项目时,Cargo 会发现 *Cargo.lock* 已存在并使用其中指定的版本,而不是再次计算所有的版本。这使得你拥有了一个自动化的可重现的构建。换句话说,项目会持续使用 `0.5.5` 直到你显式升级,多亏有了 *Cargo.lock* 文件。 +当第一次构建项目时,Cargo 计算出所有符合要求的依赖版本并写入 _Cargo.lock_ 文件。当将来构建项目时,Cargo 会发现 _Cargo.lock_ 已存在并使用其中指定的版本,而不是再次计算所有的版本。这使得你拥有了一个自动化的可重现的构建。换句话说,项目会持续使用 `0.8.3` 直到你显式升级,多亏有了 _Cargo.lock_ 文件。 #### 更新 crate 到一个新版本 -当你 **确实** 需要升级 crate 时,Cargo 提供了另一个命令,`update`,它会忽略 *Cargo.lock* 文件,并计算出所有符合 *Cargo.toml* 声明的最新版本。如果成功了,Cargo 会把这些版本写入 *Cargo.lock* 文件。 +当你 **确实** 需要升级 crate 时,Cargo 提供了另一个命令,`update`,它会忽略 _Cargo.lock_ 文件,并计算出所有符合 _Cargo.toml_ 声明的最新版本。如果成功了,Cargo 会把这些版本写入 _Cargo.lock_ 文件。 -不过,Cargo 默认只会寻找大于 `0.5.5` 而小于 `0.6.0` 的版本。如果 `rand` crate 发布了两个新版本,`0.5.6` 和 `0.6.0`,在运行 `cargo update` 时会出现如下内容: +不过,Cargo 默认只会寻找大于 `0.8.3` 而小于 `0.9.0` 的版本。如果 `rand` crate 发布了两个新版本,`0.8.4` 和 `0.9.0`,在运行 `cargo update` 时会出现如下内容: -```text +```console $ cargo update Updating crates.io index - Updating rand v0.5.5 -> v0.5.6 + Updating rand v0.8.3 -> v0.8.4 ``` -这时,你也会注意到的 *Cargo.lock* 文件中的变化无外乎现在使用的 `rand` crate 版本是`0.5.6` - -如果想要使用 `0.6.0` 版本的 `rand` 或是任何 `0.6.x` 系列的版本,必须像这样更新 *Cargo.toml* 文件: +Cargo 会忽略 `0.9.0` 版本。这时,你也会注意到的 _Cargo.lock_ 文件中的变化无外乎现在使用的 `rand` crate 版本是`0.8.4`如果想要使用 `0.9.0` 版本的 `rand` 或是任何 `0.9.x` 系列的版本,必须像这样更新 _Cargo.toml_ 文件: ```toml [dependencies] - -rand = "0.6.0" +rand = "0.9.0" ``` 下一次运行 `cargo build` 时,Cargo 会从 registry 更新可用的 crate,并根据你指定的新版本重新计算。 第十四章会讲到 [Cargo][doccargo] 及其[生态系统][doccratesio] 的更多内容,不过目前你只需要了解这么多。通过 Cargo 复用库文件非常容易,因此 Rustacean 能够编写出由很多包组装而成的更轻巧的项目。 -[doccargo]: http://doc.crates.io -[doccratesio]: http://doc.crates.io/crates-io.html - ### 生成一个随机数 -你已经把 `rand` crate 添加到 *Cargo.toml* 了,让我们开始使用 `rand`。下一步是更新 *src/main.rs*,如示例 2-3 所示。 +让我们开始使用 `rand` 来生成一个猜猜看随机数。下一步是更新 *src/main.rs*,如示例 2-3 所示。 文件名: src/main.rs ```rust,ignore -use std::io; -use rand::Rng; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1, 101); - - println!("The secret number is: {}", secret_number); - - println!("Please input your guess."); - - let mut guess = String::new(); - - io::stdin().read_line(&mut guess) - .expect("Failed to read line"); - - println!("You guessed: {}", guess); -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs:all}} ``` 示例 2-3:添加生成随机数的代码 首先,我们新增了一行 `use`:`use rand::Rng`。`Rng` 是一个 trait,它定义了随机数生成器应实现的方法,想使用这些方法的话,此 trait 必须在作用域中。第十章会详细介绍 trait。 -接下来,我们在中间还新增加了两行。`rand::thread_rng` 函数提供实际使用的随机数生成器:它位于当前执行线程的本地环境中,并从操作系统获取 seed。接下来,调用随机数生成器的 `gen_range` 方法。这个方法由刚才引入到作用域的 `Rng` trait 定义。`gen_range` 方法获取两个数字作为参数,并生成一个范围在两者之间的随机数。它包含下限但不包含上限,所以需要指定 `1` 和 `101` 来请求一个 1 和 100 之间的数。 +接下来,我们在中间还新增加了两行。第一行调用了 `rand::thread_rng` 函数提供实际使用的随机数生成器:它位于当前执行线程的本地环境中,并从操作系统获取 seed。接着调用随机数生成器的 `gen_range` 方法。这个方法由 `use rand::Rng` 语句引入到作用域的 `Rng` trait 定义。`gen_range` 方法获取一个范围表达式(range expression)作为参数,并生成一个在此范围之间的随机数。这里使用的这类范围表达式的在 `start..end` 之间取值且包含下限但不包含上限,所以需要指定 `1` 和 `101` 来请求一个 1 和 100 之间的数。另外也可以使用范围 `1..=100`,这两者是等价的。 > 注意:你不可能凭空就知道应该 use 哪个 trait 以及该从 crate 中调用哪个方法。crate 的使用说明位于其文档中。Cargo 有一个很棒的功能是:运行 `cargo doc --open` 命令来构建所有本地依赖提供的文档,并在浏览器中打开。例如,假设你对 `rand` crate 中的其他功能感兴趣,你可以运行 `cargo doc --open` 并点击左侧导航栏中的 `rand`。 @@ -389,17 +309,19 @@ fn main() { 尝试运行程序几次: -```text +```console $ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs + Finished dev [unoptimized + debuginfo] target(s) in 2.53s Running `target/debug/guessing_game` Guess the number! The secret number is: 7 Please input your guess. 4 You guessed: 4 + $ cargo run + Finished dev [unoptimized + debuginfo] target(s) in 0.02s Running `target/debug/guessing_game` Guess the number! The secret number is: 83 @@ -417,22 +339,7 @@ You guessed: 5 文件名: src/main.rs ```rust,ignore,does_not_compile -use std::io; -use std::cmp::Ordering; -use rand::Rng; - -fn main() { - - // ---snip--- - - println!("You guessed: {}", guess); - - match guess.cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => println!("You win!"), - } -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs:here}} ``` 示例 2-4:处理比较两个数字可能的返回值 @@ -441,80 +348,46 @@ fn main() { 接着,底部的五行新代码使用了 `Ordering` 类型,`cmp` 方法用来比较两个值并可以在任何可比较的值上调用。它获取一个被比较值的引用:这里是把 `guess` 与 `secret_number` 做比较。 然后它会返回一个刚才通过 `use` 引入作用域的 `Ordering` 枚举的成员。使用一个 [`match`][match] 表达式,根据对 `guess` 和 `secret_number` 调用 `cmp` 返回的 `Ordering` 成员来决定接下来做什么。 -[match]: ch06-02-match.html - 一个 `match` 表达式由 **分支(arms)** 构成。一个分支包含一个 **模式**(*pattern*)和表达式开头的值与分支模式相匹配时应该执行的代码。Rust 获取提供给 `match` 的值并挨个检查每个分支的模式。`match` 结构和模式是 Rust 中强大的功能,它体现了代码可能遇到的多种情形,并帮助你确保没有遗漏处理。这些功能将分别在第六章和第十八章详细介绍。 让我们看看使用 `match` 表达式的例子。假设用户猜了 50,这时随机生成的秘密数字是 38。比较 50 与 38 时,因为 50 比 38 要大,`cmp` 方法会返回 `Ordering::Greater`。`Ordering::Greater` 是 `match` 表达式得到的值。它检查第一个分支的模式,`Ordering::Less` 与 `Ordering::Greater`并不匹配,所以它忽略了这个分支的代码并来到下一个分支。下一个分支的模式是 `Ordering::Greater`,**正确** 匹配!这个分支关联的代码被执行,在屏幕打印出 `Too big!`。`match` 表达式就此终止,因为该场景下没有检查最后一个分支的必要。 然而,示例 2-4 的代码并不能编译,可以尝试一下: -```text -$ cargo build - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) -error[E0308]: mismatched types - --> src/main.rs:23:21 - | -23 | match guess.cmp(&secret_number) { - | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found integer - | - = note: expected type `&std::string::String` - = note: found type `&{integer}` - -error: aborting due to previous error -Could not compile `guessing_game`. +```console +{{#include ../listings/ch02-guessing-game-tutorial/listing-02-04/output.txt}} ``` -错误的核心表明这里有 **不匹配的类型**(*mismatched types*)。Rust 有一个静态强类型系统,同时也有类型推断。当我们写出 `let guess = String::new()` 时,Rust 推断出 `guess` 应该是 `String` 类型,并不需要我们写出类型。另一方面,`secret_number`,是数字类型。几个数字类型拥有 1 到 100 之间的值:32 位数字 `i32`;32 位无符号数字 `u32`;64 位数字 `i64` 等等。Rust 默认使用 `i32`,所以它是 `secret_number` 的类型,除非增加类型信息,或任何能让 Rust 推断出不同数值类型的信息。这里错误的原因在于 Rust 不会比较字符串类型和数字类型。 +错误的核心表明这里有 **不匹配的类型**(_mismatched types_)。Rust 有一个静态强类型系统,同时也有类型推断。当我们写出 `let guess = String::new()` 时,Rust 推断出 `guess` 应该是 `String` 类型,并不需要我们写出类型。另一方面,`secret_number`,是数字类型。几个数字类型拥有 1 到 100 之间的值:32 位数字 `i32`;32 位无符号数字 `u32`;64 位数字 `i64` 等等。Rust 默认使用 `i32`,所以它是 `secret_number` 的类型,除非增加类型信息,或任何能让 Rust 推断出不同数值类型的信息。这里错误的原因在于 Rust 不会比较字符串类型和数字类型。 -所以我们必须把从输入中读取到的 `String` 转换为一个真正的数字类型,才好与秘密数字进行比较。这可以通过在 `main` 函数体中增加如下两行代码来实现: +所以我们必须把从输入中读取到的 `String` 转换为一个真正的数字类型,才好与秘密数字进行比较。这可以通过在 `main` 函数体中增加如下代码来实现: 文件名: src/main.rs ```rust,ignore -// --snip-- - - let mut guess = String::new(); - - io::stdin().read_line(&mut guess) - .expect("Failed to read line"); - - let guess: u32 = guess.trim().parse() - .expect("Please type a number!"); - - println!("You guessed: {}", guess); - - match guess.cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => println!("You win!"), - } -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs:here}} ``` -这两行新代码是: +这行新代码是: ```rust,ignore -let guess: u32 = guess.trim().parse() - .expect("Please type a number!"); +let guess: u32 = guess.trim().parse().expect("Please type a number!"); ``` -这里创建了一个叫做 `guess` 的变量。不过等等,不是已经有了一个叫做 `guess` 的变量了吗?确实如此,不过 Rust 允许用一个新值来 **隐藏** (*shadow*) `guess` 之前的值。这个功能常用在需要转换值类型之类的场景。它允许我们复用 `guess` 变量的名字,而不是被迫创建两个不同变量,诸如 `guess_str` 和 `guess` 之类。(第三章会介绍 shadowing 的更多细节。) +这里创建了一个叫做 `guess` 的变量。不过等等,不是已经有了一个叫做 `guess` 的变量了吗?确实如此,不过 Rust 允许用一个新值来 **隐藏** (_shadow_) `guess` 之前的值。这个功能常用在需要转换值类型之类的场景。它允许我们复用 `guess` 变量的名字,而不是被迫创建两个不同变量,诸如 `guess_str` 和 `guess` 之类。(第三章会介绍 shadowing 的更多细节。) 我们将 `guess` 绑定到 `guess.trim().parse()` 表达式上。表达式中的 `guess` 是包含输入的原始 `String` 类型。`String` 实例的 `trim` 方法会去除字符串开头和结尾的空白字符。`u32` 只能由数字字符转换,不过用户必须输入 enter 键才能让 `read_line` 返回,然而用户按下 enter 键时,会在字符串中增加一个换行(newline)符。例如,用户输入 5 并按下 enter,`guess` 看起来像这样:`5\n`。`\n` 代表 “换行”,回车键。`trim` 方法消除 `\n`,只留下 `5`。 -[字符串的 `parse` 方法][parse] 将字符串解析成数字。因为这个方法可以解析多种数字类型,因此需要告诉 Rust 具体的数字类型,这里通过 `let guess: u32` 指定。`guess` 后面的冒号(`:`)告诉 Rust 我们指定了变量的类型。Rust 有一些内建的数字类型;`u32` 是一个无符号的 32 位整型。对于不大的正整数来说,它是不错的类型,第三章还会讲到其他数字类型。另外,程序中的 `u32` 注解以及与 `secret_number` 的比较,意味着 Rust 会推断出 `secret_number` 也是 `u32` 类型。现在可以使用相同类型比较两个值了! +[字符串的 `parse` 方法][parse] 将字符串解析成数字。因为这个方法可以解析多种数字类型,因此需要告诉 Rust 具体的数字类型,这里通过 `let guess: u32` 指定。`guess` 后面的冒号(`:`)告诉 Rust 我们指定了变量的类型。Rust 有一些内建的数字类型;`u32` 是一个无符号的 32 位整型。对于不大的正整数来说,它是不错的默认类型,第三章还会讲到其他数字类型。另外,程序中的 `u32` 注解以及与 `secret_number` 的比较,意味着 Rust 会推断出 `secret_number` 也是 `u32` 类型。现在可以使用相同类型比较两个值了! -[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse - -`parse` 调用很容易产生错误。例如,字符串中包含 `A👍%`,就无法将其转换为一个数字。因此,`parse` 方法返回一个 `Result` 类型。像之前 [“使用 `Result` 类型来处理潜在的错误”](#handling-potential-failure-with-the-result-type) 讨论的 `read_line` 方法那样,再次按部就班的用 `expect` 方法处理即可。如果 `parse` 不能从字符串生成一个数字,返回一个 `Result` 的 `Err` 成员时,`expect` 会使游戏崩溃并打印附带的信息。如果 `parse` 成功地将字符串转换为一个数字,它会返回 `Result` 的 `Ok` 成员,然后 `expect` 会返回 `Ok` 值中的数字。 +`parse` 方法只有在字符逻辑上可以转换为数字的时候才能工作所以非常容易出错。例如,字符串中包含 `A👍%`,就无法将其转换为一个数字。因此,`parse` 方法返回一个 `Result` 类型。像之前 [“使用 `Result` 类型来处理潜在的错误”](#handling-potential-failure-with-the-result-type) 讨论的 `read_line` 方法那样,再次按部就班的用 `expect` 方法处理即可。如果 `parse` 不能从字符串生成一个数字,返回一个 `Result` 的 `Err` 成员时,`expect` 会使游戏崩溃并打印附带的信息。如果 `parse` 成功地将字符串转换为一个数字,它会返回 `Result` 的 `Ok` 成员,然后 `expect` 会返回 `Ok` 值中的数字。 现在让我们运行程序! -```text +```console $ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 0.43 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.43s Running `target/debug/guessing_game` Guess the number! The secret number is: 58 @@ -530,37 +403,22 @@ Too big! ## 使用循环来允许多次猜测 -`loop` 关键字创建了一个无限循环。将其加入后,用户可以反复猜测: +`loop` 关键字创建了一个无限循环。加入循环后给了用户多次猜数字的机会: 文件名: src/main.rs ```rust,ignore -// --snip-- - - println!("The secret number is: {}", secret_number); - - loop { - println!("Please input your guess."); - - // --snip-- - - match guess.cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => println!("You win!"), - } - } -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs:here}} ``` -如上所示,我们将提示用户猜测之后的所有内容放入了循环。确保 loop 循环中的代码多缩进四个空格,再次运行程序。注意这里有一个新问题,因为程序忠实地执行了我们的要求:永远地请求另一个猜测,用户好像无法退出啊! +如上所示,我们将提示用户猜测之后的所有内容移动到了循环中。确保 loop 循环中的代码多缩进四个空格,再次运行程序。注意这里有一个新问题,因为程序忠实地执行了我们的要求:永远地请求另一个猜测,用户好像无法退出啊! 用户总能使用 ctrl-c 终止程序。不过还有另一个方法跳出无限循环,就是 [“比较猜测与秘密数字”](#comparing-the-guess-to-the-secret-number) 部分提到的 `parse`:如果用户输入的答案不是一个数字,程序会崩溃。用户可以利用这一点来退出,如下所示: -```text +```console $ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 1.50 secs + Finished dev [unoptimized + debuginfo] target(s) in 1.50s Running `target/debug/guessing_game` Guess the number! The secret number is: 59 @@ -578,9 +436,8 @@ You guessed: 59 You win! Please input your guess. quit -thread 'main' panicked at 'Please type a number!: ParseIntError { kind: InvalidDigit }', src/libcore/result.rs:785 -note: Run with `RUST_BACKTRACE=1` for a backtrace. -error: Process didn't exit successfully: `target/debug/guess` (exit code: 101) +thread 'main' panicked at 'Please type a number!: ParseIntError { kind: InvalidDigit }', src/main.rs:28:47 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` 输入 `quit` 确实退出了程序,同时其他任何非数字输入也一样。然而,这并不理想,我们想要当猜测正确的数字时游戏能自动退出。 @@ -592,18 +449,7 @@ error: Process didn't exit successfully: `target/debug/guess` (exit code: 101) 文件名: src/main.rs ```rust,ignore -// --snip-- - - match guess.cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => { - println!("You win!"); - break; - } - } - } -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs:here}} ``` 通过在 `You win!` 之后增加一行 `break`,用户猜对了神秘数字后会退出循环。退出循环也意味着退出程序,因为循环是 `main` 的最后一部分。 @@ -615,19 +461,7 @@ error: Process didn't exit successfully: `target/debug/guess` (exit code: 101) 文件名: src/main.rs ```rust,ignore -// --snip-- - -io::stdin().read_line(&mut guess) - .expect("Failed to read line"); - -let guess: u32 = match guess.trim().parse() { - Ok(num) => num, - Err(_) => continue, -}; - -println!("You guessed: {}", guess); - -// --snip-- +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs:here}} ``` 示例 2-5: 忽略非数字的猜测并重新请求数字而不是让程序崩溃 @@ -636,13 +470,14 @@ println!("You guessed: {}", guess); 如果 `parse` 能够成功的将字符串转换为一个数字,它会返回一个包含结果数字的 `Ok`。这个 `Ok` 值与 `match` 第一个分支的模式相匹配,该分支对应的动作返回 `Ok` 值中的数字 `num`,最后如愿变成新创建的 `guess` 变量。 -如果 `parse` *不* 能将字符串转换为一个数字,它会返回一个包含更多错误信息的 `Err`。`Err` 值不能匹配第一个 `match` 分支的 `Ok(num)` 模式,但是会匹配第二个分支的 `Err(_)` 模式:`_` 是一个通配符值,本例中用来匹配所有 `Err` 值,不管其中有何种信息。所以程序会执行第二个分支的动作,`continue` 意味着进入 `loop` 的下一次循环,请求另一个猜测。这样程序就有效的忽略了 `parse` 可能遇到的所有错误! +如果 `parse` **不**能将字符串转换为一个数字,它会返回一个包含更多错误信息的 `Err`。`Err` 值不能匹配第一个 `match` 分支的 `Ok(num)` 模式,但是会匹配第二个分支的 `Err(_)` 模式:`_` 是一个通配符值,本例中用来匹配所有 `Err` 值,不管其中有何种信息。所以程序会执行第二个分支的动作,`continue` 意味着进入 `loop` 的下一次循环,请求另一个猜测。这样程序就有效的忽略了 `parse` 可能遇到的所有错误! 现在万事俱备,只需运行 `cargo run`: -```text +```console $ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) + Finished dev [unoptimized + debuginfo] target(s) in 4.45s Running `target/debug/guessing_game` Guess the number! The secret number is: 61 @@ -667,40 +502,7 @@ You win! 文件名: src/main.rs ```rust,ignore -use std::io; -use std::cmp::Ordering; -use rand::Rng; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1, 101); - - loop { - println!("Please input your guess."); - - let mut guess = String::new(); - - io::stdin().read_line(&mut guess) - .expect("Failed to read line"); - - let guess: u32 = match guess.trim().parse() { - Ok(num) => num, - Err(_) => continue, - }; - - println!("You guessed: {}", guess); - - match guess.cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => { - println!("You win!"); - break; - } - } - } -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs}} ``` 示例 2-6:猜猜看游戏的完整代码 @@ -711,5 +513,21 @@ fn main() { 本项目通过动手实践,向你介绍了 Rust 新概念:`let`、`match`、方法、关联函数、使用外部 crate 等等,接下来的几章,你会继续深入学习这些概念。第三章介绍大部分编程语言都有的概念,比如变量、数据类型和函数,以及如何在 Rust 中使用它们。第四章探索所有权(ownership),这是一个 Rust 同其他语言大不相同的功能。第五章讨论结构体和方法的语法,而第六章侧重解释枚举。 -[variables-and-mutability]: -ch03-01-variables-and-mutability.html#variables-and-mutability +[prelude]: https://doc.rust-lang.org/std/prelude/index.html +[variables-and-mutability]: ch03-01-variables-and-mutability.html#variables-and-mutability +[comments]: ch03-04-comments.html +[string]: https://doc.rust-lang.org/std/string/struct.String.html +[iostdin]: https://doc.rust-lang.org/std/io/struct.Stdin.html +[read_line]: https://doc.rust-lang.org/std/io/struct.Stdin.html#method.read_line +[ioresult]: https://doc.rust-lang.org/std/io/type.Result.html +[result]: https://doc.rust-lang.org/std/result/enum.Result.html +[enums]: ch06-00-enums.html +[expect]: https://doc.rust-lang.org/std/result/enum.Result.html#method.expect +[recover]: ch09-02-recoverable-errors-with-result.html +[randcrate]: https://crates.io/crates/rand +[semver]: http://semver.org +[cratesio]: https://crates.io/ +[doccargo]: http://doc.crates.io +[doccratesio]: http://doc.crates.io/crates-io.html +[match]: ch06-02-match.html +[parse]: https://doc.rust-lang.org/std/primitive.str.html#method.parse diff --git a/src/title-page.md b/src/title-page.md index df61563..d57037f 100644 --- a/src/title-page.md +++ b/src/title-page.md @@ -1,29 +1,19 @@ # Rust 程序设计语言 > [title-page.md](https://github.com/rust-lang/book/blob/master/src/title-page.md)
-> commit a2bd349f8654f5c45ad1f07394225f946954b8ef +> commit 4491cee45aef865bffc27ed5b68dd6ce6a1598a8 **Steve Klabnik 和 Carol Nichols,以及来自 Rust 社区的贡献(Rust 中文社区翻译)** -本书假设你使用 Rust 1.41.0 或更新的版本,且在所有的项目中的 *Cargo.toml* 文件中通过 `edition="2018"` 采用 Rust 2018 Edition 规范。请查看 [第一章的 “安装” 部分][install] 了解如何安装和升级 Rust,并查看新的 [附录 E][editions] 了解版本相关的信息。 - -Rust 程序设计语言的 2018 Edition 包含许多的改进使得 Rust 更为工程化并更为容易学习。本书的此次迭代包括了很多反映这些改进的修改: - -- 第七章 “使用包、Crate 和模块管理不断增长的项目” 基本上被重写了。模块系统和路径(path)的工作方式变得更为一致。 -- 第十章新增了名为 “trait 作为参数” 和 “返回实现了 trait 的类型” 部分来解释新的 `impl Trait` 语法。 -- 第十一章新增了一个名为 “在测试中使用 `Result`” 的部分来展示如何使用 `?` 运算符来编写测试 -- 第十九章的 “高级生命周期” 部分被移除了,因为编译器的改进使得其内容变得更为少见。 -- 之前的附录 D “宏” 得到了补充,包括了过程宏并移动到了第十九章的 “宏” 部分。 -- 附录 A “关键字” 也介绍了新的原始标识符(raw identifiers)功能,这使得采用 2015 Edition 编写的 Rust 代码可以与 2018 Edition 互通。 -- 现在的附录 D 名为 “实用开发工具”,它介绍了最近发布的可以帮助你编写 Rust 代码的工具。 -- 我们还修复了全书中许多错误和不准确的描述。感谢报告了这些问题的读者们! - -注意任何 “Rust 程序设计语言” 早期迭代中的代码在项目的 *Cargo.toml* 中不包含 `edition="2018"` 时仍可以继续编译,哪怕你更新了 Rust 编译器的版本。Rust 的后向兼容性保证了这一切可以正常运行! +本书假设你使用 Rust 1.58(2022-01-13 发布) 或更新的版本。请查看 [第一章的 “安装” 部分][install] 了解如何安装和升级 Rust。(并查看新的 [附录 E][editions] 了解版本相关的信息。) 本书的 HTML 版本可以在 [https://doc.rust-lang.org/stable/book/](https://doc.rust-lang.org/stable/book/) ([简体中文译本](https://kaisery.github.io/trpl-zh-cn/))在线阅读,离线版则包含在通过 `rustup` 安装的 Rust 中;运行 `rustup docs --book` 可以打开。 +本书还有一些社区 [翻译][translations] 的版本。 + 本书的 [纸质版和电子书由 No Starch Press][nsprust] 发行。 [install]: ch01-01-installation.html [editions]: appendix-05-editions.html [nsprust]: https://nostarch.com/rust +[translations]: appendix-06-translation.html