From 5c71aac64380f74f34cd9a158cc2b1d9122b5ceb Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Tue, 26 Mar 2019 16:21:36 -0400 Subject: [PATCH] Extract code listings to separate files --- ci/dictionary.txt | 3 + .../listing-02-01/Cargo.lock | 6 + .../listing-02-01/Cargo.toml | 9 + .../listing-02-01/src/main.rs | 14 + .../listing-02-02/Cargo.lock | 87 +++ .../listing-02-02/Cargo.toml | 10 + .../listing-02-02/src/main.rs | 14 + .../listing-02-03/Cargo.lock | 87 +++ .../listing-02-03/Cargo.toml | 10 + .../listing-02-03/src/main.rs | 27 + .../listing-02-04/Cargo.lock | 87 +++ .../listing-02-04/Cargo.toml | 10 + .../listing-02-04/output.txt | 21 + .../listing-02-04/src/main.rs | 32 ++ .../listing-02-05/Cargo.lock | 87 +++ .../listing-02-05/Cargo.toml | 10 + .../listing-02-05/src/main.rs | 44 ++ .../listing-02-06/Cargo.lock | 87 +++ .../listing-02-06/Cargo.toml | 10 + .../listing-02-06/src/main.rs | 34 ++ .../no-listing-01-cargo-new/Cargo.lock | 6 + .../no-listing-01-cargo-new/Cargo.toml | 9 + .../no-listing-01-cargo-new/output.txt | 5 + .../no-listing-01-cargo-new/src/main.rs | 3 + .../no-listing-02-without-expect/Cargo.lock | 6 + .../no-listing-02-without-expect/Cargo.toml | 9 + .../no-listing-02-without-expect/output.txt | 12 + .../no-listing-02-without-expect/src/main.rs | 13 + .../Cargo.lock | 87 +++ .../Cargo.toml | 10 + .../src/main.rs | 33 ++ .../no-listing-04-looping/Cargo.lock | 87 +++ .../no-listing-04-looping/Cargo.toml | 10 + .../no-listing-04-looping/src/main.rs | 40 ++ .../no-listing-05-quitting/Cargo.lock | 87 +++ .../no-listing-05-quitting/Cargo.toml | 10 + .../no-listing-05-quitting/src/main.rs | 38 ++ .../listing-03-01/Cargo.lock | 4 + .../listing-03-01/Cargo.toml | 7 + .../listing-03-01/src/main.rs | 3 + .../listing-03-02/Cargo.lock | 4 + .../listing-03-02/Cargo.toml | 7 + .../listing-03-02/output.txt | 5 + .../listing-03-02/src/main.rs | 10 + .../listing-03-03/Cargo.lock | 4 + .../listing-03-03/Cargo.toml | 7 + .../listing-03-03/src/main.rs | 11 + .../listing-03-04/Cargo.lock | 4 + .../listing-03-04/Cargo.toml | 7 + .../listing-03-04/output.txt | 9 + .../listing-03-04/src/main.rs | 10 + .../listing-03-05/Cargo.lock | 4 + .../listing-03-05/Cargo.toml | 7 + .../listing-03-05/src/main.rs | 7 + .../Cargo.lock | 6 + .../Cargo.toml | 7 + .../output.txt | 20 + .../src/main.rs | 6 + .../no-listing-02-adding-mut/Cargo.lock | 6 + .../no-listing-02-adding-mut/Cargo.toml | 7 + .../no-listing-02-adding-mut/output.txt | 6 + .../no-listing-02-adding-mut/src/main.rs | 6 + .../no-listing-03-shadowing/Cargo.lock | 6 + .../no-listing-03-shadowing/Cargo.toml | 7 + .../no-listing-03-shadowing/output.txt | 5 + .../no-listing-03-shadowing/src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 6 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/main.rs | 6 + .../no-listing-06-floating-point/Cargo.lock | 4 + .../no-listing-06-floating-point/Cargo.toml | 7 + .../no-listing-06-floating-point/src/main.rs | 5 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 16 + .../no-listing-08-boolean/Cargo.lock | 4 + .../no-listing-08-boolean/Cargo.toml | 7 + .../no-listing-08-boolean/src/main.rs | 5 + .../no-listing-09-char/Cargo.lock | 4 + .../no-listing-09-char/Cargo.toml | 7 + .../no-listing-09-char/src/main.rs | 5 + .../no-listing-10-tuples/Cargo.lock | 4 + .../no-listing-10-tuples/Cargo.toml | 7 + .../no-listing-10-tuples/src/main.rs | 3 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 7 + .../no-listing-12-tuple-indexing/Cargo.lock | 4 + .../no-listing-12-tuple-indexing/Cargo.toml | 7 + .../no-listing-12-tuple-indexing/src/main.rs | 9 + .../no-listing-13-arrays/Cargo.lock | 4 + .../no-listing-13-arrays/Cargo.toml | 7 + .../no-listing-13-arrays/src/main.rs | 3 + .../no-listing-14-array-indexing/Cargo.lock | 4 + .../no-listing-14-array-indexing/Cargo.toml | 7 + .../no-listing-14-array-indexing/src/main.rs | 6 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 6 + .../src/main.rs | 8 + .../no-listing-16-functions/Cargo.lock | 4 + .../no-listing-16-functions/Cargo.toml | 7 + .../no-listing-16-functions/output.txt | 6 + .../no-listing-16-functions/src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 5 + .../src/main.rs | 7 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 6 + .../src/main.rs | 8 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 3 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 10 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 5 + .../src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 21 + .../src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 3 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 4 + .../no-listing-26-if-true/Cargo.lock | 4 + .../no-listing-26-if-true/Cargo.toml | 7 + .../no-listing-26-if-true/output.txt | 5 + .../no-listing-26-if-true/src/main.rs | 9 + .../no-listing-27-if-false/Cargo.lock | 4 + .../no-listing-27-if-false/Cargo.toml | 7 + .../no-listing-27-if-false/output.txt | 5 + .../no-listing-27-if-false/src/main.rs | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/main.rs | 7 + .../no-listing-29-if-not-equal-0/Cargo.lock | 4 + .../no-listing-29-if-not-equal-0/Cargo.toml | 7 + .../no-listing-29-if-not-equal-0/src/main.rs | 7 + .../no-listing-30-else-if/Cargo.lock | 4 + .../no-listing-30-else-if/Cargo.toml | 7 + .../no-listing-30-else-if/output.txt | 5 + .../no-listing-30-else-if/src/main.rs | 13 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 24 + .../src/main.rs | 11 + .../no-listing-32-loop/Cargo.lock | 6 + .../no-listing-32-loop/Cargo.toml | 7 + .../no-listing-32-loop/src/main.rs | 5 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 13 + .../no-listing-34-for-range/Cargo.lock | 4 + .../no-listing-34-for-range/Cargo.toml | 7 + .../no-listing-34-for-range/src/main.rs | 6 + .../Cargo.lock | 6 + .../Cargo.toml | 9 + .../output.txt | 17 + .../src/main.rs | 3 + .../listing-04-01/Cargo.lock | 4 + .../listing-04-01/Cargo.toml | 7 + .../listing-04-01/src/main.rs | 9 + .../listing-04-02/Cargo.lock | 4 + .../listing-04-02/Cargo.toml | 7 + .../listing-04-02/src/main.rs | 6 + .../listing-04-03/Cargo.lock | 4 + .../listing-04-03/Cargo.toml | 7 + .../listing-04-03/src/main.rs | 23 + .../listing-04-04/Cargo.lock | 4 + .../listing-04-04/Cargo.toml | 7 + .../listing-04-04/src/main.rs | 29 + .../listing-04-05/Cargo.lock | 4 + .../listing-04-05/Cargo.toml | 7 + .../listing-04-05/src/main.rs | 13 + .../listing-04-06/Cargo.lock | 4 + .../listing-04-06/Cargo.toml | 7 + .../listing-04-06/output.txt | 16 + .../listing-04-06/src/main.rs | 9 + .../listing-04-07/Cargo.lock | 4 + .../listing-04-07/Cargo.toml | 7 + .../listing-04-07/src/main.rs | 22 + .../listing-04-08/Cargo.lock | 4 + .../listing-04-08/Cargo.toml | 7 + .../listing-04-08/src/main.rs | 24 + .../listing-04-09/Cargo.lock | 4 + .../listing-04-09/Cargo.toml | 7 + .../listing-04-09/src/main.rs | 31 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 9 + .../no-listing-02-string-scope/Cargo.lock | 4 + .../no-listing-02-string-scope/Cargo.toml | 7 + .../no-listing-02-string-scope/src/main.rs | 10 + .../no-listing-03-string-move/Cargo.lock | 4 + .../no-listing-03-string-move/Cargo.toml | 7 + .../no-listing-03-string-move/src/main.rs | 6 + .../Cargo.lock | 6 + .../Cargo.toml | 7 + .../output.txt | 19 + .../src/main.rs | 8 + .../no-listing-05-clone/Cargo.lock | 4 + .../no-listing-05-clone/Cargo.toml | 7 + .../no-listing-05-clone/src/main.rs | 8 + .../no-listing-06-copy/Cargo.lock | 4 + .../no-listing-06-copy/Cargo.toml | 7 + .../no-listing-06-copy/src/main.rs | 8 + .../no-listing-07-reference/Cargo.lock | 4 + .../no-listing-07-reference/Cargo.toml | 7 + .../no-listing-07-reference/src/main.rs | 15 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 14 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 19 + .../src/main.rs | 10 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 12 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 20 + .../src/main.rs | 11 + .../Cargo.toml | 7 + .../src/main.rs | 13 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 13 + .../no-listing-16-no-dangle/Cargo.lock | 4 + .../no-listing-16-no-dangle/Cargo.toml | 7 + .../no-listing-16-no-dangle/src/main.rs | 11 + .../no-listing-17-slice/Cargo.lock | 4 + .../no-listing-17-slice/Cargo.toml | 7 + .../no-listing-17-slice/src/main.rs | 8 + .../no-listing-18-first-word-slice/Cargo.lock | 4 + .../no-listing-18-first-word-slice/Cargo.toml | 7 + .../src/main.rs | 16 + .../no-listing-19-slice-error/Cargo.lock | 4 + .../no-listing-19-slice-error/Cargo.toml | 7 + .../no-listing-19-slice-error/output.txt | 20 + .../no-listing-19-slice-error/src/main.rs | 23 + .../listing-05-01/Cargo.lock | 4 + .../listing-05-01/Cargo.toml | 7 + .../listing-05-01/src/main.rs | 11 + .../listing-05-02/Cargo.lock | 4 + .../listing-05-02/Cargo.toml | 7 + .../listing-05-02/src/main.rs | 17 + .../listing-05-03/Cargo.lock | 4 + .../listing-05-03/Cargo.toml | 7 + .../listing-05-03/src/main.rs | 19 + .../listing-05-04/Cargo.lock | 4 + .../listing-05-04/Cargo.toml | 7 + .../listing-05-04/src/main.rs | 21 + .../listing-05-05/Cargo.lock | 4 + .../listing-05-05/Cargo.toml | 7 + .../listing-05-05/src/main.rs | 21 + .../listing-05-06/Cargo.lock | 4 + .../listing-05-06/Cargo.toml | 7 + .../listing-05-06/src/main.rs | 24 + .../listing-05-07/Cargo.lock | 4 + .../listing-05-07/Cargo.toml | 7 + .../listing-05-07/src/main.rs | 23 + .../listing-05-08/Cargo.lock | 4 + .../listing-05-08/Cargo.toml | 7 + .../listing-05-08/output.txt | 5 + .../listing-05-08/src/main.rs | 17 + .../listing-05-09/Cargo.lock | 4 + .../listing-05-09/Cargo.toml | 7 + .../listing-05-09/src/main.rs | 12 + .../listing-05-10/Cargo.lock | 4 + .../listing-05-10/Cargo.toml | 7 + .../listing-05-10/src/main.rs | 17 + .../listing-05-11/Cargo.lock | 4 + .../listing-05-11/Cargo.toml | 7 + .../listing-05-11/output.txt | 18 + .../listing-05-11/src/main.rs | 10 + .../listing-05-12/Cargo.lock | 4 + .../listing-05-12/Cargo.toml | 7 + .../listing-05-12/output.txt | 5 + .../listing-05-12/src/main.rs | 11 + .../listing-05-13/Cargo.lock | 4 + .../listing-05-13/Cargo.toml | 7 + .../listing-05-13/src/main.rs | 20 + .../listing-05-14/Cargo.lock | 4 + .../listing-05-14/Cargo.toml | 7 + .../listing-05-14/src/main.rs | 8 + .../listing-05-15/Cargo.lock | 4 + .../listing-05-15/Cargo.toml | 7 + .../listing-05-15/src/main.rs | 26 + .../listing-05-16/Cargo.lock | 4 + .../listing-05-16/Cargo.toml | 7 + .../listing-05-16/src/main.rs | 29 + .../no-listing-01-tuple-structs/Cargo.lock | 4 + .../no-listing-01-tuple-structs/Cargo.toml | 7 + .../no-listing-01-tuple-structs/src/main.rs | 9 + .../Cargo.lock | 6 + .../Cargo.toml | 9 + .../output.txt | 20 + .../src/main.rs | 15 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 17 + .../output-only-01-debug/Cargo.lock | 4 + .../output-only-01-debug/Cargo.toml | 7 + .../output-only-01-debug/output.txt | 18 + .../output-only-01-debug/src/main.rs | 10 + .../output-only-02-pretty-debug/Cargo.lock | 4 + .../output-only-02-pretty-debug/Cargo.toml | 7 + .../output-only-02-pretty-debug/output.txt | 8 + .../output-only-02-pretty-debug/src/main.rs | 11 + .../listing-06-01/Cargo.lock | 4 + .../listing-06-01/Cargo.toml | 7 + .../listing-06-01/src/main.rs | 23 + .../listing-06-02/Cargo.lock | 4 + .../listing-06-02/Cargo.toml | 7 + .../listing-06-02/src/main.rs | 10 + .../listing-06-03/Cargo.lock | 4 + .../listing-06-03/Cargo.toml | 7 + .../listing-06-03/src/main.rs | 19 + .../listing-06-04/Cargo.lock | 4 + .../listing-06-04/Cargo.toml | 7 + .../listing-06-04/src/main.rs | 17 + .../listing-06-05/Cargo.lock | 4 + .../listing-06-05/Cargo.toml | 7 + .../listing-06-05/src/main.rs | 18 + .../listing-06-06/Cargo.lock | 4 + .../listing-06-06/Cargo.toml | 7 + .../listing-06-06/src/main.rs | 9 + .../no-listing-01-defining-enums/Cargo.lock | 4 + .../no-listing-01-defining-enums/Cargo.toml | 7 + .../no-listing-01-defining-enums/src/main.rs | 22 + .../no-listing-02-enum-with-data/Cargo.lock | 4 + .../no-listing-02-enum-with-data/Cargo.toml | 7 + .../no-listing-02-enum-with-data/src/main.rs | 12 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 12 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 12 + .../no-listing-05-methods-on-enums/Cargo.lock | 4 + .../no-listing-05-methods-on-enums/Cargo.toml | 7 + .../src/main.rs | 19 + .../no-listing-06-option-examples/Cargo.lock | 4 + .../no-listing-06-option-examples/Cargo.toml | 7 + .../no-listing-06-option-examples/src/main.rs | 8 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../src/main.rs | 8 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 22 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 31 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../src/main.rs | 13 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 12 + .../no-listing-12-if-let/Cargo.lock | 4 + .../no-listing-12-if-let/Cargo.toml | 7 + .../no-listing-12-if-let/src/main.rs | 8 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 24 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 25 + .../listing-07-01/Cargo.lock | 4 + .../listing-07-01/Cargo.toml | 7 + .../listing-07-01/src/lib.rs | 19 + .../listing-07-03/Cargo.lock | 4 + .../listing-07-03/Cargo.toml | 7 + .../listing-07-03/output.txt | 20 + .../listing-07-03/src/lib.rs | 13 + .../listing-07-05/Cargo.lock | 4 + .../listing-07-05/Cargo.toml | 7 + .../listing-07-05/output.txt | 20 + .../listing-07-05/src/lib.rs | 13 + .../listing-07-07/Cargo.lock | 4 + .../listing-07-07/Cargo.toml | 7 + .../listing-07-07/src/lib.rs | 17 + .../listing-07-08/Cargo.lock | 4 + .../listing-07-08/Cargo.toml | 7 + .../listing-07-08/src/lib.rs | 14 + .../listing-07-09/Cargo.lock | 4 + .../listing-07-09/Cargo.toml | 7 + .../listing-07-09/src/lib.rs | 27 + .../listing-07-10/Cargo.lock | 4 + .../listing-07-10/Cargo.toml | 7 + .../listing-07-10/src/lib.rs | 11 + .../listing-07-11/Cargo.lock | 4 + .../listing-07-11/Cargo.toml | 7 + .../listing-07-11/src/lib.rs | 17 + .../listing-07-12/Cargo.lock | 4 + .../listing-07-12/Cargo.toml | 7 + .../listing-07-12/src/lib.rs | 17 + .../listing-07-13/Cargo.lock | 4 + .../listing-07-13/Cargo.toml | 7 + .../listing-07-13/src/lib.rs | 17 + .../listing-07-14/Cargo.lock | 4 + .../listing-07-14/Cargo.toml | 7 + .../listing-07-14/src/main.rs | 6 + .../listing-07-15/Cargo.lock | 4 + .../listing-07-15/Cargo.toml | 7 + .../listing-07-15/src/lib.rs | 18 + .../listing-07-16/Cargo.lock | 4 + .../listing-07-16/Cargo.toml | 7 + .../listing-07-16/src/lib.rs | 18 + .../listing-07-17/Cargo.lock | 4 + .../listing-07-17/Cargo.toml | 7 + .../listing-07-17/src/lib.rs | 17 + .../listing-07-18/Cargo.lock | 89 ++++ .../listing-07-18/Cargo.toml | 8 + .../listing-07-18/src/main.rs | 28 + .../listing-07-19/Cargo.lock | 4 + .../listing-07-19/Cargo.toml | 7 + .../listing-07-19/src/lib.rs | 2 + .../listing-07-20/Cargo.lock | 4 + .../listing-07-20/Cargo.toml | 7 + .../listing-07-20/src/lib.rs | 1 + .../listing-07-21-and-22/Cargo.lock | 4 + .../listing-07-21-and-22/Cargo.toml | 7 + .../src/front_of_house.rs | 3 + .../listing-07-21-and-22/src/lib.rs | 9 + .../no-listing-01-use-std-unnested/Cargo.lock | 87 +++ .../no-listing-01-use-std-unnested/Cargo.toml | 10 + .../src/main.rs | 29 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/front_of_house.rs | 1 + .../src/front_of_house/hosting.rs | 1 + .../src/lib.rs | 9 + .../listing-08-01/Cargo.lock | 4 + .../listing-08-01/Cargo.toml | 7 + .../listing-08-01/src/main.rs | 5 + .../listing-08-02/Cargo.lock | 4 + .../listing-08-02/Cargo.toml | 7 + .../listing-08-02/src/main.rs | 5 + .../listing-08-03/Cargo.lock | 4 + .../listing-08-03/Cargo.toml | 7 + .../listing-08-03/src/main.rs | 10 + .../listing-08-04/Cargo.lock | 4 + .../listing-08-04/Cargo.toml | 7 + .../listing-08-04/src/main.rs | 10 + .../listing-08-05/Cargo.lock | 4 + .../listing-08-05/Cargo.toml | 7 + .../listing-08-05/src/main.rs | 13 + .../listing-08-06/Cargo.lock | 4 + .../listing-08-06/Cargo.toml | 7 + .../listing-08-06/src/main.rs | 8 + .../listing-08-07/Cargo.lock | 4 + .../listing-08-07/Cargo.toml | 7 + .../listing-08-07/output.txt | 20 + .../listing-08-07/src/main.rs | 11 + .../listing-08-08/Cargo.lock | 4 + .../listing-08-08/Cargo.toml | 7 + .../listing-08-08/src/main.rs | 8 + .../listing-08-09/Cargo.lock | 4 + .../listing-08-09/Cargo.toml | 7 + .../listing-08-09/src/main.rs | 8 + .../listing-08-10/Cargo.lock | 4 + .../listing-08-10/Cargo.toml | 7 + .../listing-08-10/src/main.rs | 15 + .../listing-08-11/Cargo.lock | 4 + .../listing-08-11/Cargo.toml | 7 + .../listing-08-11/src/main.rs | 5 + .../listing-08-12/Cargo.lock | 4 + .../listing-08-12/Cargo.toml | 7 + .../listing-08-12/src/main.rs | 10 + .../listing-08-13/Cargo.lock | 4 + .../listing-08-13/Cargo.toml | 7 + .../listing-08-13/src/main.rs | 5 + .../listing-08-14/Cargo.lock | 4 + .../listing-08-14/Cargo.toml | 7 + .../listing-08-14/src/main.rs | 19 + .../listing-08-15/Cargo.lock | 4 + .../listing-08-15/Cargo.toml | 7 + .../listing-08-15/src/main.rs | 6 + .../listing-08-16/Cargo.lock | 4 + .../listing-08-16/Cargo.toml | 7 + .../listing-08-16/src/main.rs | 8 + .../listing-08-17/Cargo.lock | 4 + .../listing-08-17/Cargo.toml | 7 + .../listing-08-17/src/main.rs | 6 + .../listing-08-18/Cargo.lock | 4 + .../listing-08-18/Cargo.toml | 7 + .../listing-08-18/src/main.rs | 7 + .../listing-08-19/Cargo.lock | 4 + .../listing-08-19/Cargo.toml | 7 + .../listing-08-19/output.txt | 16 + .../listing-08-19/src/main.rs | 6 + .../listing-08-20/Cargo.lock | 4 + .../listing-08-20/Cargo.toml | 7 + .../listing-08-20/src/main.rs | 10 + .../listing-08-21/Cargo.lock | 4 + .../listing-08-21/Cargo.toml | 7 + .../listing-08-21/src/main.rs | 10 + .../listing-08-22/Cargo.lock | 4 + .../listing-08-22/Cargo.toml | 7 + .../listing-08-22/src/main.rs | 13 + .../listing-08-23/Cargo.lock | 4 + .../listing-08-23/Cargo.toml | 7 + .../listing-08-23/src/main.rs | 13 + .../listing-08-24/Cargo.lock | 4 + .../listing-08-24/Cargo.toml | 7 + .../listing-08-24/src/main.rs | 12 + .../listing-08-25/Cargo.lock | 4 + .../listing-08-25/Cargo.toml | 7 + .../listing-08-25/src/main.rs | 13 + .../listing-08-26/Cargo.lock | 4 + .../listing-08-26/Cargo.toml | 7 + .../listing-08-26/src/main.rs | 16 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 9 + .../no-listing-02-format/Cargo.lock | 4 + .../no-listing-02-format/Cargo.toml | 7 + .../no-listing-02-format/src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 14 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 6 + .../src/main.rs | 5 + .../listing-09-01/Cargo.lock | 6 + .../listing-09-01/Cargo.toml | 7 + .../listing-09-01/output.txt | 6 + .../listing-09-01/src/main.rs | 5 + .../listing-09-03/Cargo.lock | 4 + .../listing-09-03/Cargo.toml | 7 + .../listing-09-03/src/main.rs | 5 + .../listing-09-04/Cargo.lock | 4 + .../listing-09-04/Cargo.toml | 7 + .../listing-09-04/output.txt | 6 + .../listing-09-04/src/main.rs | 12 + .../listing-09-05/Cargo.lock | 4 + .../listing-09-05/Cargo.toml | 7 + .../listing-09-05/src/main.rs | 17 + .../listing-09-06/Cargo.lock | 4 + .../listing-09-06/Cargo.toml | 7 + .../listing-09-06/src/main.rs | 25 + .../listing-09-07/Cargo.lock | 4 + .../listing-09-07/Cargo.toml | 7 + .../listing-09-07/src/main.rs | 16 + .../listing-09-08/Cargo.lock | 4 + .../listing-09-08/Cargo.toml | 7 + .../listing-09-08/src/main.rs | 17 + .../listing-09-09/Cargo.lock | 4 + .../listing-09-09/Cargo.toml | 7 + .../listing-09-09/src/main.rs | 12 + .../listing-09-10/Cargo.lock | 89 ++++ .../listing-09-10/Cargo.toml | 8 + .../listing-09-10/src/main.rs | 56 ++ .../no-listing-01-panic/Cargo.lock | 4 + .../no-listing-01-panic/Cargo.toml | 7 + .../no-listing-01-panic/output.txt | 6 + .../no-listing-01-panic/src/main.rs | 3 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/main.rs | 7 + .../no-listing-03-closures/Cargo.lock | 4 + .../no-listing-03-closures/Cargo.toml | 7 + .../no-listing-03-closures/src/main.rs | 14 + .../no-listing-04-unwrap/Cargo.lock | 4 + .../no-listing-04-unwrap/Cargo.toml | 7 + .../no-listing-04-unwrap/src/main.rs | 5 + .../no-listing-05-expect/Cargo.lock | 4 + .../no-listing-05-expect/Cargo.toml | 7 + .../no-listing-05-expect/src/main.rs | 5 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/main.rs | 5 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 8 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 7 + .../Cargo.lock | 89 ++++ .../Cargo.toml | 8 + .../src/main.rs | 46 ++ .../listing-10-01/Cargo.lock | 4 + .../listing-10-01/Cargo.toml | 7 + .../listing-10-01/src/main.rs | 18 + .../listing-10-02/Cargo.lock | 4 + .../listing-10-02/Cargo.toml | 7 + .../listing-10-02/src/main.rs | 25 + .../listing-10-03/Cargo.lock | 4 + .../listing-10-03/Cargo.toml | 7 + .../listing-10-03/src/main.rs | 31 ++ .../listing-10-04/Cargo.lock | 4 + .../listing-10-04/Cargo.toml | 7 + .../listing-10-04/src/main.rs | 43 ++ .../listing-10-05/Cargo.lock | 4 + .../listing-10-05/Cargo.toml | 7 + .../listing-10-05/output.txt | 18 + .../listing-10-05/src/main.rs | 23 + .../listing-10-06/Cargo.lock | 4 + .../listing-10-06/Cargo.toml | 7 + .../listing-10-06/src/main.rs | 9 + .../listing-10-07/Cargo.lock | 4 + .../listing-10-07/Cargo.toml | 7 + .../listing-10-07/output.txt | 17 + .../listing-10-07/src/main.rs | 8 + .../listing-10-08/Cargo.lock | 4 + .../listing-10-08/Cargo.toml | 7 + .../listing-10-08/src/main.rs | 10 + .../listing-10-09/Cargo.lock | 4 + .../listing-10-09/Cargo.toml | 7 + .../listing-10-09/src/main.rs | 16 + .../listing-10-10/Cargo.lock | 4 + .../listing-10-10/Cargo.toml | 7 + .../listing-10-10/src/main.rs | 24 + .../listing-10-11/Cargo.lock | 4 + .../listing-10-11/Cargo.toml | 7 + .../listing-10-11/src/main.rs | 22 + .../listing-10-12/Cargo.lock | 4 + .../listing-10-12/Cargo.toml | 7 + .../listing-10-12/src/lib.rs | 3 + .../listing-10-13/Cargo.lock | 4 + .../listing-10-13/Cargo.toml | 7 + .../listing-10-13/src/lib.rs | 31 ++ .../listing-10-14/Cargo.lock | 4 + .../listing-10-14/Cargo.toml | 7 + .../listing-10-14/src/lib.rs | 29 + .../listing-10-15/Cargo.lock | 4 + .../listing-10-15/Cargo.toml | 7 + .../listing-10-15/src/main.rs | 23 + .../listing-10-16/Cargo.lock | 4 + .../listing-10-16/Cargo.toml | 7 + .../listing-10-16/src/lib.rs | 25 + .../listing-10-17/Cargo.lock | 4 + .../listing-10-17/Cargo.toml | 7 + .../listing-10-17/output.txt | 19 + .../listing-10-17/src/main.rs | 14 + .../listing-10-18/Cargo.lock | 4 + .../listing-10-18/Cargo.toml | 7 + .../listing-10-18/src/main.rs | 14 + .../listing-10-19/Cargo.lock | 4 + .../listing-10-19/Cargo.toml | 7 + .../listing-10-19/src/main.rs | 12 + .../listing-10-20/Cargo.lock | 4 + .../listing-10-20/Cargo.toml | 7 + .../listing-10-20/src/main.rs | 7 + .../listing-10-21/Cargo.lock | 4 + .../listing-10-21/Cargo.toml | 7 + .../listing-10-21/output.txt | 16 + .../listing-10-21/src/main.rs | 17 + .../listing-10-22/Cargo.lock | 4 + .../listing-10-22/Cargo.toml | 7 + .../listing-10-22/src/main.rs | 17 + .../listing-10-23/Cargo.lock | 4 + .../listing-10-23/Cargo.toml | 7 + .../listing-10-23/src/main.rs | 19 + .../listing-10-24/Cargo.lock | 4 + .../listing-10-24/Cargo.toml | 7 + .../listing-10-24/output.txt | 18 + .../listing-10-24/src/main.rs | 19 + .../listing-10-25/Cargo.lock | 4 + .../listing-10-25/Cargo.toml | 7 + .../listing-10-25/src/main.rs | 11 + .../listing-10-26/Cargo.lock | 4 + .../listing-10-26/Cargo.toml | 7 + .../listing-10-26/src/main.rs | 29 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 29 + .../src/main.rs | 14 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 27 + .../src/main.rs | 15 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 24 + .../src/main.rs | 14 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 35 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 40 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 50 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 29 + .../src/main.rs | 25 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 13 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/main.rs | 14 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 28 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 22 + .../listing-11-01/Cargo.lock | 4 + .../listing-11-01/Cargo.toml | 7 + .../listing-11-01/output.txt | 16 + .../listing-11-01/src/lib.rs | 11 + .../listing-11-03/Cargo.lock | 4 + .../listing-11-03/Cargo.toml | 7 + .../listing-11-03/output.txt | 22 + .../listing-11-03/src/lib.rs | 16 + .../listing-11-05/Cargo.lock | 4 + .../listing-11-05/Cargo.toml | 7 + .../listing-11-05/src/lib.rs | 15 + .../listing-11-06/Cargo.lock | 4 + .../listing-11-06/Cargo.toml | 7 + .../listing-11-06/output.txt | 16 + .../listing-11-06/src/lib.rs | 28 + .../listing-11-07/Cargo.lock | 4 + .../listing-11-07/Cargo.toml | 7 + .../listing-11-07/output.txt | 16 + .../listing-11-07/src/lib.rs | 17 + .../listing-11-08/Cargo.lock | 4 + .../listing-11-08/Cargo.toml | 7 + .../listing-11-08/output.txt | 16 + .../listing-11-08/src/lib.rs | 30 ++ .../listing-11-09/Cargo.lock | 4 + .../listing-11-09/Cargo.toml | 7 + .../listing-11-09/src/lib.rs | 35 ++ .../listing-11-10/Cargo.lock | 4 + .../listing-11-10/Cargo.toml | 7 + .../listing-11-10/output.txt | 25 + .../listing-11-10/src/lib.rs | 21 + .../listing-11-11/Cargo.lock | 4 + .../listing-11-11/Cargo.toml | 7 + .../listing-11-11/output.txt | 18 + .../listing-11-11/src/lib.rs | 23 + .../listing-11-12/Cargo.lock | 4 + .../listing-11-12/Cargo.toml | 7 + .../listing-11-12/src/lib.rs | 21 + .../listing-11-13/Cargo.lock | 4 + .../listing-11-13/Cargo.toml | 7 + .../listing-11-13/output.txt | 23 + .../listing-11-13/src/lib.rs | 17 + .../listing-11-13/tests/integration_test.rs | 6 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../src/lib.rs | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/lib.rs | 39 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 22 + .../src/lib.rs | 37 ++ .../no-listing-04-bug-in-add-two/Cargo.lock | 4 + .../no-listing-04-bug-in-add-two/Cargo.toml | 7 + .../no-listing-04-bug-in-add-two/output.txt | 23 + .../no-listing-04-bug-in-add-two/src/lib.rs | 17 + .../no-listing-05-greeter/Cargo.lock | 4 + .../no-listing-05-greeter/Cargo.toml | 7 + .../no-listing-05-greeter/src/lib.rs | 18 + .../no-listing-06-greeter-with-bug/Cargo.lock | 4 + .../no-listing-06-greeter-with-bug/Cargo.toml | 7 + .../no-listing-06-greeter-with-bug/output.txt | 21 + .../no-listing-06-greeter-with-bug/src/lib.rs | 18 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 21 + .../src/lib.rs | 19 + .../no-listing-08-guess-with-bug/Cargo.lock | 4 + .../no-listing-08-guess-with-bug/Cargo.toml | 7 + .../no-listing-08-guess-with-bug/output.txt | 16 + .../no-listing-08-guess-with-bug/src/lib.rs | 31 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 21 + .../src/lib.rs | 32 ++ .../no-listing-10-result-in-tests/Cargo.lock | 4 + .../no-listing-10-result-in-tests/Cargo.toml | 7 + .../no-listing-10-result-in-tests/src/lib.rs | 11 + .../no-listing-11-ignore-a-test/Cargo.lock | 4 + .../no-listing-11-ignore-a-test/Cargo.toml | 7 + .../no-listing-11-ignore-a-test/output.txt | 17 + .../no-listing-11-ignore-a-test/src/lib.rs | 14 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 29 + .../src/lib.rs | 17 + .../tests/common.rs | 3 + .../tests/integration_test.rs | 6 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 17 + .../tests/common/mod.rs | 3 + .../tests/integration_test.rs | 9 + .../output-only-01-show-output/Cargo.lock | 4 + .../output-only-01-show-output/Cargo.toml | 7 + .../output-only-01-show-output/output.txt | 6 + .../output-only-01-show-output/src/lib.rs | 21 + .../output-only-02-single-test/Cargo.lock | 4 + .../output-only-02-single-test/Cargo.toml | 7 + .../output-only-02-single-test/output.txt | 10 + .../output-only-02-single-test/src/lib.rs | 23 + .../output-only-03-multiple-tests/Cargo.lock | 4 + .../output-only-03-multiple-tests/Cargo.toml | 7 + .../output-only-03-multiple-tests/output.txt | 11 + .../output-only-03-multiple-tests/src/lib.rs | 23 + .../output-only-04-running-ignored/Cargo.lock | 4 + .../output-only-04-running-ignored/Cargo.toml | 7 + .../output-only-04-running-ignored/output.txt | 16 + .../output-only-04-running-ignored/src/lib.rs | 14 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 10 + .../src/lib.rs | 17 + .../tests/integration_test.rs | 6 + .../listing-12-01/Cargo.lock | 4 + .../listing-12-01/Cargo.toml | 7 + .../listing-12-01/output.txt | 5 + .../listing-12-01/src/main.rs | 6 + .../listing-12-02/Cargo.lock | 4 + .../listing-12-02/Cargo.toml | 7 + .../listing-12-02/output.txt | 6 + .../listing-12-02/src/main.rs | 11 + .../listing-12-03/Cargo.lock | 4 + .../listing-12-03/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-03/poem.txt | 9 + .../listing-12-03/src/main.rs | 11 + .../listing-12-04/Cargo.lock | 4 + .../listing-12-04/Cargo.toml | 7 + .../listing-12-04/output.txt | 17 + .../ch12-an-io-project/listing-12-04/poem.txt | 9 + .../listing-12-04/src/main.rs | 22 + .../listing-12-05/Cargo.lock | 4 + .../listing-12-05/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-05/poem.txt | 9 + .../listing-12-05/src/main.rs | 29 + .../listing-12-06/Cargo.lock | 4 + .../listing-12-06/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-06/poem.txt | 9 + .../listing-12-06/src/main.rs | 34 ++ .../listing-12-07/Cargo.lock | 4 + .../listing-12-07/Cargo.toml | 7 + .../listing-12-07/output.txt | 6 + .../ch12-an-io-project/listing-12-07/poem.txt | 9 + .../listing-12-07/src/main.rs | 40 ++ .../listing-12-08/Cargo.lock | 4 + .../listing-12-08/Cargo.toml | 7 + .../listing-12-08/output.txt | 6 + .../ch12-an-io-project/listing-12-08/poem.txt | 9 + .../listing-12-08/src/main.rs | 38 ++ .../listing-12-09/Cargo.lock | 4 + .../listing-12-09/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-09/poem.txt | 9 + .../listing-12-09/src/main.rs | 36 ++ .../listing-12-10/Cargo.lock | 4 + .../listing-12-10/Cargo.toml | 7 + .../listing-12-10/output.txt | 5 + .../ch12-an-io-project/listing-12-10/poem.txt | 9 + .../listing-12-10/src/main.rs | 42 ++ .../listing-12-11/Cargo.lock | 4 + .../listing-12-11/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-11/poem.txt | 9 + .../listing-12-11/src/main.rs | 50 ++ .../listing-12-12/Cargo.lock | 4 + .../listing-12-12/Cargo.toml | 7 + .../listing-12-12/output.txt | 26 + .../ch12-an-io-project/listing-12-12/poem.txt | 9 + .../listing-12-12/src/main.rs | 51 ++ .../listing-12-13/Cargo.lock | 4 + .../listing-12-13/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-13/poem.txt | 9 + .../listing-12-13/src/lib.rs | 36 ++ .../listing-12-13/src/main.rs | 20 + .../listing-12-14/Cargo.lock | 4 + .../listing-12-14/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-14/poem.txt | 9 + .../listing-12-14/src/lib.rs | 28 + .../listing-12-14/src/main.rs | 30 ++ .../listing-12-15/Cargo.lock | 4 + .../listing-12-15/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-15/poem.txt | 9 + .../listing-12-15/src/lib.rs | 49 ++ .../listing-12-15/src/main.rs | 19 + .../listing-12-16/Cargo.lock | 4 + .../listing-12-16/Cargo.toml | 7 + .../listing-12-16/output.txt | 23 + .../ch12-an-io-project/listing-12-16/poem.txt | 9 + .../listing-12-16/src/lib.rs | 53 ++ .../listing-12-16/src/main.rs | 19 + .../listing-12-17/Cargo.lock | 4 + .../listing-12-17/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-17/poem.txt | 9 + .../listing-12-17/src/lib.rs | 53 ++ .../listing-12-17/src/main.rs | 19 + .../listing-12-18/Cargo.lock | 4 + .../listing-12-18/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-18/poem.txt | 9 + .../listing-12-18/src/lib.rs | 55 ++ .../listing-12-18/src/main.rs | 19 + .../listing-12-19/Cargo.lock | 4 + .../listing-12-19/Cargo.toml | 7 + .../listing-12-19/output.txt | 22 + .../ch12-an-io-project/listing-12-19/poem.txt | 9 + .../listing-12-19/src/lib.rs | 61 +++ .../listing-12-19/src/main.rs | 19 + .../listing-12-20/Cargo.lock | 4 + .../listing-12-20/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-20/poem.txt | 9 + .../listing-12-20/src/lib.rs | 81 +++ .../listing-12-20/src/main.rs | 19 + .../listing-12-21/Cargo.lock | 4 + .../listing-12-21/Cargo.toml | 7 + .../listing-12-21/output.txt | 23 + .../ch12-an-io-project/listing-12-21/poem.txt | 9 + .../listing-12-21/src/lib.rs | 94 ++++ .../listing-12-21/src/main.rs | 19 + .../listing-12-22/Cargo.lock | 4 + .../listing-12-22/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-22/poem.txt | 9 + .../listing-12-22/src/lib.rs | 103 ++++ .../listing-12-22/src/main.rs | 19 + .../listing-12-23/Cargo.lock | 6 + .../listing-12-23/Cargo.toml | 7 + .../listing-12-23/output.txt | 6 + .../ch12-an-io-project/listing-12-23/poem.txt | 9 + .../listing-12-23/src/lib.rs | 108 ++++ .../listing-12-23/src/main.rs | 19 + .../listing-12-24/Cargo.lock | 4 + .../listing-12-24/Cargo.toml | 7 + .../ch12-an-io-project/listing-12-24/poem.txt | 9 + .../listing-12-24/src/lib.rs | 100 ++++ .../listing-12-24/src/main.rs | 21 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../poem.txt | 9 + .../src/main.rs | 54 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 5 + .../poem.txt | 9 + .../src/lib.rs | 63 +++ .../src/main.rs | 19 + .../output-only-01-with-args/Cargo.lock | 4 + .../output-only-01-with-args/Cargo.toml | 7 + .../output-only-01-with-args/output.txt | 5 + .../output-only-01-with-args/src/main.rs | 6 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../output-only-02-missing-lifetimes/poem.txt | 9 + .../src/lib.rs | 53 ++ .../src/main.rs | 19 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 7 + .../output-only-03-multiple-matches/poem.txt | 9 + .../src/lib.rs | 63 +++ .../src/main.rs | 19 + .../output-only-04-no-matches/Cargo.lock | 4 + .../output-only-04-no-matches/Cargo.toml | 7 + .../output-only-04-no-matches/output.txt | 4 + .../output-only-04-no-matches/poem.txt | 9 + .../output-only-04-no-matches/src/lib.rs | 63 +++ .../output-only-04-no-matches/src/main.rs | 19 + .../listing-12-23-reproduced/Cargo.lock | 4 + .../listing-12-23-reproduced/Cargo.toml | 7 + .../listing-12-23-reproduced/poem.txt | 9 + .../listing-12-23-reproduced/src/lib.rs | 104 ++++ .../listing-12-23-reproduced/src/main.rs | 19 + .../listing-12-24-reproduced/Cargo.lock | 4 + .../listing-12-24-reproduced/Cargo.toml | 7 + .../listing-12-24-reproduced/poem.txt | 9 + .../listing-12-24-reproduced/src/lib.rs | 100 ++++ .../listing-12-24-reproduced/src/main.rs | 25 + .../listing-13-01/Cargo.toml | 7 + .../listing-13-01/src/main.rs | 12 + .../listing-13-02/Cargo.lock | 4 + .../listing-13-02/Cargo.toml | 7 + .../listing-13-02/src/main.rs | 22 + .../listing-13-03/Cargo.lock | 4 + .../listing-13-03/Cargo.toml | 7 + .../listing-13-03/src/main.rs | 42 ++ .../listing-13-04/Cargo.lock | 4 + .../listing-13-04/Cargo.toml | 7 + .../listing-13-04/src/main.rs | 45 ++ .../listing-13-05/Cargo.lock | 4 + .../listing-13-05/Cargo.toml | 7 + .../listing-13-05/src/main.rs | 42 ++ .../listing-13-06/Cargo.lock | 4 + .../listing-13-06/Cargo.toml | 7 + .../listing-13-06/src/main.rs | 42 ++ .../listing-13-07/Cargo.lock | 4 + .../listing-13-07/Cargo.toml | 7 + .../listing-13-07/src/main.rs | 42 ++ .../listing-13-08/Cargo.lock | 4 + .../listing-13-08/Cargo.toml | 7 + .../listing-13-08/output.txt | 20 + .../listing-13-08/src/main.rs | 8 + .../listing-13-09/Cargo.lock | 4 + .../listing-13-09/Cargo.toml | 7 + .../listing-13-09/src/main.rs | 10 + .../listing-13-10/Cargo.lock | 4 + .../listing-13-10/Cargo.toml | 7 + .../listing-13-10/src/main.rs | 32 ++ .../listing-13-11/Cargo.lock | 4 + .../listing-13-11/Cargo.toml | 7 + .../listing-13-11/src/main.rs | 71 +++ .../listing-13-12/Cargo.lock | 4 + .../listing-13-12/Cargo.toml | 7 + .../listing-13-12/src/main.rs | 9 + .../listing-13-13/Cargo.lock | 4 + .../listing-13-13/Cargo.toml | 7 + .../listing-13-13/src/main.rs | 7 + .../listing-13-14/Cargo.lock | 4 + .../listing-13-14/Cargo.toml | 7 + .../listing-13-14/src/main.rs | 11 + .../listing-13-15/Cargo.lock | 4 + .../listing-13-15/Cargo.toml | 7 + .../listing-13-15/src/lib.rs | 18 + .../listing-13-16/Cargo.lock | 4 + .../listing-13-16/Cargo.toml | 7 + .../listing-13-16/src/lib.rs | 17 + .../listing-13-17/Cargo.lock | 4 + .../listing-13-17/Cargo.toml | 7 + .../listing-13-17/output.txt | 13 + .../listing-13-17/src/main.rs | 7 + .../listing-13-18/Cargo.lock | 4 + .../listing-13-18/Cargo.toml | 7 + .../listing-13-18/src/main.rs | 9 + .../listing-13-19/Cargo.lock | 4 + .../listing-13-19/Cargo.toml | 7 + .../listing-13-19/src/lib.rs | 37 ++ .../listing-13-20/Cargo.lock | 4 + .../listing-13-20/Cargo.toml | 7 + .../listing-13-20/src/lib.rs | 11 + .../listing-13-21/Cargo.lock | 4 + .../listing-13-21/Cargo.toml | 7 + .../listing-13-21/src/lib.rs | 27 + .../listing-13-22/Cargo.lock | 4 + .../listing-13-22/Cargo.toml | 7 + .../listing-13-22/src/lib.rs | 44 ++ .../listing-13-23/Cargo.lock | 4 + .../listing-13-23/Cargo.toml | 7 + .../listing-13-23/src/lib.rs | 53 ++ .../listing-13-25/Cargo.lock | 4 + .../listing-13-25/Cargo.toml | 7 + .../listing-13-25/poem.txt | 9 + .../listing-13-25/src/lib.rs | 100 ++++ .../listing-13-25/src/main.rs | 23 + .../listing-13-26/Cargo.lock | 4 + .../listing-13-26/Cargo.toml | 7 + .../listing-13-26/poem.txt | 9 + .../listing-13-26/src/lib.rs | 103 ++++ .../listing-13-26/src/main.rs | 17 + .../listing-13-27/Cargo.lock | 4 + .../listing-13-27/Cargo.toml | 7 + .../listing-13-27/poem.txt | 9 + .../listing-13-27/src/lib.rs | 109 ++++ .../listing-13-27/src/main.rs | 17 + .../listing-13-29/Cargo.lock | 4 + .../listing-13-29/Cargo.toml | 7 + .../listing-13-29/poem.txt | 9 + .../listing-13-29/src/lib.rs | 101 ++++ .../listing-13-29/src/main.rs | 17 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 23 + .../src/lib.rs | 45 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../src/main.rs | 9 + .../no-listing-03-move-closures/Cargo.lock | 4 + .../no-listing-03-move-closures/Cargo.toml | 7 + .../no-listing-03-move-closures/output.txt | 22 + .../no-listing-03-move-closures/src/main.rs | 11 + .../listing-14-01/Cargo.lock | 6 + .../listing-14-01/Cargo.toml | 7 + .../listing-14-01/src/lib.rs | 13 + .../listing-14-02/Cargo.lock | 4 + .../listing-14-02/Cargo.toml | 7 + .../listing-14-02/src/lib.rs | 21 + .../listing-14-03/Cargo.lock | 4 + .../listing-14-03/Cargo.toml | 7 + .../listing-14-03/src/lib.rs | 36 ++ .../listing-14-04/Cargo.lock | 4 + .../listing-14-04/Cargo.toml | 7 + .../listing-14-04/src/lib.rs | 29 + .../listing-14-04/src/main.rs | 8 + .../listing-14-05/Cargo.lock | 4 + .../listing-14-05/Cargo.toml | 7 + .../listing-14-05/src/lib.rs | 41 ++ .../listing-14-06/Cargo.lock | 4 + .../listing-14-06/Cargo.toml | 7 + .../listing-14-06/src/lib.rs | 33 ++ .../listing-14-06/src/main.rs | 13 + .../listing-14-07/add/Cargo.lock | 13 + .../listing-14-07/add/Cargo.toml | 6 + .../listing-14-07/add/add-one/Cargo.toml | 7 + .../listing-14-07/add/add-one/src/lib.rs | 3 + .../listing-14-07/add/adder/Cargo.toml | 9 + .../listing-14-07/add/adder/src/main.rs | 6 + .../add/Cargo.lock | 4 + .../add/Cargo.toml | 5 + .../add/adder/Cargo.toml | 7 + .../add/adder/src/main.rs | 3 + .../add/Cargo.lock | 8 + .../add/Cargo.toml | 6 + .../add/add-one/Cargo.toml | 7 + .../add/add-one/src/lib.rs | 3 + .../add/adder/Cargo.toml | 9 + .../add/adder/src/main.rs | 3 + .../add/Cargo.lock | 94 ++++ .../add/Cargo.toml | 6 + .../add/add-one/Cargo.toml | 8 + .../add/add-one/src/lib.rs | 5 + .../add/adder/Cargo.toml | 9 + .../add/adder/src/main.rs | 6 + .../add/Cargo.lock | 13 + .../add/Cargo.toml | 6 + .../add/add-one/Cargo.toml | 7 + .../add/add-one/src/lib.rs | 13 + .../add/adder/Cargo.toml | 9 + .../add/adder/src/main.rs | 6 + .../output-only-01-adder-crate/add/.gitignore | 1 + .../output-only-01-adder-crate/add/Cargo.toml | 5 + .../output-only-02-add-one/add/.gitignore | 1 + .../output-only-02-add-one/add/Cargo.lock | 8 + .../output-only-02-add-one/add/Cargo.toml | 6 + .../add/add-one/Cargo.toml | 9 + .../add/add-one/src/lib.rs | 7 + .../add/adder/Cargo.toml | 9 + .../add/adder/src/main.rs | 3 + .../output-only-03-use-rand/add/Cargo.lock | 94 ++++ .../output-only-03-use-rand/add/Cargo.toml | 6 + .../add/add-one/Cargo.toml | 8 + .../add/add-one/src/lib.rs | 5 + .../add/adder/Cargo.toml | 9 + .../add/adder/src/main.rs | 7 + .../listing-15-01/Cargo.lock | 4 + .../listing-15-01/Cargo.toml | 7 + .../listing-15-01/src/main.rs | 4 + .../listing-15-02/Cargo.lock | 4 + .../listing-15-02/Cargo.toml | 7 + .../listing-15-02/src/main.rs | 8 + .../listing-15-03/Cargo.lock | 4 + .../listing-15-03/Cargo.toml | 7 + .../listing-15-03/output.txt | 28 + .../listing-15-03/src/main.rs | 12 + .../listing-15-05/Cargo.lock | 4 + .../listing-15-05/Cargo.toml | 7 + .../listing-15-05/src/main.rs | 13 + .../listing-15-06/Cargo.lock | 4 + .../listing-15-06/Cargo.toml | 7 + .../listing-15-06/src/main.rs | 7 + .../listing-15-07/Cargo.lock | 4 + .../listing-15-07/Cargo.toml | 7 + .../listing-15-07/src/main.rs | 7 + .../listing-15-08/Cargo.lock | 4 + .../listing-15-08/Cargo.toml | 7 + .../listing-15-08/src/main.rs | 12 + .../listing-15-09/Cargo.lock | 4 + .../listing-15-09/Cargo.toml | 7 + .../listing-15-09/output.txt | 14 + .../listing-15-09/src/main.rs | 17 + .../listing-15-10/Cargo.lock | 4 + .../listing-15-10/Cargo.toml | 7 + .../listing-15-10/src/main.rs | 27 + .../listing-15-11/Cargo.lock | 4 + .../listing-15-11/Cargo.toml | 7 + .../listing-15-11/src/main.rs | 8 + .../listing-15-12/Cargo.lock | 4 + .../listing-15-12/Cargo.toml | 7 + .../listing-15-12/src/main.rs | 28 + .../listing-15-13/Cargo.lock | 4 + .../listing-15-13/Cargo.toml | 7 + .../listing-15-13/src/main.rs | 28 + .../listing-15-14/Cargo.lock | 4 + .../listing-15-14/Cargo.toml | 7 + .../listing-15-14/output.txt | 7 + .../listing-15-14/src/main.rs | 15 + .../listing-15-15/Cargo.lock | 4 + .../listing-15-15/Cargo.toml | 7 + .../listing-15-15/output.txt | 14 + .../listing-15-15/src/main.rs | 18 + .../listing-15-16/Cargo.lock | 4 + .../listing-15-16/Cargo.toml | 7 + .../listing-15-16/output.txt | 7 + .../listing-15-16/src/main.rs | 18 + .../listing-15-17/Cargo.lock | 4 + .../listing-15-17/Cargo.toml | 7 + .../listing-15-17/output.txt | 19 + .../listing-15-17/src/main.rs | 14 + .../listing-15-18/Cargo.lock | 4 + .../listing-15-18/Cargo.toml | 7 + .../listing-15-18/src/main.rs | 13 + .../listing-15-19/Cargo.lock | 4 + .../listing-15-19/Cargo.toml | 7 + .../listing-15-19/output.txt | 8 + .../listing-15-19/src/main.rs | 21 + .../listing-15-20/Cargo.lock | 4 + .../listing-15-20/Cargo.toml | 7 + .../listing-15-20/src/lib.rs | 34 ++ .../listing-15-21/Cargo.lock | 4 + .../listing-15-21/Cargo.toml | 7 + .../listing-15-21/output.txt | 16 + .../listing-15-21/src/lib.rs | 67 +++ .../listing-15-22/Cargo.lock | 4 + .../listing-15-22/Cargo.toml | 7 + .../listing-15-22/src/lib.rs | 74 +++ .../listing-15-23/Cargo.lock | 4 + .../listing-15-23/Cargo.toml | 7 + .../listing-15-23/output.txt | 21 + .../listing-15-23/src/lib.rs | 72 +++ .../listing-15-24/Cargo.lock | 4 + .../listing-15-24/Cargo.toml | 7 + .../listing-15-24/output.txt | 7 + .../listing-15-24/src/main.rs | 24 + .../listing-15-25/Cargo.lock | 4 + .../listing-15-25/Cargo.toml | 7 + .../listing-15-25/src/main.rs | 20 + .../listing-15-26/Cargo.lock | 4 + .../listing-15-26/Cargo.toml | 7 + .../listing-15-26/output.txt | 11 + .../listing-15-26/src/main.rs | 44 ++ .../listing-15-27/Cargo.lock | 4 + .../listing-15-27/Cargo.toml | 7 + .../listing-15-27/src/main.rs | 24 + .../listing-15-28/Cargo.lock | 4 + .../listing-15-28/Cargo.toml | 7 + .../listing-15-28/src/main.rs | 33 ++ .../listing-15-29/Cargo.lock | 4 + .../listing-15-29/Cargo.toml | 7 + .../listing-15-29/src/main.rs | 54 ++ .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../src/main.rs | 4 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/main.rs | 7 + .../listing-16-01/Cargo.lock | 4 + .../listing-16-01/Cargo.toml | 7 + .../listing-16-01/src/main.rs | 16 + .../listing-16-02/Cargo.lock | 4 + .../listing-16-02/Cargo.toml | 7 + .../listing-16-02/src/main.rs | 18 + .../listing-16-03/Cargo.lock | 4 + .../listing-16-03/Cargo.toml | 7 + .../listing-16-03/output.txt | 29 + .../listing-16-03/src/main.rs | 11 + .../listing-16-04/Cargo.lock | 4 + .../listing-16-04/Cargo.toml | 7 + .../listing-16-04/src/main.rs | 13 + .../listing-16-05/Cargo.lock | 4 + .../listing-16-05/Cargo.toml | 7 + .../listing-16-05/src/main.rs | 11 + .../listing-16-06/Cargo.lock | 4 + .../listing-16-06/Cargo.toml | 7 + .../listing-16-06/src/main.rs | 5 + .../listing-16-07/Cargo.lock | 4 + .../listing-16-07/Cargo.toml | 7 + .../listing-16-07/src/main.rs | 11 + .../listing-16-08/Cargo.lock | 4 + .../listing-16-08/Cargo.toml | 7 + .../listing-16-08/src/main.rs | 14 + .../listing-16-09/Cargo.lock | 4 + .../listing-16-09/Cargo.toml | 7 + .../listing-16-09/output.txt | 18 + .../listing-16-09/src/main.rs | 15 + .../listing-16-10/Cargo.lock | 4 + .../listing-16-10/Cargo.toml | 7 + .../listing-16-10/src/main.rs | 25 + .../listing-16-11/Cargo.lock | 4 + .../listing-16-11/Cargo.toml | 7 + .../listing-16-11/src/main.rs | 46 ++ .../listing-16-12/Cargo.lock | 4 + .../listing-16-12/Cargo.toml | 7 + .../listing-16-12/src/main.rs | 12 + .../listing-16-13/Cargo.lock | 4 + .../listing-16-13/Cargo.toml | 7 + .../listing-16-13/output.txt | 19 + .../listing-16-13/src/main.rs | 22 + .../listing-16-14/Cargo.lock | 4 + .../listing-16-14/Cargo.toml | 7 + .../listing-16-14/output.txt | 18 + .../listing-16-14/src/main.rs | 24 + .../listing-16-15/Cargo.lock | 4 + .../listing-16-15/Cargo.toml | 7 + .../listing-16-15/src/main.rs | 23 + .../no-listing-01-join-too-early/Cargo.lock | 4 + .../no-listing-01-join-too-early/Cargo.toml | 7 + .../no-listing-01-join-too-early/src/main.rs | 18 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 27 + .../output-only-01-move-drop/Cargo.lock | 4 + .../output-only-01-move-drop/Cargo.toml | 7 + .../output-only-01-move-drop/output.txt | 22 + .../output-only-01-move-drop/src/main.rs | 13 + listings/ch17-oop/listing-17-01/Cargo.lock | 4 + listings/ch17-oop/listing-17-01/Cargo.toml | 7 + listings/ch17-oop/listing-17-01/src/lib.rs | 4 + listings/ch17-oop/listing-17-02/Cargo.lock | 4 + listings/ch17-oop/listing-17-02/Cargo.toml | 7 + listings/ch17-oop/listing-17-02/src/lib.rs | 33 ++ listings/ch17-oop/listing-17-03/Cargo.toml | 7 + listings/ch17-oop/listing-17-03/src/lib.rs | 3 + listings/ch17-oop/listing-17-04/Cargo.lock | 4 + listings/ch17-oop/listing-17-04/Cargo.toml | 7 + listings/ch17-oop/listing-17-04/src/lib.rs | 9 + listings/ch17-oop/listing-17-05/Cargo.lock | 4 + listings/ch17-oop/listing-17-05/Cargo.toml | 7 + listings/ch17-oop/listing-17-05/src/lib.rs | 17 + listings/ch17-oop/listing-17-06/Cargo.lock | 4 + listings/ch17-oop/listing-17-06/Cargo.toml | 7 + listings/ch17-oop/listing-17-06/src/lib.rs | 18 + listings/ch17-oop/listing-17-07/Cargo.lock | 4 + listings/ch17-oop/listing-17-07/Cargo.toml | 7 + listings/ch17-oop/listing-17-07/src/lib.rs | 31 ++ listings/ch17-oop/listing-17-08/Cargo.lock | 4 + listings/ch17-oop/listing-17-08/Cargo.toml | 7 + listings/ch17-oop/listing-17-08/src/lib.rs | 27 + listings/ch17-oop/listing-17-08/src/main.rs | 17 + listings/ch17-oop/listing-17-09/Cargo.lock | 4 + listings/ch17-oop/listing-17-09/Cargo.toml | 7 + listings/ch17-oop/listing-17-09/src/lib.rs | 27 + listings/ch17-oop/listing-17-09/src/main.rs | 40 ++ listings/ch17-oop/listing-17-10/Cargo.lock | 4 + listings/ch17-oop/listing-17-10/Cargo.toml | 7 + listings/ch17-oop/listing-17-10/output.txt | 16 + listings/ch17-oop/listing-17-10/src/lib.rs | 27 + listings/ch17-oop/listing-17-10/src/main.rs | 11 + listings/ch17-oop/listing-17-11/Cargo.lock | 4 + listings/ch17-oop/listing-17-11/Cargo.toml | 7 + listings/ch17-oop/listing-17-11/src/main.rs | 20 + listings/ch17-oop/listing-17-12/Cargo.lock | 4 + listings/ch17-oop/listing-17-12/Cargo.toml | 7 + listings/ch17-oop/listing-17-12/src/lib.rs | 19 + listings/ch17-oop/listing-17-12/src/main.rs | 14 + listings/ch17-oop/listing-17-13/Cargo.lock | 4 + listings/ch17-oop/listing-17-13/Cargo.toml | 7 + listings/ch17-oop/listing-17-13/src/lib.rs | 30 ++ listings/ch17-oop/listing-17-13/src/main.rs | 14 + listings/ch17-oop/listing-17-14/Cargo.lock | 4 + listings/ch17-oop/listing-17-14/Cargo.toml | 7 + listings/ch17-oop/listing-17-14/src/lib.rs | 34 ++ listings/ch17-oop/listing-17-14/src/main.rs | 14 + listings/ch17-oop/listing-17-15/Cargo.lock | 4 + listings/ch17-oop/listing-17-15/Cargo.toml | 7 + listings/ch17-oop/listing-17-15/src/lib.rs | 54 ++ listings/ch17-oop/listing-17-15/src/main.rs | 14 + listings/ch17-oop/listing-17-16/Cargo.lock | 4 + listings/ch17-oop/listing-17-16/Cargo.toml | 7 + listings/ch17-oop/listing-17-16/src/lib.rs | 85 +++ listings/ch17-oop/listing-17-16/src/main.rs | 14 + listings/ch17-oop/listing-17-17/Cargo.lock | 4 + listings/ch17-oop/listing-17-17/Cargo.toml | 7 + listings/ch17-oop/listing-17-17/src/lib.rs | 82 +++ listings/ch17-oop/listing-17-17/src/main.rs | 14 + listings/ch17-oop/listing-17-18/Cargo.lock | 4 + listings/ch17-oop/listing-17-18/Cargo.toml | 7 + listings/ch17-oop/listing-17-18/src/lib.rs | 94 ++++ listings/ch17-oop/listing-17-18/src/main.rs | 14 + listings/ch17-oop/listing-17-19/Cargo.lock | 4 + listings/ch17-oop/listing-17-19/Cargo.toml | 7 + listings/ch17-oop/listing-17-19/src/lib.rs | 25 + listings/ch17-oop/listing-17-20/Cargo.lock | 4 + listings/ch17-oop/listing-17-20/Cargo.toml | 7 + listings/ch17-oop/listing-17-20/src/lib.rs | 48 ++ listings/ch17-oop/listing-17-21/Cargo.lock | 4 + listings/ch17-oop/listing-17-21/Cargo.toml | 7 + listings/ch17-oop/listing-17-21/src/lib.rs | 43 ++ listings/ch17-oop/listing-17-21/src/main.rs | 13 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 16 + .../src/lib.rs | 3 + .../listing-18-01/Cargo.lock | 4 + .../listing-18-01/Cargo.toml | 7 + .../listing-18-01/src/main.rs | 19 + .../listing-18-02/Cargo.lock | 4 + .../listing-18-02/Cargo.toml | 7 + .../listing-18-02/src/main.rs | 13 + .../listing-18-03/Cargo.lock | 4 + .../listing-18-03/Cargo.toml | 7 + .../listing-18-03/output.txt | 7 + .../listing-18-03/src/main.rs | 9 + .../listing-18-04/Cargo.lock | 4 + .../listing-18-04/Cargo.toml | 7 + .../listing-18-04/src/main.rs | 5 + .../listing-18-05/Cargo.lock | 4 + .../listing-18-05/Cargo.toml | 7 + .../listing-18-05/output.txt | 17 + .../listing-18-05/src/main.rs | 5 + .../listing-18-06/Cargo.lock | 4 + .../listing-18-06/Cargo.toml | 7 + .../listing-18-06/src/main.rs | 7 + .../listing-18-07/Cargo.lock | 4 + .../listing-18-07/Cargo.toml | 7 + .../listing-18-07/src/main.rs | 8 + .../listing-18-08/Cargo.lock | 4 + .../listing-18-08/Cargo.toml | 7 + .../listing-18-08/output.txt | 14 + .../listing-18-08/src/main.rs | 6 + .../listing-18-09/Cargo.lock | 4 + .../listing-18-09/Cargo.toml | 7 + .../listing-18-09/src/main.rs | 8 + .../listing-18-10/Cargo.lock | 4 + .../listing-18-10/Cargo.toml | 7 + .../listing-18-10/output.txt | 15 + .../listing-18-10/src/main.rs | 7 + .../listing-18-11/Cargo.lock | 4 + .../listing-18-11/Cargo.toml | 7 + .../listing-18-11/src/main.rs | 14 + .../listing-18-12/Cargo.lock | 4 + .../listing-18-12/Cargo.toml | 7 + .../listing-18-12/src/main.rs | 12 + .../listing-18-13/Cargo.lock | 4 + .../listing-18-13/Cargo.toml | 7 + .../listing-18-13/src/main.rs | 12 + .../listing-18-14/Cargo.lock | 4 + .../listing-18-14/Cargo.toml | 7 + .../listing-18-14/src/main.rs | 16 + .../listing-18-15/Cargo.lock | 4 + .../listing-18-15/Cargo.toml | 7 + .../listing-18-15/src/main.rs | 32 ++ .../listing-18-16/Cargo.lock | 4 + .../listing-18-16/Cargo.toml | 7 + .../listing-18-16/src/main.rs | 35 ++ .../listing-18-17/Cargo.lock | 4 + .../listing-18-17/Cargo.toml | 7 + .../listing-18-17/src/main.rs | 7 + .../listing-18-18/Cargo.lock | 4 + .../listing-18-18/Cargo.toml | 7 + .../listing-18-18/src/main.rs | 17 + .../listing-18-19/Cargo.lock | 4 + .../listing-18-19/Cargo.toml | 7 + .../listing-18-19/src/main.rs | 11 + .../listing-18-20/Cargo.lock | 4 + .../listing-18-20/Cargo.toml | 7 + .../listing-18-20/src/main.rs | 4 + .../listing-18-21/Cargo.lock | 4 + .../listing-18-21/Cargo.toml | 7 + .../listing-18-21/src/main.rs | 11 + .../listing-18-22/Cargo.lock | 4 + .../listing-18-22/Cargo.toml | 7 + .../listing-18-22/src/main.rs | 11 + .../listing-18-23/Cargo.lock | 4 + .../listing-18-23/Cargo.toml | 7 + .../listing-18-23/src/main.rs | 15 + .../listing-18-24/Cargo.lock | 4 + .../listing-18-24/Cargo.toml | 7 + .../listing-18-24/src/main.rs | 9 + .../listing-18-25/Cargo.lock | 4 + .../listing-18-25/Cargo.toml | 7 + .../listing-18-25/output.txt | 15 + .../listing-18-25/src/main.rs | 9 + .../listing-18-26/Cargo.lock | 4 + .../listing-18-26/Cargo.toml | 7 + .../listing-18-26/src/main.rs | 11 + .../listing-18-27/Cargo.lock | 4 + .../listing-18-27/Cargo.toml | 7 + .../listing-18-27/src/main.rs | 12 + .../listing-18-28/Cargo.lock | 4 + .../listing-18-28/Cargo.toml | 7 + .../listing-18-28/src/main.rs | 11 + .../listing-18-29/Cargo.lock | 4 + .../listing-18-29/Cargo.toml | 7 + .../listing-18-29/src/main.rs | 21 + .../no-listing-01-literals/Cargo.lock | 4 + .../no-listing-01-literals/Cargo.toml | 7 + .../no-listing-01-literals/src/main.rs | 12 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 11 + .../no-listing-03-ranges/Cargo.lock | 4 + .../no-listing-03-ranges/Cargo.toml | 7 + .../no-listing-03-ranges/src/main.rs | 10 + .../no-listing-04-ranges-of-char/Cargo.lock | 4 + .../no-listing-04-ranges-of-char/Cargo.toml | 7 + .../no-listing-04-ranges-of-char/src/main.rs | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 10 + .../listing-13-21-reproduced/Cargo.lock | 4 + .../listing-13-21-reproduced/Cargo.toml | 7 + .../listing-13-21-reproduced/src/lib.rs | 28 + .../listing-19-01/Cargo.lock | 4 + .../listing-19-01/Cargo.toml | 7 + .../listing-19-01/src/main.rs | 8 + .../listing-19-02/Cargo.lock | 4 + .../listing-19-02/Cargo.toml | 7 + .../listing-19-02/src/main.rs | 6 + .../listing-19-03/Cargo.lock | 4 + .../listing-19-03/Cargo.toml | 7 + .../listing-19-03/src/main.rs | 13 + .../listing-19-04/Cargo.lock | 4 + .../listing-19-04/Cargo.toml | 7 + .../listing-19-04/src/main.rs | 12 + .../listing-19-05/Cargo.lock | 4 + .../listing-19-05/Cargo.toml | 7 + .../listing-19-05/output.txt | 23 + .../listing-19-05/src/main.rs | 15 + .../listing-19-06/Cargo.lock | 4 + .../listing-19-06/Cargo.toml | 7 + .../listing-19-06/src/main.rs | 20 + .../listing-19-07/Cargo.lock | 4 + .../listing-19-07/Cargo.toml | 7 + .../listing-19-07/src/main.rs | 12 + .../listing-19-08/Cargo.lock | 4 + .../listing-19-08/Cargo.toml | 7 + .../listing-19-08/src/main.rs | 9 + .../listing-19-09/Cargo.lock | 4 + .../listing-19-09/Cargo.toml | 7 + .../listing-19-09/src/main.rs | 5 + .../listing-19-10/Cargo.lock | 4 + .../listing-19-10/Cargo.toml | 7 + .../listing-19-10/src/main.rs | 15 + .../listing-19-11/Cargo.lock | 4 + .../listing-19-11/Cargo.toml | 7 + .../listing-19-11/src/main.rs | 9 + .../listing-19-12/Cargo.lock | 4 + .../listing-19-12/Cargo.toml | 7 + .../listing-19-12/src/lib.rs | 5 + .../listing-19-13/Cargo.lock | 4 + .../listing-19-13/Cargo.toml | 7 + .../listing-19-13/src/lib.rs | 3 + .../listing-19-14/Cargo.lock | 4 + .../listing-19-14/Cargo.toml | 7 + .../listing-19-14/src/main.rs | 23 + .../listing-19-15/Cargo.lock | 4 + .../listing-19-15/Cargo.toml | 7 + .../listing-19-15/src/lib.rs | 12 + .../listing-19-16/Cargo.lock | 4 + .../listing-19-16/Cargo.toml | 7 + .../listing-19-16/src/main.rs | 31 ++ .../listing-19-17/Cargo.lock | 4 + .../listing-19-17/Cargo.toml | 7 + .../listing-19-17/src/main.rs | 34 ++ .../listing-19-18/Cargo.lock | 4 + .../listing-19-18/Cargo.toml | 7 + .../listing-19-18/output.txt | 7 + .../listing-19-18/src/main.rs | 36 ++ .../listing-19-19/Cargo.lock | 4 + .../listing-19-19/Cargo.toml | 7 + .../listing-19-19/output.txt | 5 + .../listing-19-19/src/main.rs | 21 + .../listing-19-20/Cargo.lock | 4 + .../listing-19-20/Cargo.toml | 7 + .../listing-19-20/output.txt | 20 + .../listing-19-20/src/main.rs | 23 + .../listing-19-21/Cargo.lock | 4 + .../listing-19-21/Cargo.toml | 7 + .../listing-19-21/output.txt | 5 + .../listing-19-21/src/main.rs | 23 + .../listing-19-22/Cargo.lock | 4 + .../listing-19-22/Cargo.toml | 7 + .../listing-19-22/src/main.rs | 17 + .../listing-19-23/Cargo.lock | 4 + .../listing-19-23/Cargo.toml | 7 + .../listing-19-23/src/main.rs | 14 + .../listing-19-24/Cargo.lock | 4 + .../listing-19-24/Cargo.toml | 7 + .../listing-19-24/src/main.rs | 16 + .../listing-19-25/Cargo.lock | 4 + .../listing-19-25/Cargo.toml | 7 + .../listing-19-25/src/main.rs | 18 + .../listing-19-27/Cargo.lock | 4 + .../listing-19-27/Cargo.toml | 7 + .../listing-19-27/src/main.rs | 13 + .../listing-19-28/Cargo.lock | 4 + .../listing-19-28/Cargo.toml | 7 + .../listing-19-28/src/lib.rs | 12 + .../listing-19-30/Cargo.lock | 4 + .../listing-19-30/Cargo.toml | 7 + .../listing-19-30/src/main.rs | 9 + .../listing-19-31/hello_macro/Cargo.lock | 4 + .../listing-19-31/hello_macro/Cargo.toml | 7 + .../hello_macro/hello_macro_derive/Cargo.lock | 44 ++ .../hello_macro/hello_macro_derive/Cargo.toml | 12 + .../hello_macro/hello_macro_derive/src/lib.rs | 15 + .../listing-19-31/hello_macro/src/lib.rs | 3 + .../listing-19-31/hello_macro/src/main.rs | 13 + .../listing-19-33/hello_macro/Cargo.lock | 4 + .../listing-19-33/hello_macro/Cargo.toml | 7 + .../hello_macro/hello_macro_derive/Cargo.lock | 44 ++ .../hello_macro/hello_macro_derive/Cargo.toml | 12 + .../hello_macro/hello_macro_derive/src/lib.rs | 29 + .../listing-19-33/hello_macro/src/lib.rs | 3 + .../listing-19-33/hello_macro/src/main.rs | 13 + .../no-listing-01-unsafe-fn/Cargo.lock | 4 + .../no-listing-01-unsafe-fn/Cargo.toml | 7 + .../no-listing-01-unsafe-fn/src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../output.txt | 17 + .../src/main.rs | 27 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 33 ++ .../no-listing-04-kilometers-alias/Cargo.lock | 4 + .../no-listing-04-kilometers-alias/Cargo.toml | 7 + .../src/main.rs | 12 + .../no-listing-05-write-trait/Cargo.lock | 4 + .../no-listing-05-write-trait/Cargo.toml | 7 + .../no-listing-05-write-trait/src/lib.rs | 10 + .../no-listing-06-result-alias/Cargo.lock | 4 + .../no-listing-06-result-alias/Cargo.toml | 7 + .../no-listing-06-result-alias/src/lib.rs | 17 + .../no-listing-07-never-type/Cargo.lock | 4 + .../no-listing-07-never-type/Cargo.toml | 7 + .../no-listing-07-never-type/src/lib.rs | 10 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 9 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 17 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/main.rs | 9 + .../no-listing-11-cant-create-str/Cargo.lock | 4 + .../no-listing-11-cant-create-str/Cargo.toml | 7 + .../no-listing-11-cant-create-str/src/main.rs | 6 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 3 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 3 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 3 + .../no-listing-15-map-closure/Cargo.lock | 4 + .../no-listing-15-map-closure/Cargo.toml | 7 + .../no-listing-15-map-closure/src/main.rs | 9 + .../no-listing-16-map-function/Cargo.lock | 4 + .../no-listing-16-map-function/Cargo.toml | 7 + .../no-listing-16-map-function/src/main.rs | 9 + .../no-listing-17-map-initializer/Cargo.lock | 4 + .../no-listing-17-map-initializer/Cargo.toml | 7 + .../no-listing-17-map-initializer/src/main.rs | 13 + .../no-listing-18-returns-closure/Cargo.lock | 4 + .../no-listing-18-returns-closure/Cargo.toml | 7 + .../no-listing-18-returns-closure/output.txt | 30 ++ .../no-listing-18-returns-closure/src/lib.rs | 3 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../src/lib.rs | 3 + .../hello_macro/Cargo.lock | 4 + .../hello_macro/Cargo.toml | 7 + .../hello_macro/src/lib.rs | 3 + .../pancakes/Cargo.lock | 11 + .../pancakes/Cargo.toml | 8 + .../pancakes/src/main.rs | 13 + .../hello_macro/Cargo.lock | 4 + .../hello_macro/Cargo.toml | 7 + .../hello_macro/hello_macro_derive/Cargo.lock | 44 ++ .../hello_macro/hello_macro_derive/Cargo.toml | 12 + .../hello_macro/hello_macro_derive/src/lib.rs | 27 + .../hello_macro/src/lib.rs | 3 + .../hello_macro/src/main.rs | 13 + .../pancakes/Cargo.lock | 56 ++ .../pancakes/Cargo.toml | 9 + .../pancakes/src/main.rs | 9 + .../output-only-01-missing-unsafe/Cargo.lock | 4 + .../output-only-01-missing-unsafe/Cargo.toml | 7 + .../output-only-01-missing-unsafe/output.txt | 16 + .../output-only-01-missing-unsafe/src/main.rs | 7 + .../ch20-web-server/listing-20-01/Cargo.lock | 4 + .../ch20-web-server/listing-20-01/Cargo.toml | 7 + .../ch20-web-server/listing-20-01/src/main.rs | 11 + .../ch20-web-server/listing-20-02/Cargo.lock | 4 + .../ch20-web-server/listing-20-02/Cargo.toml | 7 + .../ch20-web-server/listing-20-02/src/main.rs | 21 + .../ch20-web-server/listing-20-03/Cargo.lock | 4 + .../ch20-web-server/listing-20-03/Cargo.toml | 7 + .../ch20-web-server/listing-20-03/src/main.rs | 26 + .../ch20-web-server/listing-20-04/Cargo.lock | 4 + .../ch20-web-server/listing-20-04/Cargo.toml | 7 + .../ch20-web-server/listing-20-04/hello.html | 11 + .../ch20-web-server/listing-20-04/src/main.rs | 24 + .../ch20-web-server/listing-20-05/Cargo.lock | 4 + .../ch20-web-server/listing-20-05/Cargo.toml | 7 + .../ch20-web-server/listing-20-05/hello.html | 11 + .../ch20-web-server/listing-20-05/src/main.rs | 32 ++ .../ch20-web-server/listing-20-06/Cargo.lock | 4 + .../ch20-web-server/listing-20-06/Cargo.toml | 7 + .../ch20-web-server/listing-20-06/hello.html | 11 + .../ch20-web-server/listing-20-06/src/main.rs | 36 ++ .../ch20-web-server/listing-20-07/Cargo.lock | 4 + .../ch20-web-server/listing-20-07/Cargo.toml | 7 + .../ch20-web-server/listing-20-07/hello.html | 11 + .../ch20-web-server/listing-20-07/src/main.rs | 42 ++ .../ch20-web-server/listing-20-08/404.html | 11 + .../ch20-web-server/listing-20-08/Cargo.lock | 4 + .../ch20-web-server/listing-20-08/Cargo.toml | 7 + .../ch20-web-server/listing-20-08/hello.html | 11 + .../ch20-web-server/listing-20-08/src/main.rs | 38 ++ .../ch20-web-server/listing-20-09/404.html | 11 + .../ch20-web-server/listing-20-09/Cargo.lock | 4 + .../ch20-web-server/listing-20-09/Cargo.toml | 7 + .../ch20-web-server/listing-20-09/hello.html | 11 + .../ch20-web-server/listing-20-09/src/main.rs | 42 ++ .../ch20-web-server/listing-20-10/404.html | 11 + .../ch20-web-server/listing-20-10/Cargo.lock | 4 + .../ch20-web-server/listing-20-10/Cargo.toml | 7 + .../ch20-web-server/listing-20-10/hello.html | 11 + .../ch20-web-server/listing-20-10/src/main.rs | 53 ++ .../ch20-web-server/listing-20-11/404.html | 11 + .../ch20-web-server/listing-20-11/Cargo.lock | 4 + .../ch20-web-server/listing-20-11/Cargo.toml | 7 + .../ch20-web-server/listing-20-11/hello.html | 11 + .../ch20-web-server/listing-20-11/src/main.rs | 44 ++ .../ch20-web-server/listing-20-12/404.html | 11 + .../ch20-web-server/listing-20-12/Cargo.lock | 4 + .../ch20-web-server/listing-20-12/Cargo.toml | 7 + .../ch20-web-server/listing-20-12/hello.html | 11 + .../ch20-web-server/listing-20-12/output.txt | 14 + .../ch20-web-server/listing-20-12/src/main.rs | 45 ++ .../ch20-web-server/listing-20-13/404.html | 11 + .../ch20-web-server/listing-20-13/Cargo.lock | 4 + .../ch20-web-server/listing-20-13/Cargo.toml | 7 + .../ch20-web-server/listing-20-13/hello.html | 11 + .../listing-20-13/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-13/src/lib.rs | 31 ++ .../ch20-web-server/listing-20-14/404.html | 11 + .../ch20-web-server/listing-20-14/Cargo.lock | 4 + .../ch20-web-server/listing-20-14/Cargo.toml | 7 + .../ch20-web-server/listing-20-14/hello.html | 11 + .../listing-20-14/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-14/src/lib.rs | 44 ++ .../ch20-web-server/listing-20-15/404.html | 11 + .../ch20-web-server/listing-20-15/Cargo.lock | 4 + .../ch20-web-server/listing-20-15/Cargo.toml | 7 + .../ch20-web-server/listing-20-15/hello.html | 11 + .../listing-20-15/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-15/src/lib.rs | 61 +++ .../ch20-web-server/listing-20-16/404.html | 11 + .../ch20-web-server/listing-20-16/Cargo.lock | 4 + .../ch20-web-server/listing-20-16/Cargo.toml | 7 + .../ch20-web-server/listing-20-16/hello.html | 11 + .../listing-20-16/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-16/src/lib.rs | 69 +++ .../ch20-web-server/listing-20-17/404.html | 11 + .../ch20-web-server/listing-20-17/Cargo.lock | 4 + .../ch20-web-server/listing-20-17/Cargo.toml | 7 + .../ch20-web-server/listing-20-17/hello.html | 11 + .../ch20-web-server/listing-20-17/output.txt | 17 + .../listing-20-17/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-17/src/lib.rs | 73 +++ .../ch20-web-server/listing-20-18/404.html | 11 + .../ch20-web-server/listing-20-18/Cargo.lock | 4 + .../ch20-web-server/listing-20-18/Cargo.toml | 7 + .../ch20-web-server/listing-20-18/hello.html | 11 + .../listing-20-18/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-18/src/lib.rs | 85 +++ .../ch20-web-server/listing-20-19/404.html | 11 + .../ch20-web-server/listing-20-19/Cargo.lock | 4 + .../ch20-web-server/listing-20-19/Cargo.toml | 7 + .../ch20-web-server/listing-20-19/hello.html | 11 + .../listing-20-19/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-19/src/lib.rs | 77 +++ .../ch20-web-server/listing-20-20/404.html | 11 + .../ch20-web-server/listing-20-20/Cargo.lock | 6 + .../ch20-web-server/listing-20-20/Cargo.toml | 7 + .../ch20-web-server/listing-20-20/hello.html | 11 + .../listing-20-20/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-20/src/lib.rs | 76 +++ .../ch20-web-server/listing-20-21/404.html | 11 + .../ch20-web-server/listing-20-21/Cargo.lock | 4 + .../ch20-web-server/listing-20-21/Cargo.toml | 7 + .../ch20-web-server/listing-20-21/hello.html | 11 + .../listing-20-21/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-21/src/lib.rs | 73 +++ .../ch20-web-server/listing-20-22/404.html | 11 + .../ch20-web-server/listing-20-22/Cargo.lock | 4 + .../ch20-web-server/listing-20-22/Cargo.toml | 7 + .../ch20-web-server/listing-20-22/hello.html | 11 + .../ch20-web-server/listing-20-22/output.txt | 14 + .../listing-20-22/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-22/src/lib.rs | 84 +++ .../ch20-web-server/listing-20-23/404.html | 11 + .../ch20-web-server/listing-20-23/Cargo.lock | 4 + .../ch20-web-server/listing-20-23/Cargo.toml | 7 + .../ch20-web-server/listing-20-23/hello.html | 11 + .../listing-20-23/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-23/src/lib.rs | 114 ++++ .../ch20-web-server/listing-20-24/404.html | 11 + .../ch20-web-server/listing-20-24/Cargo.lock | 6 + .../ch20-web-server/listing-20-24/Cargo.toml | 7 + .../ch20-web-server/listing-20-24/hello.html | 11 + .../listing-20-24/src/bin/main.rs | 44 ++ .../ch20-web-server/listing-20-24/src/lib.rs | 110 ++++ .../ch20-web-server/listing-20-25/404.html | 11 + .../ch20-web-server/listing-20-25/Cargo.lock | 4 + .../ch20-web-server/listing-20-25/Cargo.toml | 7 + .../ch20-web-server/listing-20-25/hello.html | 11 + .../listing-20-25/src/bin/main.rs | 50 ++ .../ch20-web-server/listing-20-25/src/lib.rs | 112 ++++ .../404.html | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../hello.html | 11 + .../output.txt | 14 + .../src/bin/main.rs | 46 ++ .../src/lib.rs | 1 + .../404.html | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../hello.html | 11 + .../output.txt | 14 + .../src/bin/main.rs | 44 ++ .../src/lib.rs | 11 + .../no-listing-03-define-execute/404.html | 11 + .../no-listing-03-define-execute/Cargo.lock | 4 + .../no-listing-03-define-execute/Cargo.toml | 7 + .../no-listing-03-define-execute/hello.html | 11 + .../no-listing-03-define-execute/output.txt | 3 + .../src/bin/main.rs | 44 ++ .../no-listing-03-define-execute/src/lib.rs | 21 + .../404.html | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../hello.html | 11 + .../output.txt | 27 + .../src/bin/main.rs | 44 ++ .../src/lib.rs | 84 +++ .../no-listing-05-fix-worker-new/404.html | 11 + .../no-listing-05-fix-worker-new/Cargo.lock | 4 + .../no-listing-05-fix-worker-new/Cargo.toml | 7 + .../no-listing-05-fix-worker-new/hello.html | 11 + .../src/bin/main.rs | 44 ++ .../no-listing-05-fix-worker-new/src/lib.rs | 88 ++++ .../404.html | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../hello.html | 11 + .../src/bin/main.rs | 44 ++ .../src/lib.rs | 86 +++ .../404.html | 11 + .../Cargo.lock | 4 + .../Cargo.toml | 7 + .../hello.html | 11 + .../src/bin/main.rs | 44 ++ .../src/lib.rs | 93 ++++ src/ch02-00-guessing-game-tutorial.md | 274 +++------- src/ch03-01-variables-and-mutability.md | 61 +-- src/ch03-02-data-types.md | 94 +--- src/ch03-03-how-functions-work.md | 118 +---- src/ch03-04-comments.md | 9 +- src/ch03-05-control-flow.md | 188 +------ src/ch04-01-what-is-ownership.md | 138 +---- src/ch04-02-references-and-borrowing.md | 143 +---- src/ch04-03-slices.md | 114 +--- src/ch05-01-defining-structs.md | 138 +---- src/ch05-02-example-structs.md | 89 +--- src/ch05-03-method-syntax.md | 77 +-- src/ch06-01-defining-an-enum.md | 117 +---- src/ch06-02-match.md | 112 +--- src/ch06-03-if-let.md | 50 +- ...ng-modules-to-control-scope-and-privacy.md | 18 +- ...referring-to-an-item-in-the-module-tree.md | 123 +---- ...g-paths-into-scope-with-the-use-keyword.md | 114 +--- ...separating-modules-into-different-files.md | 18 +- src/ch08-01-vectors.md | 75 +-- src/ch08-02-strings.md | 67 +-- src/ch08-03-hash-maps.md | 77 +-- ...ch09-01-unrecoverable-errors-with-panic.md | 122 ++--- src/ch09-02-recoverable-errors-with-result.md | 171 ++---- src/ch09-03-to-panic-or-not-to-panic.md | 46 +- src/ch10-00-generics.md | 67 +-- src/ch10-01-syntax.md | 163 +----- src/ch10-02-traits.md | 194 +------ src/ch10-03-lifetime-syntax.md | 199 +------ src/ch11-01-writing-tests.md | 377 ++----------- src/ch11-02-running-tests.md | 125 +---- src/ch11-03-test-organization.md | 105 +--- ...h12-01-accepting-command-line-arguments.md | 36 +- src/ch12-02-reading-a-file.md | 46 +- ...improving-error-handling-and-modularity.md | 205 +------- ...2-04-testing-the-librarys-functionality.md | 123 +---- ...2-05-working-with-environment-variables.md | 137 +---- ...-06-writing-to-stderr-instead-of-stdout.md | 15 +- src/ch13-01-closures.md | 311 +---------- src/ch13-02-iterators.md | 179 +------ src/ch13-03-improving-our-io-project.md | 87 +-- src/ch14-01-release-profiles.md | 11 +- src/ch14-02-publishing-to-crates-io.md | 124 ++--- src/ch14-03-cargo-workspaces.md | 116 ++-- src/ch14-04-installing-binaries.md | 26 +- src/ch15-01-box.md | 55 +- src/ch15-02-deref.md | 116 +--- src/ch15-03-drop.md | 54 +- src/ch15-04-rc.md | 65 +-- src/ch15-05-interior-mutability.md | 199 +------ src/ch15-06-reference-cycles.md | 196 +------ src/ch16-01-threads.md | 139 +---- src/ch16-02-message-passing.md | 143 +---- src/ch16-03-shared-state.md | 115 +--- src/ch17-01-what-is-oo.md | 36 +- src/ch17-02-trait-objects.md | 134 +---- src/ch17-03-oo-design-patterns.md | 265 +--------- src/ch18-01-all-the-places-for-patterns.md | 66 +-- src/ch18-02-refutability.md | 29 +- src/ch18-03-pattern-syntax.md | 298 +---------- src/ch19-01-unsafe-rust.md | 121 +---- src/ch19-03-advanced-traits.md | 274 +--------- src/ch19-04-advanced-types.md | 108 +--- ...ch19-05-advanced-functions-and-closures.md | 56 +- src/ch19-06-macros.md | 84 +-- src/ch20-01-single-threaded.md | 167 +----- src/ch20-02-multithreaded.md | 496 ++---------------- src/ch20-03-graceful-shutdown-and-cleanup.md | 329 +----------- 1950 files changed, 24678 insertions(+), 7665 deletions(-) create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-04/output.txt create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.lock create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.toml create mode 100644 listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/listing-03-01/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/listing-03-01/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/listing-03-01/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/listing-03-02/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/listing-03-02/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/listing-03-02/output.txt create mode 100644 listings/ch03-common-programming-concepts/listing-03-02/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/listing-03-03/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/listing-03-03/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/listing-03-03/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/listing-03-04/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/listing-03-04/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/listing-03-04/output.txt create mode 100644 listings/ch03-common-programming-concepts/listing-03-04/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/listing-03-05/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/listing-03-05/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/listing-03-05/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-06-floating-point/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-08-boolean/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-09-char/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-13-arrays/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt create mode 100644 listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs create mode 100644 listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.lock create mode 100644 listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.toml create mode 100644 listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt create mode 100644 listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-01/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-01/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-01/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-02/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-02/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-02/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-03/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-03/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-03/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-04/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-04/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-04/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-05/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-05/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-05/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-06/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-06/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-06/output.txt create mode 100644 listings/ch04-understanding-ownership/listing-04-06/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-07/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-07/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-07/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-08/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-08/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-08/src/main.rs create mode 100644 listings/ch04-understanding-ownership/listing-04-09/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/listing-04-09/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/listing-04-09/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt create mode 100644 listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-06-copy/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt create mode 100644 listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt create mode 100644 listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt create mode 100644 listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs create mode 100644 listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.lock create mode 100644 listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.toml create mode 100644 listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt create mode 100644 listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.lock create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.toml create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt create mode 100644 listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.lock create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.toml create mode 100644 listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-01/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-01/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-03/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-03/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-03/output.txt create mode 100644 listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-05/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-05/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-05/output.txt create mode 100644 listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-07/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-07/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-08/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-08/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-09/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-09/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-10/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-10/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-11/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-11/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-12/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-12/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-13/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-13/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-14/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-14/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-14/src/main.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-15/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-15/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-15/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-16/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-16/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-16/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-17/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-17/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-18/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-18/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-18/src/main.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-19/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-19/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-19/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-20/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-20/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-20/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs create mode 100644 listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs create mode 100644 listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs create mode 100644 listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.lock create mode 100644 listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.toml create mode 100644 listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house.rs create mode 100644 listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs create mode 100644 listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/lib.rs create mode 100644 listings/ch08-common-collections/listing-08-01/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-01/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-01/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-02/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-02/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-02/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-03/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-03/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-03/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-04/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-04/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-04/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-05/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-05/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-05/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-06/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-06/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-06/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-07/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-07/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-07/output.txt create mode 100644 listings/ch08-common-collections/listing-08-07/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-08/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-08/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-08/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-09/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-09/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-09/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-10/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-10/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-10/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-11/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-11/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-11/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-12/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-12/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-12/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-13/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-13/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-13/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-14/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-14/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-14/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-15/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-15/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-15/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-16/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-16/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-16/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-17/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-17/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-17/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-18/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-18/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-18/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-19/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-19/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-19/output.txt create mode 100644 listings/ch08-common-collections/listing-08-19/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-20/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-20/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-20/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-21/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-21/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-21/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-22/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-22/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-22/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-23/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-23/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-23/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-24/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-24/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-24/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-25/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-25/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-25/src/main.rs create mode 100644 listings/ch08-common-collections/listing-08-26/Cargo.lock create mode 100644 listings/ch08-common-collections/listing-08-26/Cargo.toml create mode 100644 listings/ch08-common-collections/listing-08-26/src/main.rs create mode 100644 listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.lock create mode 100644 listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.toml create mode 100644 listings/ch08-common-collections/no-listing-01-concat-multiple-strings/src/main.rs create mode 100644 listings/ch08-common-collections/no-listing-02-format/Cargo.lock create mode 100644 listings/ch08-common-collections/no-listing-02-format/Cargo.toml create mode 100644 listings/ch08-common-collections/no-listing-02-format/src/main.rs create mode 100644 listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.lock create mode 100644 listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.toml create mode 100644 listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs create mode 100644 listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.lock create mode 100644 listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.toml create mode 100644 listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt create mode 100644 listings/ch08-common-collections/output-only-01-not-char-boundary/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-01/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-01/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-01/output.txt create mode 100644 listings/ch09-error-handling/listing-09-01/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-03/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-03/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-03/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-04/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-04/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-04/output.txt create mode 100644 listings/ch09-error-handling/listing-09-04/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-05/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-05/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-05/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-06/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-06/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-06/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-07/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-07/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-07/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-08/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-08/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-08/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-09/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-09/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-09/src/main.rs create mode 100644 listings/ch09-error-handling/listing-09-10/Cargo.lock create mode 100644 listings/ch09-error-handling/listing-09-10/Cargo.toml create mode 100644 listings/ch09-error-handling/listing-09-10/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-01-panic/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-01-panic/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-01-panic/output.txt create mode 100644 listings/ch09-error-handling/no-listing-01-panic/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/output.txt create mode 100644 listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-03-closures/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-03-closures/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-03-closures/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-04-unwrap/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-04-unwrap/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-05-expect/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-05-expect/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-05-expect/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-06-question-mark-in-main/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-06-question-mark-in-main/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-06-question-mark-in-main/output.txt create mode 100644 listings/ch09-error-handling/no-listing-06-question-mark-in-main/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-07-main-returning-result/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-07-main-returning-result/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-07-main-returning-result/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs create mode 100644 listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.lock create mode 100644 listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.toml create mode 100644 listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/output.txt create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.lock create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.toml create mode 100644 listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-01/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-01/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-01/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-03/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-03/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-03/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-05/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-05/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-06/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-06/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-06/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-07/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-07/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-07/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-08/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-08/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-08/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-09/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-09/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-10/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-10/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-10/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-11/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-11/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-11/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-12/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-12/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-13/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/listing-11-13/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/listing-11-13/output.txt create mode 100644 listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt create mode 100644 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/common.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/common/mod.rs create mode 100644 listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs create mode 100644 listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt create mode 100644 listings/ch11-writing-automated-tests/output-only-01-show-output/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt create mode 100644 listings/ch11-writing-automated-tests/output-only-02-single-test/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt create mode 100644 listings/ch11-writing-automated-tests/output-only-03-multiple-tests/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt create mode 100644 listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.lock create mode 100644 listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.toml create mode 100644 listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt create mode 100644 listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs create mode 100644 listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs create mode 100644 listings/ch12-an-io-project/listing-12-01/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-01/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-01/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-01/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-02/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-02/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-02/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-02/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-03/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-03/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-03/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-03/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-04/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-04/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-04/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-04/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-04/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-05/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-05/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-05/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-05/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-06/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-06/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-06/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-06/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-07/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-07/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-07/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-07/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-07/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-08/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-08/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-08/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-08/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-08/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-09/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-09/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-09/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-09/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-10/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-10/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-10/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-10/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-10/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-11/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-11/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-11/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-11/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-12/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-12/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-12/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-12/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-12/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-13/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-13/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-13/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-13/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-13/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-14/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-14/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-14/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-14/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-14/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-15/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-15/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-15/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-15/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-15/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-16/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-16/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-16/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-16/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-16/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-16/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-17/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-17/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-17/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-17/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-17/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-18/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-18/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-18/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-18/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-18/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-19/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-19/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-19/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-19/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-19/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-19/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-20/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-20/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-20/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-20/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-20/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-21/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-21/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-21/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-21/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-21/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-21/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-22/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-22/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-22/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-22/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-22/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-23/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-23/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-23/output.txt create mode 100644 listings/ch12-an-io-project/listing-12-23/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-23/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-23/src/main.rs create mode 100644 listings/ch12-an-io-project/listing-12-24/Cargo.lock create mode 100644 listings/ch12-an-io-project/listing-12-24/Cargo.toml create mode 100644 listings/ch12-an-io-project/listing-12-24/poem.txt create mode 100644 listings/ch12-an-io-project/listing-12-24/src/lib.rs create mode 100644 listings/ch12-an-io-project/listing-12-24/src/main.rs create mode 100644 listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.lock create mode 100644 listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.toml create mode 100644 listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/poem.txt create mode 100644 listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs create mode 100644 listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.lock create mode 100644 listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.toml create mode 100644 listings/ch12-an-io-project/no-listing-02-using-search-in-run/output.txt create mode 100644 listings/ch12-an-io-project/no-listing-02-using-search-in-run/poem.txt create mode 100644 listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs create mode 100644 listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/main.rs create mode 100644 listings/ch12-an-io-project/output-only-01-with-args/Cargo.lock create mode 100644 listings/ch12-an-io-project/output-only-01-with-args/Cargo.toml create mode 100644 listings/ch12-an-io-project/output-only-01-with-args/output.txt create mode 100644 listings/ch12-an-io-project/output-only-01-with-args/src/main.rs create mode 100644 listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.lock create mode 100644 listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.toml create mode 100644 listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt create mode 100644 listings/ch12-an-io-project/output-only-02-missing-lifetimes/poem.txt create mode 100644 listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs create mode 100644 listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/main.rs create mode 100644 listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.lock create mode 100644 listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.toml create mode 100644 listings/ch12-an-io-project/output-only-03-multiple-matches/output.txt create mode 100644 listings/ch12-an-io-project/output-only-03-multiple-matches/poem.txt create mode 100644 listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs create mode 100644 listings/ch12-an-io-project/output-only-03-multiple-matches/src/main.rs create mode 100644 listings/ch12-an-io-project/output-only-04-no-matches/Cargo.lock create mode 100644 listings/ch12-an-io-project/output-only-04-no-matches/Cargo.toml create mode 100644 listings/ch12-an-io-project/output-only-04-no-matches/output.txt create mode 100644 listings/ch12-an-io-project/output-only-04-no-matches/poem.txt create mode 100644 listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs create mode 100644 listings/ch12-an-io-project/output-only-04-no-matches/src/main.rs create mode 100644 listings/ch13-functional-features/listing-12-23-reproduced/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-12-23-reproduced/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-12-23-reproduced/poem.txt create mode 100644 listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-12-23-reproduced/src/main.rs create mode 100644 listings/ch13-functional-features/listing-12-24-reproduced/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-12-24-reproduced/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-12-24-reproduced/poem.txt create mode 100644 listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-01/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-01/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-02/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-02/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-02/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-03/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-03/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-03/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-04/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-04/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-04/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-05/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-05/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-05/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-06/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-06/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-06/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-07/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-07/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-07/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-08/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-08/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-08/output.txt create mode 100644 listings/ch13-functional-features/listing-13-08/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-09/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-09/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-09/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-10/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-10/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-10/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-11/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-11/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-11/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-12/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-12/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-12/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-13/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-13/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-13/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-14/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-14/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-14/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-15/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-15/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-15/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-16/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-16/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-16/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-17/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-17/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-17/output.txt create mode 100644 listings/ch13-functional-features/listing-13-17/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-18/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-18/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-18/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-19/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-19/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-19/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-20/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-20/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-20/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-21/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-21/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-21/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-22/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-22/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-22/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-23/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-23/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-23/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-25/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-25/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-25/poem.txt create mode 100644 listings/ch13-functional-features/listing-13-25/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-25/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-26/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-26/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-26/poem.txt create mode 100644 listings/ch13-functional-features/listing-13-26/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-26/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-27/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-27/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-27/poem.txt create mode 100644 listings/ch13-functional-features/listing-13-27/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-27/src/main.rs create mode 100644 listings/ch13-functional-features/listing-13-29/Cargo.lock create mode 100644 listings/ch13-functional-features/listing-13-29/Cargo.toml create mode 100644 listings/ch13-functional-features/listing-13-29/poem.txt create mode 100644 listings/ch13-functional-features/listing-13-29/src/lib.rs create mode 100644 listings/ch13-functional-features/listing-13-29/src/main.rs create mode 100644 listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.lock create mode 100644 listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.toml create mode 100644 listings/ch13-functional-features/no-listing-01-failing-cacher-test/output.txt create mode 100644 listings/ch13-functional-features/no-listing-01-failing-cacher-test/src/lib.rs create mode 100644 listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.lock create mode 100644 listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.toml create mode 100644 listings/ch13-functional-features/no-listing-02-functions-cant-capture/output.txt create mode 100644 listings/ch13-functional-features/no-listing-02-functions-cant-capture/src/main.rs create mode 100644 listings/ch13-functional-features/no-listing-03-move-closures/Cargo.lock create mode 100644 listings/ch13-functional-features/no-listing-03-move-closures/Cargo.toml create mode 100644 listings/ch13-functional-features/no-listing-03-move-closures/output.txt create mode 100644 listings/ch13-functional-features/no-listing-03-move-closures/src/main.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-01/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/listing-14-01/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-01/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-02/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/listing-14-02/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-02/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-03/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/listing-14-03/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-03/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-04/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/listing-14-04/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-04/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-04/src/main.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-05/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/listing-14-05/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-05/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-06/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/listing-14-06/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-06/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-06/src/main.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-07/add/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/listing-14-07/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-07/add/add-one/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-07/add/add-one/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/listing-14-07/add/adder/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs create mode 100644 listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/src/main.rs create mode 100644 listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add-one/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add-one/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/src/main.rs create mode 100644 listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add-one/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add-one/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs create mode 100644 listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add-one/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add-one/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs create mode 100644 listings/ch14-more-about-cargo/output-only-01-adder-crate/add/.gitignore create mode 100644 listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/output-only-02-add-one/add/.gitignore create mode 100644 listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/output-only-02-add-one/add/add-one/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/output-only-02-add-one/add/add-one/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/src/main.rs create mode 100644 listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.lock create mode 100644 listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/output-only-03-use-rand/add/add-one/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/output-only-03-use-rand/add/add-one/src/lib.rs create mode 100644 listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/Cargo.toml create mode 100644 listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-01/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-01/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-01/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-02/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-02/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-02/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-03/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-03/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-03/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-03/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-05/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-05/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-05/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-06/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-06/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-06/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-07/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-07/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-07/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-08/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-08/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-08/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-09/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-09/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-09/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-09/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-10/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-10/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-10/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-11/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-11/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-11/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-12/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-12/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-12/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-13/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-13/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-13/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-14/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-14/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-14/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-14/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-15/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-15/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-15/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-15/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-16/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-16/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-16/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-16/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-17/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-17/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-17/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-17/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-18/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-18/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-18/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-19/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-19/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-19/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-19/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-20/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-20/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-20/src/lib.rs create mode 100644 listings/ch15-smart-pointers/listing-15-21/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-21/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-21/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-21/src/lib.rs create mode 100644 listings/ch15-smart-pointers/listing-15-22/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-22/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-22/src/lib.rs create mode 100644 listings/ch15-smart-pointers/listing-15-23/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-23/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-23/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-23/src/lib.rs create mode 100644 listings/ch15-smart-pointers/listing-15-24/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-24/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-24/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-24/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-25/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-25/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-25/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-26/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-26/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-26/output.txt create mode 100644 listings/ch15-smart-pointers/listing-15-26/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-27/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-27/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-27/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-28/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-28/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-28/src/main.rs create mode 100644 listings/ch15-smart-pointers/listing-15-29/Cargo.lock create mode 100644 listings/ch15-smart-pointers/listing-15-29/Cargo.toml create mode 100644 listings/ch15-smart-pointers/listing-15-29/src/main.rs create mode 100644 listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock create mode 100644 listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml create mode 100644 listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt create mode 100644 listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs create mode 100644 listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock create mode 100644 listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml create mode 100644 listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt create mode 100644 listings/ch15-smart-pointers/output-only-01-comparing-to-reference/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-01/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-01/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-01/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-02/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-02/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-02/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-03/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-03/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-03/output.txt create mode 100644 listings/ch16-fearless-concurrency/listing-16-03/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-04/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-04/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-04/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-05/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-05/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-05/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-06/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-06/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-06/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-07/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-07/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-07/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-08/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-08/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-08/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-09/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-09/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-09/output.txt create mode 100644 listings/ch16-fearless-concurrency/listing-16-09/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-10/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-10/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-10/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-11/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-11/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-11/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-12/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-12/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-12/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-13/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-13/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-13/output.txt create mode 100644 listings/ch16-fearless-concurrency/listing-16-13/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-14/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-14/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-14/output.txt create mode 100644 listings/ch16-fearless-concurrency/listing-16-14/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/listing-16-15/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/listing-16-15/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/listing-16-15/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/src/main.rs create mode 100644 listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.lock create mode 100644 listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.toml create mode 100644 listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt create mode 100644 listings/ch16-fearless-concurrency/output-only-01-move-drop/src/main.rs create mode 100644 listings/ch17-oop/listing-17-01/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-01/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-01/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-02/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-02/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-02/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-03/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-03/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-04/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-04/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-04/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-05/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-05/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-05/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-06/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-06/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-06/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-07/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-07/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-07/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-08/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-08/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-08/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-08/src/main.rs create mode 100644 listings/ch17-oop/listing-17-09/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-09/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-09/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-09/src/main.rs create mode 100644 listings/ch17-oop/listing-17-10/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-10/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-10/output.txt create mode 100644 listings/ch17-oop/listing-17-10/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-10/src/main.rs create mode 100644 listings/ch17-oop/listing-17-11/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-11/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-11/src/main.rs create mode 100644 listings/ch17-oop/listing-17-12/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-12/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-12/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-12/src/main.rs create mode 100644 listings/ch17-oop/listing-17-13/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-13/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-13/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-13/src/main.rs create mode 100644 listings/ch17-oop/listing-17-14/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-14/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-14/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-14/src/main.rs create mode 100644 listings/ch17-oop/listing-17-15/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-15/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-15/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-15/src/main.rs create mode 100644 listings/ch17-oop/listing-17-16/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-16/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-16/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-16/src/main.rs create mode 100644 listings/ch17-oop/listing-17-17/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-17/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-17/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-17/src/main.rs create mode 100644 listings/ch17-oop/listing-17-18/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-18/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-18/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-18/src/main.rs create mode 100644 listings/ch17-oop/listing-17-19/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-19/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-19/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-20/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-20/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-20/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-21/Cargo.lock create mode 100644 listings/ch17-oop/listing-17-21/Cargo.toml create mode 100644 listings/ch17-oop/listing-17-21/src/lib.rs create mode 100644 listings/ch17-oop/listing-17-21/src/main.rs create mode 100644 listings/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.lock create mode 100644 listings/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.toml create mode 100644 listings/ch17-oop/no-listing-01-trait-object-of-clone/output.txt create mode 100644 listings/ch17-oop/no-listing-01-trait-object-of-clone/src/lib.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-01/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-01/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-02/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-02/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-03/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-03/output.txt create mode 100644 listings/ch18-patterns-and-matching/listing-18-03/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-04/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-04/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-05/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-05/output.txt create mode 100644 listings/ch18-patterns-and-matching/listing-18-05/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-06/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-06/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-07/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-07/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-08/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-08/output.txt create mode 100644 listings/ch18-patterns-and-matching/listing-18-08/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-09/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-09/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-10/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-10/output.txt create mode 100644 listings/ch18-patterns-and-matching/listing-18-10/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-11/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-11/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-12/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-12/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-13/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-13/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-14/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-14/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-15/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-15/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-16/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-16/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-17/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-17/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-18/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-18/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-19/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-19/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-20/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-20/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-21/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-21/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-22/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-22/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-23/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-23/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-24/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-24/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-25/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-25/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-25/output.txt create mode 100644 listings/ch18-patterns-and-matching/listing-18-25/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-26/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-26/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-27/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-27/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-28/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-28/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/listing-18-29/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/listing-18-29/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/no-listing-01-literals/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/src/main.rs create mode 100644 listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock create mode 100644 listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.toml create mode 100644 listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-13-21-reproduced/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-01/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-01/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-01/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-02/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-02/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-02/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-03/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-03/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-03/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-04/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-04/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-04/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-05/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-05/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-05/output.txt create mode 100644 listings/ch19-advanced-features/listing-19-05/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-06/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-06/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-06/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-07/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-07/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-07/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-08/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-08/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-08/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-09/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-09/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-09/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-10/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-10/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-10/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-11/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-11/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-11/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-12/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-12/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-12/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-13/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-13/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-13/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-14/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-14/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-14/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-15/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-15/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-15/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-16/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-16/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-16/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-17/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-17/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-17/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-18/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-18/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-18/output.txt create mode 100644 listings/ch19-advanced-features/listing-19-18/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-19/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-19/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-19/output.txt create mode 100644 listings/ch19-advanced-features/listing-19-19/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-20/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-20/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-20/output.txt create mode 100644 listings/ch19-advanced-features/listing-19-20/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-21/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-21/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-21/output.txt create mode 100644 listings/ch19-advanced-features/listing-19-21/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-22/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-22/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-22/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-23/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-23/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-23/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-24/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-24/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-24/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-25/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-25/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-25/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-27/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-27/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-27/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-28/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-28/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-28/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-30/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-30/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-30/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-31/hello_macro/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-31/hello_macro/src/main.rs create mode 100644 listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.lock create mode 100644 listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.toml create mode 100644 listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-33/hello_macro/src/lib.rs create mode 100644 listings/ch19-advanced-features/listing-19-33/hello_macro/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-01-unsafe-fn/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt create mode 100644 listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-04-kilometers-alias/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-05-write-trait/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-06-result-alias/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-07-never-type/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-07-never-type/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-10-loop-returns-never/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-12-generic-fn-definition/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-15-map-closure/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-16-map-function/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-16-map-function/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt create mode 100644 listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/lib.rs create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/main.rs create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.lock create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.toml create mode 100644 listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/src/main.rs create mode 100644 listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock create mode 100644 listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.toml create mode 100644 listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt create mode 100644 listings/ch19-advanced-features/output-only-01-missing-unsafe/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-01/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-01/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-01/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-02/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-02/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-02/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-03/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-03/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-03/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-04/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-04/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-04/hello.html create mode 100644 listings/ch20-web-server/listing-20-04/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-05/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-05/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-05/hello.html create mode 100644 listings/ch20-web-server/listing-20-05/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-06/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-06/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-06/hello.html create mode 100644 listings/ch20-web-server/listing-20-06/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-07/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-07/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-07/hello.html create mode 100644 listings/ch20-web-server/listing-20-07/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-08/404.html create mode 100644 listings/ch20-web-server/listing-20-08/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-08/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-08/hello.html create mode 100644 listings/ch20-web-server/listing-20-08/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-09/404.html create mode 100644 listings/ch20-web-server/listing-20-09/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-09/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-09/hello.html create mode 100644 listings/ch20-web-server/listing-20-09/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-10/404.html create mode 100644 listings/ch20-web-server/listing-20-10/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-10/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-10/hello.html create mode 100644 listings/ch20-web-server/listing-20-10/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-11/404.html create mode 100644 listings/ch20-web-server/listing-20-11/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-11/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-11/hello.html create mode 100644 listings/ch20-web-server/listing-20-11/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-12/404.html create mode 100644 listings/ch20-web-server/listing-20-12/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-12/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-12/hello.html create mode 100644 listings/ch20-web-server/listing-20-12/output.txt create mode 100644 listings/ch20-web-server/listing-20-12/src/main.rs create mode 100644 listings/ch20-web-server/listing-20-13/404.html create mode 100644 listings/ch20-web-server/listing-20-13/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-13/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-13/hello.html create mode 100644 listings/ch20-web-server/listing-20-13/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-13/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-14/404.html create mode 100644 listings/ch20-web-server/listing-20-14/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-14/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-14/hello.html create mode 100644 listings/ch20-web-server/listing-20-14/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-14/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-15/404.html create mode 100644 listings/ch20-web-server/listing-20-15/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-15/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-15/hello.html create mode 100644 listings/ch20-web-server/listing-20-15/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-15/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-16/404.html create mode 100644 listings/ch20-web-server/listing-20-16/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-16/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-16/hello.html create mode 100644 listings/ch20-web-server/listing-20-16/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-16/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-17/404.html create mode 100644 listings/ch20-web-server/listing-20-17/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-17/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-17/hello.html create mode 100644 listings/ch20-web-server/listing-20-17/output.txt create mode 100644 listings/ch20-web-server/listing-20-17/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-17/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-18/404.html create mode 100644 listings/ch20-web-server/listing-20-18/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-18/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-18/hello.html create mode 100644 listings/ch20-web-server/listing-20-18/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-18/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-19/404.html create mode 100644 listings/ch20-web-server/listing-20-19/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-19/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-19/hello.html create mode 100644 listings/ch20-web-server/listing-20-19/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-19/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-20/404.html create mode 100644 listings/ch20-web-server/listing-20-20/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-20/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-20/hello.html create mode 100644 listings/ch20-web-server/listing-20-20/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-20/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-21/404.html create mode 100644 listings/ch20-web-server/listing-20-21/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-21/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-21/hello.html create mode 100644 listings/ch20-web-server/listing-20-21/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-21/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-22/404.html create mode 100644 listings/ch20-web-server/listing-20-22/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-22/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-22/hello.html create mode 100644 listings/ch20-web-server/listing-20-22/output.txt create mode 100644 listings/ch20-web-server/listing-20-22/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-22/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-23/404.html create mode 100644 listings/ch20-web-server/listing-20-23/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-23/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-23/hello.html create mode 100644 listings/ch20-web-server/listing-20-23/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-23/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-24/404.html create mode 100644 listings/ch20-web-server/listing-20-24/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-24/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-24/hello.html create mode 100644 listings/ch20-web-server/listing-20-24/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-24/src/lib.rs create mode 100644 listings/ch20-web-server/listing-20-25/404.html create mode 100644 listings/ch20-web-server/listing-20-25/Cargo.lock create mode 100644 listings/ch20-web-server/listing-20-25/Cargo.toml create mode 100644 listings/ch20-web-server/listing-20-25/hello.html create mode 100644 listings/ch20-web-server/listing-20-25/src/bin/main.rs create mode 100644 listings/ch20-web-server/listing-20-25/src/lib.rs create mode 100644 listings/ch20-web-server/no-listing-01-define-threadpool-struct/404.html create mode 100644 listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock create mode 100644 listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.toml create mode 100644 listings/ch20-web-server/no-listing-01-define-threadpool-struct/hello.html create mode 100644 listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt create mode 100644 listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs create mode 100644 listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/lib.rs create mode 100644 listings/ch20-web-server/no-listing-02-impl-threadpool-new/404.html create mode 100644 listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock create mode 100644 listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.toml create mode 100644 listings/ch20-web-server/no-listing-02-impl-threadpool-new/hello.html create mode 100644 listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt create mode 100644 listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/bin/main.rs create mode 100644 listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs create mode 100644 listings/ch20-web-server/no-listing-03-define-execute/404.html create mode 100644 listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock create mode 100644 listings/ch20-web-server/no-listing-03-define-execute/Cargo.toml create mode 100644 listings/ch20-web-server/no-listing-03-define-execute/hello.html create mode 100644 listings/ch20-web-server/no-listing-03-define-execute/output.txt create mode 100644 listings/ch20-web-server/no-listing-03-define-execute/src/bin/main.rs create mode 100644 listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs create mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/404.html create mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock create mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.toml create mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/hello.html create mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt create mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/src/bin/main.rs create mode 100644 listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs create mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/404.html create mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock create mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.toml create mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/hello.html create mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/src/bin/main.rs create mode 100644 listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs create mode 100644 listings/ch20-web-server/no-listing-06-fix-threadpool-drop/404.html create mode 100644 listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock create mode 100644 listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.toml create mode 100644 listings/ch20-web-server/no-listing-06-fix-threadpool-drop/hello.html create mode 100644 listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/bin/main.rs create mode 100644 listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs create mode 100644 listings/ch20-web-server/no-listing-07-define-message-enum/404.html create mode 100644 listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.lock create mode 100644 listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.toml create mode 100644 listings/ch20-web-server/no-listing-07-define-message-enum/hello.html create mode 100644 listings/ch20-web-server/no-listing-07-define-message-enum/src/bin/main.rs create mode 100644 listings/ch20-web-server/no-listing-07-define-message-enum/src/lib.rs diff --git a/ci/dictionary.txt b/ci/dictionary.txt index 98f4b89e..2ac71a67 100644 --- a/ci/dictionary.txt +++ b/ci/dictionary.txt @@ -6,6 +6,7 @@ adaptor adaptors AddAssign Addr +afdc aggregator AGraph aliasability @@ -247,6 +248,7 @@ libpanic librarys libreoffice libstd +libunwind lifecycle LimitTracker linter @@ -334,6 +336,7 @@ parameterize ParseIntError PartialEq PartialOrd +pbcopy PendingReview PendingReviewPost PlaceholderType 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 100644 index 00000000..5802b7dc --- /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 100644 index 00000000..e3091e7d --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-01/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# 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 100644 index 00000000..805241a5 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs @@ -0,0 +1,14 @@ +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-02/Cargo.lock b/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.lock new file mode 100644 index 00000000..2752c9fb --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.62" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..805241a5 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs @@ -0,0 +1,14 @@ +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 100644 index 00000000..2b3d41ad --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-03/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..b73f3678 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs @@ -0,0 +1,27 @@ +// 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 100644 index 00000000..2b3d41ad --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..940d3727 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt @@ -0,0 +1,21 @@ +$ cargo build + Compiling libc v0.2.51 + Compiling rand_core v0.4.0 + Compiling rand_core v0.3.1 + Compiling rand v0.5.6 + 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 `std::string::String`, found integer + | + = note: expected type `&std::string::String` + found type `&{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `guessing_game`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..bee037d4 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs @@ -0,0 +1,32 @@ +// ANCHOR: here +use std::io; +use std::cmp::Ordering; +use rand::Rng; + +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 100644 index 00000000..2b3d41ad --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-05/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..84bf59c9 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs @@ -0,0 +1,44 @@ +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); + + 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 100644 index 00000000..890a6580 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.53" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)" = "ec350a9417dfd244dc9a6c4a71e13895a4db6b92f0b106f07ebbc3f3bc580cee" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-06/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..2d4254ea --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs @@ -0,0 +1,34 @@ +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; + } + } + } +} 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 100644 index 00000000..5802b7dc --- /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 100644 index 00000000..e3091e7d --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# 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 100644 index 00000000..2724c145 --- /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 100644 index 00000000..e7a11a96 --- /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 100644 index 00000000..5802b7dc --- /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 100644 index 00000000..e3091e7d --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# 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 100644 index 00000000..928bff97 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt @@ -0,0 +1,12 @@ +$ cargo build + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) +warning: unused `std::result::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 + + 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 100644 index 00000000..aaf90bd6 --- /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 100644 index 00000000..2b3d41ad --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..b2060378 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs @@ -0,0 +1,33 @@ +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); + + 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 100644 index 00000000..2b3d41ad --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..2efd6243 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs @@ -0,0 +1,40 @@ +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); + + // 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 \ No newline at end of file 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 100644 index 00000000..2b3d41ad --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..c6975ea0 --- /dev/null +++ b/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs @@ -0,0 +1,38 @@ +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); + + 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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b492d384 --- /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 100644 index 00000000..a9b4d7e6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8ddf6914 --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "branches" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3eb8d102 --- /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 100644 index 00000000..11ebad4e --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-02/src/main.rs @@ -0,0 +1,10 @@ +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 100644 index 00000000..3ca5bbae --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b5ed848a --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "loops" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..651ed68c --- /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 100644 index 00000000..3ca5bbae --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b5ed848a --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "loops" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..35c0f804 --- /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 100644 index 00000000..38fd301e --- /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 100644 index 00000000..3ca5bbae --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b5ed848a --- /dev/null +++ b/listings/ch03-common-programming-concepts/listing-03-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "loops" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6e3cca66 --- /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.iter() { + 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 100644 index 00000000..2d62cbe7 --- /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 100644 index 00000000..7915d397 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "variables" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f40d3632 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt @@ -0,0 +1,20 @@ +$ 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: make this binding mutable: `mut x` +3 | println!("The value of x is: {}", x); +4 | x = 6; + | ^^^^^ cannot assign twice to immutable variable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0384`. +error: Could not compile `variables`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..a6c7ac07 --- /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 100644 index 00000000..2d62cbe7 --- /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 100644 index 00000000..7915d397 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "variables" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8ed6598f --- /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 100644 index 00000000..c4e4a195 --- /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 100644 index 00000000..2d62cbe7 --- /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 100644 index 00000000..7915d397 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "variables" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..64ac2bf5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt @@ -0,0 +1,5 @@ +$ 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 is: 12 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 100644 index 00000000..d3251801 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + let x = 5; + + let x = x + 1; + + let x = x * 2; + + 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 100644 index 00000000..6d77f6bc --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..7915d397 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "variables" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..42589f54 --- /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 100644 index 00000000..6d77f6bc --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..7915d397 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "variables" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..34bec245 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt @@ -0,0 +1,17 @@ +$ cargo run + Compiling variables v0.1.0 (file:///projects/variables) +error[E0308]: mismatched types + --> src/main.rs:3:14 + | +3 | spaces = spaces.len(); + | ^^^^^^^^^^^^ expected &str, found usize + | + = note: expected type `&str` + found type `usize` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `variables`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..f52635d0 --- /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 100644 index 00000000..c51ba572 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..81e80c29 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-06-floating-point/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "floating-point" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6f4f0fe8 --- /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 100644 index 00000000..4f0ede62 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..00601dde --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "numeric-operations" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0a784bbc --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs @@ -0,0 +1,16 @@ +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; + + // 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 100644 index 00000000..bbe61d93 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..783df3dd --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-08-boolean/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "boolean" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2c56e62f --- /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 100644 index 00000000..d55f4e95 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..cfde83b8 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-09-char/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "char" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4b8d9d93 --- /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 100644 index 00000000..12bebfec --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8d6c2d57 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-10-tuples/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "tuples" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b7b51fb2 --- /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 100644 index 00000000..12bebfec --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8d6c2d57 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "tuples" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..35dcb442 --- /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 100644 index 00000000..12bebfec --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8d6c2d57 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "tuples" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1b1e646f --- /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 100644 index 00000000..5ba3a3ec --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..ec97b7d5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-13-arrays/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "arrays" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d475901c --- /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 100644 index 00000000..5ba3a3ec --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..ec97b7d5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "arrays" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d33e3174 --- /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 100644 index 00000000..5ba3a3ec --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..ec97b7d5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "arrays" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] diff --git a/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt new file mode 100644 index 00000000..be3ef310 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling arrays v0.1.0 (file:///projects/arrays) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + Running `target/debug/arrays` +thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 10', src/main.rs:5:19 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. 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 100644 index 00000000..5ce0ed4a --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + let a = [1, 2, 3, 4, 5]; + let index = 10; + + let element = a[index]; + + println!("The value of element is: {}", 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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-16-functions/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..723fad32 --- /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 100644 index 00000000..38be8565 --- /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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..546bbc04 --- /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 100644 index 00000000..029446c0 --- /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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d651191c --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt @@ -0,0 +1,6 @@ +$ cargo run + Compiling functions v0.1.0 (file:///projects/functions) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + Running `target/debug/functions` +The value of x is: 5 +The value of y is: 6 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 100644 index 00000000..fe476db0 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + another_function(5, 6); +} + +fn another_function(x: i32, y: i32) { + println!("The value of x is: {}", x); + println!("The value of y is: {}", y); +} 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 100644 index 00000000..89a654d6 --- /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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..988f9653 --- /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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..baa853e1 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + let x = 5; + + 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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a457e339 --- /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 100644 index 00000000..5303b108 --- /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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b4c84437 --- /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 100644 index 00000000..89a654d6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..291680cf --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6dbc57e5 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt @@ -0,0 +1,21 @@ +$ 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 () + | | + | this function's body doesn't return +8 | x + 1; + | - help: consider removing this semicolon + | + = note: expected type `i32` + found type `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `functions`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..c9c4edc1 --- /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 100644 index 00000000..0c3b6780 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..c53d8757 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "comments" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..535f4b99 --- /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 100644 index 00000000..0c3b6780 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..c53d8757 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "comments" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..81cd9355 --- /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 100644 index 00000000..a9b4d7e6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8ddf6914 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-26-if-true/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "branches" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3d8c7dc3 --- /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 100644 index 00000000..e64a42ad --- /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 100644 index 00000000..a9b4d7e6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8ddf6914 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-27-if-false/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "branches" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e40da961 --- /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 100644 index 00000000..f7d76cf5 --- /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 100644 index 00000000..a9b4d7e6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8ddf6914 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "branches" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..79500f97 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt @@ -0,0 +1,17 @@ +$ 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 + | + = note: expected type `bool` + found type `{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `branches`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..bc4af767 --- /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 100644 index 00000000..a9b4d7e6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8ddf6914 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "branches" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..704650f4 --- /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 100644 index 00000000..a9b4d7e6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8ddf6914 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-30-else-if/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "branches" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b218941a --- /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 100644 index 00000000..d0ef9b2c --- /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 100644 index 00000000..a9b4d7e6 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8ddf6914 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "branches" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..591e73ab --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt @@ -0,0 +1,24 @@ +$ cargo run + Compiling branches v0.1.0 (file:///projects/branches) +error[E0308]: if and else have incompatible types + --> src/main.rs:7:9 + | +4 | let number = if condition { + | __________________- +5 | | 5 + | | - expected because of this +6 | | } else { +7 | | "six" + | | ^^^^^ expected integer, found &str +8 | | }; + | |_____- if and else have incompatible types + | + = note: expected type `{integer}` + found type `&str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `branches`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..ca1ac970 --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs @@ -0,0 +1,11 @@ +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-loop/Cargo.lock b/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.lock new file mode 100644 index 00000000..9942b362 --- /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 100644 index 00000000..b5ed848a --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-32-loop/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "loops" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f1692e46 --- /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 100644 index 00000000..3ca5bbae --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b5ed848a --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "loops" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6ffdab5a --- /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 100644 index 00000000..3ca5bbae --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b5ed848a --- /dev/null +++ b/listings/ch03-common-programming-concepts/no-listing-34-for-range/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "loops" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e7286a84 --- /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 100644 index 00000000..b5664bc3 --- /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 100644 index 00000000..964f9e8e --- /dev/null +++ b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "no_type_annotations" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# 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 100644 index 00000000..e0cba5ff --- /dev/null +++ b/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt @@ -0,0 +1,17 @@ +$ 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!"); + | ^^^^^ + | | + | cannot infer type + | consider giving `guess` a type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. +error: Could not compile `no_type_annotations`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..f41c5580 --- /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 100644 index 00000000..9e4e62dd --- /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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..148ad84c --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..de0f1b32 --- /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 100644 index 00000000..9e4e62dd --- /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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..23906b43 --- /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 100644 index 00000000..9e4e62dd --- /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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..e3e54a81 --- /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 goes out of scope but 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("hello"); // some_string comes into scope + + some_string // some_string is returned and + // moves out to the calling + // function +} + +// takes_and_gives_back will take a String and return 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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..22aee141 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8ce93233 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-06/output.txt @@ -0,0 +1,16 @@ +$ 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 std::string::String` +8 | some_string.push_str(", world"); + | ^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. +error: Could not compile `ownership`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..330ffa68 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..dddcb5a1 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Carol (Nichols || Goulding) "] +edition = "2018" + +[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 100644 index 00000000..a5ed8890 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-07/src/main.rs @@ -0,0 +1,22 @@ +// 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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b6182fe2 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..19a9cc74 --- /dev/null +++ b/listings/ch04-understanding-ownership/listing-04-09/src/main.rs @@ -0,0 +1,31 @@ +// 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 + 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); +} +// 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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..86e1ffb4 --- /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 100644 index 00000000..9e4e62dd --- /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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..7e6d46f8 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-03-string-move/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a5817e71 --- /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 100644 index 00000000..2aa4918e --- /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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fcffb809 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt @@ -0,0 +1,19 @@ +$ 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 `std::string::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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. +error: Could not compile `ownership`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..d0b9f187 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-05-clone/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4e61cc1a --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-06-copy/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..63a1fae2 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-07-reference/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fd32a5fc --- /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 100644 index 00000000..9e4e62dd --- /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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..6e40b8c3 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fdf7f0a6 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..dd5eaac9 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt @@ -0,0 +1,19 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0499`. +error: Could not compile `ownership`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..ddbf8120 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..36a4cbdd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs @@ -0,0 +1,12 @@ +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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a1978001 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt @@ -0,0 +1,20 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. +error: Could not compile `ownership`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..0da04c01 --- /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.toml b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.toml new file mode 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3b0a7da6 --- /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); + // r1 and r2 are no longer 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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..681bf734 --- /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 { + | ^ help: consider giving it a 'static lifetime: `&'static` + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0106`. +error: Could not compile `ownership`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..b1026978 --- /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 100644 index 00000000..9e4e62dd --- /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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..9fbb372a --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-16-no-dangle/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9c20a3b2 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-17-slice/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..44163af9 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ffe53251 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs @@ -0,0 +1,16 @@ +// 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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-19-slice-error/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4725aa18 --- /dev/null +++ b/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt @@ -0,0 +1,20 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. +error: Could not compile `ownership`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..99e04018 --- /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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..01bf0aa6 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} +// 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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..390c8ff1 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs @@ -0,0 +1,17 @@ +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} + +fn main() { + // ANCHOR: here + 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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..15919f68 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs @@ -0,0 +1,19 @@ +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} + +fn main() { + // ANCHOR: here + 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 +} \ No newline at end of file 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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e81e37c8 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs @@ -0,0 +1,21 @@ +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} + +// 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")); +} \ No newline at end of file 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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..40c9d7c9 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs @@ -0,0 +1,21 @@ +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} + +// 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")); +} \ No newline at end of file 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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6c6d83d9 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs @@ -0,0 +1,24 @@ +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} + +fn main() { + 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"), + username: String::from("anotherusername567"), + active: user1.active, + 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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..17cef457 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs @@ -0,0 +1,23 @@ +struct User { + username: String, + email: String, + sign_in_count: u64, + active: bool, +} + +fn main() { + 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"), + username: String::from("anotherusername567"), + ..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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..88e10d32 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling structs v0.1.0 (file:///projects/structs) + Finished dev [unoptimized + debuginfo] target(s) in 0.42s + Running `target/debug/structs` +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 100644 index 00000000..f324529f --- /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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d4b77ba7 --- /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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..67cabcc1 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs @@ -0,0 +1,17 @@ +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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..eb3e23f9 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt @@ -0,0 +1,18 @@ +$ cargo run + Compiling structs v0.1.0 (file:///projects/structs) +error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` + --> src/main.rs:9:29 + | +9 | 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: required by `std::fmt::Display::fmt` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `structs`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..e494ffc9 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs @@ -0,0 +1,10 @@ +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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3abfb425 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt @@ -0,0 +1,5 @@ +$ cargo run + Compiling structs v0.1.0 (file:///projects/structs) + Finished dev [unoptimized + debuginfo] target(s) in 0.48s + Running `target/debug/structs` +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 100644 index 00000000..3f33dd74 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs @@ -0,0 +1,11 @@ +#[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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7b39830c --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs @@ -0,0 +1,20 @@ +#[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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..29283d08 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs @@ -0,0 +1,8 @@ +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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5dd554ea --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs @@ -0,0 +1,26 @@ +#[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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..89be55a0 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs @@ -0,0 +1,29 @@ +#[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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4c92c5d7 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + struct Color(i32, i32, i32); + struct Point(i32, i32, i32); + + let black = Color(0, 0, 0); + let origin = Point(0, 0, 0); + // ANCHOR_END: here +} 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 100644 index 00000000..bede081a --- /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 100644 index 00000000..dec1c4bd --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# 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 100644 index 00000000..1292e51e --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt @@ -0,0 +1,20 @@ +$ cargo run + Compiling structs v0.1.0 (file:///projects/structs) +error[E0106]: missing lifetime specifier + --> src/main.rs:2:15 + | +2 | username: &str, + | ^ expected lifetime parameter + +error[E0106]: missing lifetime specifier + --> src/main.rs:3:12 + | +3 | email: &str, + | ^ expected lifetime parameter + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. +error: Could not compile `structs`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..3cf6ffa4 --- /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 { + username: &str, + email: &str, + sign_in_count: u64, + active: bool, +} + +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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8b1d5abc --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs @@ -0,0 +1,17 @@ +#[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); +} \ No newline at end of file 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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d1902d02 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt @@ -0,0 +1,18 @@ +$ cargo run + Compiling structs v0.1.0 (file:///projects/structs) +error[E0277]: `Rectangle` doesn't implement `std::fmt::Debug` + --> src/main.rs:9:31 + | +9 | println!("rect1 is {:?}", rect1); + | ^^^^^ `Rectangle` cannot be formatted using `{:?}` + | + = help: the trait `std::fmt::Debug` is not implemented for `Rectangle` + = note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` + = note: required by `std::fmt::Debug::fmt` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `structs`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..1b3e5783 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs @@ -0,0 +1,10 @@ +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 100644 index 00000000..25b0b721 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "structs" +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 100644 index 00000000..431e5c30 --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "structs" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..099ef9ea --- /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 structs v0.1.0 (file:///projects/structs) + Finished dev [unoptimized + debuginfo] target(s) in 0.48s + Running `target/debug/structs` +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 100644 index 00000000..3cd1e8ce --- /dev/null +++ b/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs @@ -0,0 +1,11 @@ +#[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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5b688e0f --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3ba74978 --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6007e4ce --- /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() {} \ No newline at end of file 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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3ba384fb --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c86190aa --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..222d5455 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs @@ -0,0 +1,9 @@ +fn main() { + // ANCHOR: here + let some_u8_value = Some(0u8); + match some_u8_value { + Some(3) => println!("three"), + _ => (), + } + // 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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..784119f7 --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7d59b811 --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..844a1404 --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a8e657ec --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs @@ -0,0 +1,12 @@ +// 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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..66e0b6da --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9de5791b --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..21146004 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling enums v0.1.0 (file:///projects/enums) +error[E0277]: cannot add `std::option::Option` to `i8` + --> src/main.rs:5:17 + | +5 | let sum = x + y; + | ^ no implementation for `i8 + std::option::Option` + | + = help: the trait `std::ops::Add>` is not implemented for `i8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `enums`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..ec65565d --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ac786e1f --- /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() {} \ No newline at end of file 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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2cf79985 --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e6cb637a --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt @@ -0,0 +1,16 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. +error: Could not compile `enums`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..f1963d0c --- /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-11-underscore-placeholder/Cargo.lock b/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/Cargo.lock new file mode 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "enums" +version = "0.1.0" + diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/Cargo.toml b/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/Cargo.toml new file mode 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] diff --git a/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/src/main.rs b/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/src/main.rs new file mode 100644 index 00000000..6fc8ab05 --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/src/main.rs @@ -0,0 +1,12 @@ +fn main() { + // ANCHOR: here + let some_u8_value = 0u8; + match some_u8_value { + 1 => println!("one"), + 3 => println!("three"), + 5 => println!("five"), + 7 => println!("seven"), + _ => (), + } + // ANCHOR_END: here +} 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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fb6578cf --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/src/main.rs @@ -0,0 +1,8 @@ +fn main() { + let some_u8_value = Some(0u8); + // ANCHOR: here + if let Some(3) = some_u8_value { + println!("three"); + } + // 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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..12c4c0fe --- /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 100644 index 00000000..d3577dda --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..04988d1f --- /dev/null +++ b/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "enums" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ba7eda27 --- /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/ch07-managing-growing-projects/listing-07-01/Cargo.lock b/listings/ch07-managing-growing-projects/listing-07-01/Cargo.lock new file mode 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0e40be70 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs @@ -0,0 +1,19 @@ +// ANCHOR: here +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() {} + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..40fedb20 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-03/output.txt @@ -0,0 +1,20 @@ +$ 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(); + | ^^^^^^^ + +error[E0603]: module `hosting` is private + --> src/lib.rs:12:21 + | +12 | front_of_house::hosting::add_to_waitlist(); + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0603`. +error: Could not compile `restaurant`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..0b8a43c6 --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f02880d3 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-05/output.txt @@ -0,0 +1,20 @@ +$ 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(); + | ^^^^^^^^^^^^^^^ + +error[E0603]: function `add_to_waitlist` is private + --> src/lib.rs:12:30 + | +12 | front_of_house::hosting::add_to_waitlist(); + | ^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0603`. +error: Could not compile `restaurant`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..05372dbe --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5a6edf98 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +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(); +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ee3cf5ec --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs @@ -0,0 +1,14 @@ +// ANCHOR: here +fn serve_order() {} + +mod back_of_house { + fn fix_incorrect_order() { + cook_order(); + super::serve_order(); + } + + fn cook_order() {} +} +// ANCHOR_END: here + +fn main() {} \ No newline at end of file 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..92c4695d --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..908f1dfb --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3a756837 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +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(); +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6b0101b7 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +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(); +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..98414aac --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +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(); +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4379e7c7 --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..bfac3a07 --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..843490b4 --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e948d7c3 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +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(); +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..2e0b103b --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-18/Cargo.lock @@ -0,0 +1,89 @@ +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.53" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)" = "ec350a9417dfd244dc9a6c4a71e13895a4db6b92f0b106f07ebbc3f3bc580cee" +"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..ad5ca696 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-18/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..0d23c367 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-18/src/main.rs @@ -0,0 +1,28 @@ +use std::{cmp::Ordering, 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"); + + 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3fee46c4 --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..341f40a4 --- /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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/listing-07-21-and-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6875dfdb --- /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 100644 index 00000000..065b1b80 --- /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 100644 index 00000000..2b3d41ad --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.lock @@ -0,0 +1,87 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "bitflags" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a606a02debe2813760609f57a64a2ffd27d9fdf5b2f133eaca0b248dd92cdd2" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..10932024 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..5ccfb12a --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs @@ -0,0 +1,29 @@ +// ANCHOR: here +use std::io; +use std::cmp::Ordering; +// --snip-- +// ANCHOR_END: here +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); + + 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 100644 index 00000000..4e4270a2 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8bdd0a41 --- /dev/null +++ b/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "restaurant" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d0a8154e --- /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 100644 index 00000000..d65f3afd --- /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 100644 index 00000000..065b1b80 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..45e45581 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3b10a53e --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..147223f9 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7fd5a490 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-04/src/main.rs @@ -0,0 +1,10 @@ +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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9bfa37a4 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..783d9b11 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..686c9098 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-07/output.txt @@ -0,0 +1,20 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. +error: Could not compile `collections`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..1b42274a --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..38b97784 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c62ba21b --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c2198883 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4cf4c81c --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d9e5e768 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b81e3745 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f701fd57 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7dec657d --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8938dc14 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0a9e8cc0 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8e55dc51 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2583f619 --- /dev/null +++ b/listings/ch08-common-collections/listing-08-19/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling collections v0.1.0 (file:///projects/collections) +error[E0277]: the type `std::string::String` cannot be indexed by `{integer}` + --> src/main.rs:3:13 + | +3 | let h = s1[0]; + | ^^^^^ `std::string::String` cannot be indexed by `{integer}` + | + = help: the trait `std::ops::Index<{integer}>` is not implemented for `std::string::String` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `collections`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..fc08e9ce --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..54c20109 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ce51345a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-21/src/main.rs @@ -0,0 +1,10 @@ +fn main() { + // ANCHOR: here + use std::collections::HashMap; + + let teams = vec![String::from("Blue"), String::from("Yellow")]; + let initial_scores = vec![10, 50]; + + let scores: HashMap<_, _> = teams.iter().zip(initial_scores.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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2b2a73f9 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-23/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..508e33cb --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-24/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-24/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e8684cf2 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-25/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-25/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3ad97b57 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/listing-08-26/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/listing-08-26/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f3f6aa16 --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/no-listing-01-concat-multiple-strings/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4995650d --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/no-listing-02-format/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/no-listing-02-format/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4a38e63d --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2e7dc02e --- /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 100644 index 00000000..14856a6a --- /dev/null +++ b/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b36871be --- /dev/null +++ b/listings/ch08-common-collections/output-only-01-not-char-boundary/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "collections" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..449271dc --- /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/libcore/str/mod.rs:2034:5 +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 100644 index 00000000..9283ff5b --- /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 100644 index 00000000..4fe030fa --- /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 100644 index 00000000..310342cd --- /dev/null +++ b/listings/ch09-error-handling/listing-09-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "panic" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..67a4f959 --- /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', /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/slice/mod.rs:2681:10 +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 100644 index 00000000..70194abd --- /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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/listing-09-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0dfd10b5 --- /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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/listing-09-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5bf2a522 --- /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:9:13 +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 100644 index 00000000..65973a45 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-04/src/main.rs @@ -0,0 +1,12 @@ +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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/listing-09-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d53952e3 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-05/src/main.rs @@ -0,0 +1,17 @@ +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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/listing-09-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..65b6156f --- /dev/null +++ b/listings/ch09-error-handling/listing-09-06/src/main.rs @@ -0,0 +1,25 @@ +// ANCHOR: here +use std::io; +use std::io::Read; +use std::fs::File; + +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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/listing-09-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2fb154e3 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-07/src/main.rs @@ -0,0 +1,16 @@ +// ANCHOR: here +use std::io; +use std::io::Read; +use std::fs::File; + +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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/listing-09-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..930a8bf0 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-08/src/main.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +use std::io; +use std::io::Read; +use std::fs::File; + +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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/listing-09-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f8a213bc --- /dev/null +++ b/listings/ch09-error-handling/listing-09-09/src/main.rs @@ -0,0 +1,12 @@ +// ANCHOR: here +use std::io; +use std::fs; + +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 100644 index 00000000..2e0b103b --- /dev/null +++ b/listings/ch09-error-handling/listing-09-10/Cargo.lock @@ -0,0 +1,89 @@ +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.53" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)" = "ec350a9417dfd244dc9a6c4a71e13895a4db6b92f0b106f07ebbc3f3bc580cee" +"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..ad5ca696 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-10/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..be30ed72 --- /dev/null +++ b/listings/ch09-error-handling/listing-09-10/src/main.rs @@ -0,0 +1,56 @@ +use std::io; +use std::cmp::Ordering; +use rand::Rng; + +// 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 100644 index 00000000..c6c01a5d --- /dev/null +++ b/listings/ch09-error-handling/no-listing-01-panic/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..310342cd --- /dev/null +++ b/listings/ch09-error-handling/no-listing-01-panic/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "panic" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1bc3dc72 --- /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 100644 index 00000000..32a4c243 --- /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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1d661eb2 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/output.txt @@ -0,0 +1,17 @@ +$ 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 `std::result::Result` + | + = note: expected type `u32` + found type `std::result::Result` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `error-handling`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..a637f5f9 --- /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-03-closures/Cargo.lock b/listings/ch09-error-handling/no-listing-03-closures/Cargo.lock new file mode 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-03-closures/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-03-closures/Cargo.toml b/listings/ch09-error-handling/no-listing-03-closures/Cargo.toml new file mode 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/no-listing-03-closures/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-03-closures/src/main.rs b/listings/ch09-error-handling/no-listing-03-closures/src/main.rs new file mode 100644 index 00000000..c6682cd2 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-03-closures/src/main.rs @@ -0,0 +1,14 @@ +use std::fs::File; +use std::io::ErrorKind; + +fn main() { + let f = File::open("hello.txt").unwrap_or_else(|error| { + if error.kind() == ErrorKind::NotFound { + File::create("hello.txt").unwrap_or_else(|error| { + panic!("Problem creating the file: {:?}", error); + }) + } else { + panic!("Problem opening the file: {:?}", error); + } + }); +} 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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/no-listing-04-unwrap/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7b6b13ae --- /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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-05-expect/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/no-listing-05-expect/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..cab643bc --- /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-06-question-mark-in-main/Cargo.lock b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/Cargo.lock new file mode 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-06-question-mark-in-main/Cargo.toml b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/Cargo.toml new file mode 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-06-question-mark-in-main/output.txt b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/output.txt new file mode 100644 index 00000000..1b41e79e --- /dev/null +++ b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/output.txt @@ -0,0 +1,17 @@ +$ 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 `std::ops::Try`) + --> src/main.rs:4:13 + | +4 | let f = File::open("hello.txt")?; + | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()` + | + = help: the trait `std::ops::Try` is not implemented for `()` + = note: required by `std::ops::Try::from_error` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `error-handling`. + +To learn more, run the command again with --verbose. diff --git a/listings/ch09-error-handling/no-listing-06-question-mark-in-main/src/main.rs b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/src/main.rs new file mode 100644 index 00000000..8608dc13 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-06-question-mark-in-main/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/no-listing-07-main-returning-result/Cargo.lock b/listings/ch09-error-handling/no-listing-07-main-returning-result/Cargo.lock new file mode 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-07-main-returning-result/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "error-handling" +version = "0.1.0" + diff --git a/listings/ch09-error-handling/no-listing-07-main-returning-result/Cargo.toml b/listings/ch09-error-handling/no-listing-07-main-returning-result/Cargo.toml new file mode 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/no-listing-07-main-returning-result/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] diff --git a/listings/ch09-error-handling/no-listing-07-main-returning-result/src/main.rs b/listings/ch09-error-handling/no-listing-07-main-returning-result/src/main.rs new file mode 100644 index 00000000..7f16b8e9 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-07-main-returning-result/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/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 100644 index 00000000..47037886 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a48daef --- /dev/null +++ b/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "error-handling" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e829724c --- /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 100644 index 00000000..2e0b103b --- /dev/null +++ b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.lock @@ -0,0 +1,89 @@ +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "guessing_game" +version = "0.1.0" +dependencies = [ + "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.53" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.53 (registry+https://github.com/rust-lang/crates.io-index)" = "ec350a9417dfd244dc9a6c4a71e13895a4db6b92f0b106f07ebbc3f3bc580cee" +"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..ad5ca696 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..0fdd8460 --- /dev/null +++ b/listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs @@ -0,0 +1,46 @@ +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); + + // 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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/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-01/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d2ba23b4 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/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-02/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9138dfcb --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/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-03/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7704ff33 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/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-04/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a7c0b6d6 --- /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.iter() { + if item > largest { + largest = item; + } + } + + largest +} + +fn largest_char(list: &[char]) -> char { + let mut largest = list[0]; + + for &item in list.iter() { + 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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/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-05/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..972e40c8 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt @@ -0,0 +1,18 @@ +$ 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 + | + = note: `T` might need a bound for `std::cmp::PartialOrd` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. +error: Could not compile `chapter10`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..1ee316bd --- /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.iter() { + 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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/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-06/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4252593d --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/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-07/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9a143a8d --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt @@ -0,0 +1,17 @@ +$ 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 + | + = note: expected type `{integer}` + found type `{float}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `chapter10`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..7883db1a --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/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-08/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..615b78cf --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/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-09/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..288b64ea --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/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-10/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4c5b01bd --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/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-11/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..622d39b2 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs @@ -0,0 +1,22 @@ +struct Point { + x: T, + y: U, +} + +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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/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-12/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..cfaedb02 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/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-13/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c4c83329 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/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-14/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fb59b84f --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/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-15/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..755f991c --- /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.iter() { + 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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/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-16/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6009860d --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/lib.rs @@ -0,0 +1,25 @@ +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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/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-17/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1cf2f459 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt @@ -0,0 +1,19 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0597]: `x` does not live long enough + --> src/main.rs:7:13 + | +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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. +error: Could not compile `chapter10`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..16adb6a0 --- /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 100644 index 00000000..6388bb2b --- /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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..65dbf375 --- /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 100644 index 00000000..6388bb2b --- /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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] 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 100644 index 00000000..94e70f00 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/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-20/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0f076a71 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/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-21/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..bef87a3a --- /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 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` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0106`. +error: Could not compile `chapter10`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..6af8c9f0 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/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-22/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..09c3a0da --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/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-23/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..836ec729 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/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-24/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..135923e3 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt @@ -0,0 +1,18 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. +error: Could not compile `chapter10`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..2a6fa589 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/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-25/Cargo.toml b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.toml new file mode 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7d138708 --- /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 100644 index 00000000..9e4e62dd --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..686de938 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "ownership" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..431a261d --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fa644ca4 --- /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 100644 index 00000000..94fb22c6 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs @@ -0,0 +1,14 @@ +use chapter10::{self, Tweet, Summary}; + +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-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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b6f93a68 --- /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 100644 index 00000000..de599f68 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs @@ -0,0 +1,15 @@ +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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..643906f6 --- /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 100644 index 00000000..94fb22c6 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs @@ -0,0 +1,14 @@ +use chapter10::{self, Tweet, Summary}; + +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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..95038433 --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..15d602c6 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs @@ -0,0 +1,40 @@ +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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "chapter10" +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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c229f949 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs @@ -0,0 +1,50 @@ +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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4cd544da --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/output.txt @@ -0,0 +1,29 @@ +$ 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.iter() { + | ----- ^^^^^^^^^^^ + | || + | |data moved here + | |move occurs because `item` has type `T`, which does not implement the `Copy` trait + | help: consider removing the `&`: `item` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0507, E0508. +For more information about an error, try `rustc --explain E0507`. +error: Could not compile `chapter10`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..0310a764 --- /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.iter() { + 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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d144305c --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..24fec3ab --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt @@ -0,0 +1,17 @@ +$ cargo run + Compiling chapter10 v0.1.0 (file:///projects/chapter10) +error[E0515]: cannot return value referencing local variable `result` + --> src/main.rs:11:5 + | +11 | result.as_str() + | ------^^^^^^^^^ + | | + | returns a value referencing data owned by the current function + | `result` is borrowed here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. +error: Could not compile `chapter10`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..aca4be0a --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b841a03e --- /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 100644 index 00000000..6388bb2b --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..6d5a0ff1 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chapter10" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..86875233 --- /dev/null +++ b/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs @@ -0,0 +1,22 @@ +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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e61930e4 --- /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 dev [unoptimized + debuginfo] target(s) in 0.22s + Running target/debug/deps/adder-c8315fb1790f5086 + +running 1 test +test tests::it_works ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..8e678421 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2c3052ef --- /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 dev [unoptimized + debuginfo] target(s) in 0.90s + Running target/debug/deps/adder-c8315fb1790f5086 + +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 + +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 100644 index 00000000..92f315ac --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs @@ -0,0 +1,16 @@ +// 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 + +fn main() {} 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 100644 index 00000000..b67fe4de --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..32efee50 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rectangle" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..aad33554 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs @@ -0,0 +1,15 @@ +// 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 + +fn main() {} 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 100644 index 00000000..b67fe4de --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..32efee50 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rectangle" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..78a2bca9 --- /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 dev [unoptimized + debuginfo] target(s) in 0.74s + Running target/debug/deps/rectangle-25efb29cecd27cb7 + +running 1 test +test tests::larger_can_hold_smaller ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests rectangle + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..f8a1f921 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs @@ -0,0 +1,28 @@ +#[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 + +fn main() {} 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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0b200e75 --- /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 dev [unoptimized + debuginfo] target(s) in 0.62s + Running target/debug/deps/adder-c8315fb1790f5086 + +running 1 test +test tests::it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..53407327 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs @@ -0,0 +1,17 @@ +// ANCHOR: here +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)); + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..3145e605 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..922762ab --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..212e28f2 --- /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 dev [unoptimized + debuginfo] target(s) in 0.56s + Running target/debug/deps/guessing_game-70eb198107cbd930 + +running 1 test +test tests::greater_than_100 ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests guessing_game + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..68e740a3 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs @@ -0,0 +1,30 @@ +// 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 + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic] + fn greater_than_100() { + Guess::new(200); + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..3145e605 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..922762ab --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d0069a89 --- /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 + +fn main() {} 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 100644 index 00000000..25c04956 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4e0f185a --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "silly-function" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d6eb90ad --- /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 dev [unoptimized + debuginfo] target(s) in 0.67s + Running target/debug/deps/silly_function-01fb9d1182907f15 + +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 + +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 100644 index 00000000..6fd76ce0 --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5d10f3bf --- /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 dev [unoptimized + debuginfo] target(s) in 0.64s + Running target/debug/deps/adder-c8315fb1790f5086 + +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 + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..f5671526 --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..800b84f5 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs @@ -0,0 +1,21 @@ +// ANCHOR: here +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)); + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/listing-11-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b719437e --- /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 dev [unoptimized + debuginfo] target(s) in 0.31s + Running target/debug/deps/adder-c8315fb1790f5086 + +running 1 test +test tests::internal ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target/debug/deps/integration_test-18ce67e0d628b336 + +running 1 test +test it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..f36aba39 --- /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)); + } +} \ No newline at end of file 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 100644 index 00000000..e26fa710 --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d23a8093 --- /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 dev [unoptimized + debuginfo] target(s) in 0.69s + Running target/debug/deps/adder-c8315fb1790f5086 + +running 1 test +test tests::exploration ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..2974d727 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +#[cfg(test)] +mod tests { + #[test] + fn exploration() { + assert_eq!(2 + 2, 4); + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..b67fe4de --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..32efee50 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rectangle" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2628c97c --- /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 dev [unoptimized + debuginfo] target(s) in 0.79s + Running target/debug/deps/rectangle-25efb29cecd27cb7 + +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 + + Doc-tests rectangle + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..c20a7315 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs @@ -0,0 +1,39 @@ +#[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 + +fn main() {} 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 100644 index 00000000..b67fe4de --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..32efee50 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "rectangle" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7207126a --- /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 dev [unoptimized + debuginfo] target(s) in 0.69s + Running target/debug/deps/rectangle-25efb29cecd27cb7 + +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:22: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 + +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 100644 index 00000000..6e065c65 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs @@ -0,0 +1,37 @@ +#[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)); + } +} + +fn main() {} 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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a6631ca5 --- /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 dev [unoptimized + debuginfo] target(s) in 0.68s + Running target/debug/deps/adder-c8315fb1790f5086 + +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 + +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 100644 index 00000000..8b4534b4 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs @@ -0,0 +1,17 @@ +// 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)); + } +} + +fn main() {} 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 100644 index 00000000..175cd34b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..c289e837 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-05-greeter/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "greeter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4fcdbbf2 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs @@ -0,0 +1,18 @@ +// ANCHOR: here +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")); + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..175cd34b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..c289e837 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "greeter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..255fc3e5 --- /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 dev [unoptimized + debuginfo] target(s) in 0.87s + Running target/debug/deps/greeter-dcea10e99a85879f + +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 + +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 100644 index 00000000..d516534e --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs @@ -0,0 +1,18 @@ +// 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")); + } +} + +fn main() {} 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 100644 index 00000000..175cd34b --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..c289e837 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "greeter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7ae6c520 --- /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 dev [unoptimized + debuginfo] target(s) in 0.90s + Running target/debug/deps/greeter-dcea10e99a85879f + +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 + +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 100644 index 00000000..bf42d36e --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs @@ -0,0 +1,19 @@ +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 100644 index 00000000..3145e605 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..922762ab --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..11376f58 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt @@ -0,0 +1,16 @@ +$ cargo test + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) + Finished dev [unoptimized + debuginfo] target(s) in 0.65s + Running target/debug/deps/guessing_game-70eb198107cbd930 + +running 1 test +test tests::greater_than_100 ... FAILED + +failures: + +failures: + tests::greater_than_100 + +test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out + +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 100644 index 00000000..54096143 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs @@ -0,0 +1,31 @@ +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); + } +} + +fn main() {} 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 100644 index 00000000..3145e605 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..922762ab --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "guessing_game" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6cb5ab61 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt @@ -0,0 +1,21 @@ +$ cargo test + Compiling guessing_game v0.1.0 (file:///projects/guessing_game) + Finished dev [unoptimized + debuginfo] target(s) in 0.93s + Running target/debug/deps/guessing_game-70eb198107cbd930 + +running 1 test +test tests::greater_than_100 ... 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:11:13 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: panic did not include expected string '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 + +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 100644 index 00000000..59e818cc --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs @@ -0,0 +1,32 @@ +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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6284f4f2 --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9a2c06cd --- /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 dev [unoptimized + debuginfo] target(s) in 0.24s + Running target/debug/deps/adder-c8315fb1790f5086 + +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 + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..9a75301e --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs @@ -0,0 +1,14 @@ +// 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 + +fn main() {} 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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..11c1ec73 --- /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 dev [unoptimized + debuginfo] target(s) in 0.89s + Running target/debug/deps/adder-c8315fb1790f5086 + +running 1 test +test tests::internal ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target/debug/deps/common-83ccd8bd71e531b5 + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target/debug/deps/integration_test-18ce67e0d628b336 + +running 1 test +test it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..f36aba39 --- /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)); + } +} \ No newline at end of file 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 100644 index 00000000..5fb7a390 --- /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 100644 index 00000000..e26fa710 --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f36aba39 --- /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)); + } +} \ No newline at end of file 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 100644 index 00000000..5fb7a390 --- /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 100644 index 00000000..58b8b7b8 --- /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 100644 index 00000000..25c04956 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4e0f185a --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-01-show-output/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "silly-function" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..caf3b074 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt @@ -0,0 +1,6 @@ +$ cargo test -- --show-output + Compiling silly-function v0.1.0 (file:///projects/silly-function) + Finished dev [unoptimized + debuginfo] target(s) in 0.61s + Running target/debug/deps/silly_function-01fb9d1182907f15 +error: Unrecognized option: 'show-output' +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 100644 index 00000000..43c4c92f --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-02-single-test/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7184d8b5 --- /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 dev [unoptimized + debuginfo] target(s) in 0.0s + Running target/debug/deps/adder-c8315fb1790f5086 + +running 1 test +test tests::one_hundred ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out + 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 100644 index 00000000..f5671526 --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..63371a44 --- /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 dev [unoptimized + debuginfo] target(s) in 0.0s + Running target/debug/deps/adder-c8315fb1790f5086 + +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 + 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 100644 index 00000000..f5671526 --- /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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8ca2c878 --- /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 dev [unoptimized + debuginfo] target(s) in 0.0s + Running target/debug/deps/adder-c8315fb1790f5086 + +running 1 test +test expensive_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out + + Doc-tests adder + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..9a75301e --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs @@ -0,0 +1,14 @@ +// 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 + +fn main() {} 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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch11-writing-automated-tests/output-only-05-single-integration/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..eed35616 --- /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 dev [unoptimized + debuginfo] target(s) in 0.0s + Running target/debug/deps/integration_test-18ce67e0d628b336 + +running 1 test +test it_adds_two ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..f36aba39 --- /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)); + } +} \ No newline at end of file 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 100644 index 00000000..e26fa710 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d0ef9981 --- /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 100644 index 00000000..aa3056de --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f759eea0 --- /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 100644 index 00000000..8daf125c --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..8daf125c --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..75e7863e --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..9a0eade5 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..fb880568 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..b5d89bc9 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8c8d53aa --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..36d35cea --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fa5d235e --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..462a16a0 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..83f46ee3 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7aad57f5 --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..c8aeb1d3 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..974b503b --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2ba70808 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-12/output.txt @@ -0,0 +1,26 @@ +$ cargo run the poem.txt + Compiling minigrep v0.1.0 (file:///projects/minigrep) +warning: unused `std::result::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 + + 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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..f2e0e6b9 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..5b2850a5 --- /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 100644 index 00000000..b2447dce --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..2ba2fd19 --- /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 100644 index 00000000..5eb4024f --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..74a92643 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-15/src/lib.rs @@ -0,0 +1,49 @@ +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 + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..673760ac --- /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 dev [unoptimized + debuginfo] target(s) in 0.43s + Running target/debug/deps/minigrep-2413544be48babd8 + +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 + +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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..a1d09a31 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-16/src/lib.rs @@ -0,0 +1,53 @@ +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) + ); + } +} + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..18513672 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-17/src/lib.rs @@ -0,0 +1,53 @@ +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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..94c59b79 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-18/src/lib.rs @@ -0,0 +1,55 @@ +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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..06e57b8e --- /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 dev [unoptimized + debuginfo] target(s) in 1.77s + Running target/debug/deps/minigrep-2413544be48babd8 + +running 1 test +test tests::one_result ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target/debug/deps/minigrep-fbafa3053caa51fd + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests minigrep + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..2e09856c --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-19/src/lib.rs @@ -0,0 +1,61 @@ +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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..6ed35e09 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-20/src/lib.rs @@ -0,0 +1,81 @@ +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 + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fd173c7b --- /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 dev [unoptimized + debuginfo] target(s) in 1.33s + Running target/debug/deps/minigrep-2413544be48babd8 + +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 + + Running target/debug/deps/minigrep-fbafa3053caa51fd + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Doc-tests minigrep + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + 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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..58fbf469 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-21/src/lib.rs @@ -0,0 +1,94 @@ +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) + ); + } +} + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..667c003a --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-22/src/lib.rs @@ -0,0 +1,103 @@ +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) + ); + } +} + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..88bf82d1 --- /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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0f0f07f7 --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..920d6747 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-23/src/lib.rs @@ -0,0 +1,108 @@ +// 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) + ); + } +} + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..10792052 --- /dev/null +++ b/listings/ch12-an-io-project/listing-12-24/src/lib.rs @@ -0,0 +1,100 @@ +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 100644 index 00000000..9e38553c --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..88df1eb2 --- /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::fs; +use std::process; +use std::error::Error; + +// 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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..91532d0c --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..79479827 --- /dev/null +++ b/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs @@ -0,0 +1,63 @@ +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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-01-with-args/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-01-with-args/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..eb88d9a9 --- /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 100644 index 00000000..aa3056de --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d3bdcbc3 --- /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 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` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0106`. +error: Could not compile `minigrep`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..8a12ac2f --- /dev/null +++ b/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs @@ -0,0 +1,53 @@ +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) + ); + } +} + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c0ab7efd --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..79479827 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs @@ -0,0 +1,63 @@ +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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4cd6c8a0 --- /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 100644 index 00000000..208e35a5 --- /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 100644 index 00000000..79479827 --- /dev/null +++ b/listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs @@ -0,0 +1,63 @@ +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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-reproduced/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..87075273 --- /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 100644 index 00000000..936aeac2 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-23-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, +} + +// 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) + ); + } +} + +fn main() {} 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 100644 index 00000000..53af83fd --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..87075273 --- /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 100644 index 00000000..10792052 --- /dev/null +++ b/listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs @@ -0,0 +1,100 @@ +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 100644 index 00000000..ec27e67f --- /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.toml b/listings/ch13-functional-features/listing-13-01/Cargo.toml new file mode 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..97eace01 --- /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 100644 index 00000000..f2ba2742 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..30827264 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-02/src/main.rs @@ -0,0 +1,22 @@ +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 100644 index 00000000..f2ba2742 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..509f98cb --- /dev/null +++ b/listings/ch13-functional-features/listing-13-03/src/main.rs @@ -0,0 +1,42 @@ +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 100644 index 00000000..f2ba2742 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..95deed3f --- /dev/null +++ b/listings/ch13-functional-features/listing-13-04/src/main.rs @@ -0,0 +1,45 @@ +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 100644 index 00000000..f2ba2742 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c30eff59 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-05/src/main.rs @@ -0,0 +1,42 @@ +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 100644 index 00000000..f2ba2742 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..66c2e770 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-06/src/main.rs @@ -0,0 +1,42 @@ +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 100644 index 00000000..f2ba2742 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..70e3c438 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-07/src/main.rs @@ -0,0 +1,42 @@ +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 100644 index 00000000..f38db09f --- /dev/null +++ b/listings/ch13-functional-features/listing-13-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..54b904e4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "closure-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..df271575 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-08/output.txt @@ -0,0 +1,20 @@ +$ 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); + | ^ + | | + | expected struct `std::string::String`, found integer + | help: try using a conversion method: `5.to_string()` + | + = note: expected type `std::string::String` + found type `{integer}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `closure-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..ebb2489b --- /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 100644 index 00000000..d42a3257 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..54ab6f21 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cacher" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..79be866c --- /dev/null +++ b/listings/ch13-functional-features/listing-13-09/src/main.rs @@ -0,0 +1,10 @@ +// 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 100644 index 00000000..d42a3257 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..54ab6f21 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cacher" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..29f47ac1 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-10/src/main.rs @@ -0,0 +1,32 @@ +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 100644 index 00000000..f2ba2742 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8e64540e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "workout-app" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..45cf2fbe --- /dev/null +++ b/listings/ch13-functional-features/listing-13-11/src/main.rs @@ -0,0 +1,71 @@ +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 100644 index 00000000..f46a603e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4fd5d852 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "equal-to-x" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7352b80b --- /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 100644 index 00000000..2e7cf8a4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..015f9512 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "iterators" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..55a0dd37 --- /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 100644 index 00000000..2e7cf8a4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..015f9512 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "iterators" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..712aff40 --- /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 100644 index 00000000..2e7cf8a4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..015f9512 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "iterators" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..afea80d2 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-15/src/lib.rs @@ -0,0 +1,18 @@ +#[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 +} + +fn main() {} 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 100644 index 00000000..2e7cf8a4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..015f9512 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "iterators" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..198b3c83 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-16/src/lib.rs @@ -0,0 +1,17 @@ +#[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 +} + +fn main() {} 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 100644 index 00000000..2e7cf8a4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..015f9512 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "iterators" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..dcf903d5 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-17/output.txt @@ -0,0 +1,13 @@ +$ cargo run + Compiling iterators v0.1.0 (file:///projects/iterators) +warning: unused `std::iter::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 + + 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 100644 index 00000000..62a68be9 --- /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 100644 index 00000000..2e7cf8a4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..015f9512 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "iterators" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..db9025d6 --- /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 100644 index 00000000..f5ca1b91 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..d0ecdac6 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shoe_size" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a8b5cb55 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-19/src/lib.rs @@ -0,0 +1,37 @@ +#[derive(PartialEq, Debug)] +struct Shoe { + size: u32, + style: String, +} + +fn shoes_in_my_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_my_size(shoes, 10); + + assert_eq!( + in_my_size, + vec![ + Shoe { size: 10, style: String::from("sneaker") }, + Shoe { size: 10, style: String::from("boot") }, + ] + ); + } +} + +fn main() {} 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 100644 index 00000000..da4124d8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4eb29e80 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "counter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..897804c4 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-20/src/lib.rs @@ -0,0 +1,11 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +fn main() {} 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 100644 index 00000000..da4124d8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4eb29e80 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "counter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..76de1b7a --- /dev/null +++ b/listings/ch13-functional-features/listing-13-21/src/lib.rs @@ -0,0 +1,27 @@ +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 { + self.count += 1; + + if self.count < 6 { + Some(self.count) + } else { + None + } + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..da4124d8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4eb29e80 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "counter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0b85a9e6 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-22/src/lib.rs @@ -0,0 +1,44 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +impl Iterator for Counter { + type Item = u32; + + fn next(&mut self) -> Option { + self.count += 1; + + if self.count < 6 { + 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 +} + +fn main() {} 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 100644 index 00000000..da4124d8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-23/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4eb29e80 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "counter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ec8593bb --- /dev/null +++ b/listings/ch13-functional-features/listing-13-23/src/lib.rs @@ -0,0 +1,53 @@ +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +impl Iterator for Counter { + type Item = u32; + + fn next(&mut self) -> Option { + self.count += 1; + + if self.count < 6 { + 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 +} + +fn main() {} 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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..87075273 --- /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 100644 index 00000000..10792052 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-25/src/lib.rs @@ -0,0 +1,100 @@ +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 100644 index 00000000..d09966e4 --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..87075273 --- /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 100644 index 00000000..e980f44e --- /dev/null +++ b/listings/ch13-functional-features/listing-13-26/src/lib.rs @@ -0,0 +1,103 @@ +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: std::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 100644 index 00000000..06aac30e --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..87075273 --- /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 100644 index 00000000..b56edf51 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-27/src/lib.rs @@ -0,0 +1,109 @@ +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: 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 }) + } +} +// 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) + ); + } +} + +fn main() {} 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 100644 index 00000000..06aac30e --- /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 100644 index 00000000..5b5afdd8 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..82606426 --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "minigrep" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..87075273 --- /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 100644 index 00000000..555d797f --- /dev/null +++ b/listings/ch13-functional-features/listing-13-29/src/lib.rs @@ -0,0 +1,101 @@ +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 100644 index 00000000..06aac30e --- /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 100644 index 00000000..d42a3257 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..54ab6f21 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cacher" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..096203fc --- /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 dev [unoptimized + debuginfo] target(s) in 0.61s + Running target/debug/deps/cacher-a6183d86a6fe7833 + +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:41: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 + +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 100644 index 00000000..4ec6d9bf --- /dev/null +++ b/listings/ch13-functional-features/no-listing-01-failing-cacher-test/src/lib.rs @@ -0,0 +1,45 @@ +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 100644 index 00000000..f46a603e --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4fd5d852 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "equal-to-x" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..27886a95 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/output.txt @@ -0,0 +1,16 @@ +$ 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:4:42 + | +4 | fn equal_to_x(z: i32) -> bool { z == x } + | ^ + | + = help: use the `|| { ... }` closure form instead + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0434`. +error: Could not compile `equal-to-x`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..032ecc88 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-02-functions-cant-capture/src/main.rs @@ -0,0 +1,9 @@ +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 100644 index 00000000..f46a603e --- /dev/null +++ b/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4fd5d852 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-03-move-closures/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "equal-to-x" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8d4b1a49 --- /dev/null +++ b/listings/ch13-functional-features/no-listing-03-move-closures/output.txt @@ -0,0 +1,22 @@ +$ 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 `std::vec::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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. +error: Could not compile `equal-to-x`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..19d47760 --- /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 100644 index 00000000..b304dd7c --- /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 100644 index 00000000..716953ae --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "my_crate" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ed7abb72 --- /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 100644 index 00000000..764f4fe4 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..716953ae --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "my_crate" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..64c9c439 --- /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 100644 index 00000000..21233541 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..a2e9e369 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "art" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..00a81c50 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-03/src/lib.rs @@ -0,0 +1,36 @@ +// 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 + SecondaryColor::Orange + // ANCHOR: here + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..21233541 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..a2e9e369 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "art" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b077a9a7 --- /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 100644 index 00000000..b1a4bf79 --- /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 100644 index 00000000..21233541 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..a2e9e369 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "art" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c5aa9e7b --- /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 100644 index 00000000..21233541 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..a2e9e369 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "art" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..daabd006 --- /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 100644 index 00000000..4b6e112a --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-06/src/main.rs @@ -0,0 +1,13 @@ +// ANCHOR: here +use art::PrimaryColor; +use art::mix; + +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 100644 index 00000000..77292f61 --- /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 100644 index 00000000..d26e7cfb --- /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 100644 index 00000000..8260fb54 --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/add-one/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "add-one" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b0bb8694 --- /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 100644 index 00000000..e73f1bec --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/adder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..cec9a65c --- /dev/null +++ b/listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs @@ -0,0 +1,6 @@ +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 100644 index 00000000..4fb18f93 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..c5ea8e51 --- /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 100644 index 00000000..0e3940cf --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e7a11a96 --- /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 100644 index 00000000..be803f31 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.lock @@ -0,0 +1,8 @@ +[[package]] +name = "add-one" +version = "0.1.0" + +[[package]] +name = "adder" +version = "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 100644 index 00000000..d26e7cfb --- /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 100644 index 00000000..8260fb54 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add-one/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "add-one" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b0bb8694 --- /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 100644 index 00000000..e73f1bec --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e7a11a96 --- /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 100644 index 00000000..f17f35e8 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/Cargo.lock @@ -0,0 +1,94 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add-one" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add-one 0.1.0", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..d26e7cfb --- /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 100644 index 00000000..5b52051a --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add-one/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "add-one" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..7b61b40a --- /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 100644 index 00000000..e73f1bec --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..cec9a65c --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs @@ -0,0 +1,6 @@ +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 100644 index 00000000..77292f61 --- /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 100644 index 00000000..d26e7cfb --- /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 100644 index 00000000..8260fb54 --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add-one/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "add-one" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..40ceb128 --- /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 100644 index 00000000..e73f1bec --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..cec9a65c --- /dev/null +++ b/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs @@ -0,0 +1,6 @@ +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 100644 index 00000000..b46d5c46 --- /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.toml b/listings/ch14-more-about-cargo/output-only-01-adder-crate/add/Cargo.toml new file mode 100644 index 00000000..c5ea8e51 --- /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-02-add-one/add/.gitignore b/listings/ch14-more-about-cargo/output-only-02-add-one/add/.gitignore new file mode 100644 index 00000000..64904e06 --- /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 100644 index 00000000..be803f31 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/Cargo.lock @@ -0,0 +1,8 @@ +[[package]] +name = "add-one" +version = "0.1.0" + +[[package]] +name = "adder" +version = "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 100644 index 00000000..d26e7cfb --- /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/add-one/Cargo.toml b/listings/ch14-more-about-cargo/output-only-02-add-one/add/add-one/Cargo.toml new file mode 100644 index 00000000..602f686d --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/add-one/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "add-one" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/listings/ch14-more-about-cargo/output-only-02-add-one/add/add-one/src/lib.rs b/listings/ch14-more-about-cargo/output-only-02-add-one/add/add-one/src/lib.rs new file mode 100644 index 00000000..31e1bb20 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/add-one/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + assert_eq!(2 + 2, 4); + } +} 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 100644 index 00000000..e73f1bec --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e7a11a96 --- /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 100644 index 00000000..f17f35e8 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/Cargo.lock @@ -0,0 +1,94 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add-one" +version = "0.1.0" +dependencies = [ + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "adder" +version = "0.1.0" +dependencies = [ + "add-one 0.1.0", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +"checksum libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)" = "c6785aa7dd976f5fbf3b71cfd9cd49d7f783c1ff565a858d71031c6c313aa5c6" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 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 100644 index 00000000..d26e7cfb --- /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 100644 index 00000000..5b52051a --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/add-one/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "add-one" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] +rand = "0.5.5" 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 100644 index 00000000..7b61b40a --- /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 100644 index 00000000..e73f1bec --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "adder" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d08f1e59 --- /dev/null +++ b/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs @@ -0,0 +1,7 @@ +use rand; +use add_one; + +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 100644 index 00000000..9307e308 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4a0bb9d2 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "box-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8da1d905 --- /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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..84640b9b --- /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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b7d5c225 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-03/output.txt @@ -0,0 +1,28 @@ +$ 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 indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable + +error[E0391]: cycle detected when processing `List` + --> src/main.rs:1:1 + | +1 | enum List { + | ^^^^^^^^^ + | + = note: ...which again requires processing `List`, completing the cycle + = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, def_id: None }, value: List } }` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0072, E0391. +For more information about an error, try `rustc --explain E0072`. +error: Could not compile `cons-list`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..a96f3d7b --- /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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a3f6c19f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-05/src/main.rs @@ -0,0 +1,13 @@ +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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..174b620c --- /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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4933a416 --- /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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8cbf312d --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-08/src/main.rs @@ -0,0 +1,12 @@ +// 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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c2155186 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-09/output.txt @@ -0,0 +1,14 @@ +$ 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); + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0614`. +error: Could not compile `deref-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..d07f2d78 --- /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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a97f97c9 --- /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) -> &T { + &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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..76ffd531 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-11/src/main.rs @@ -0,0 +1,8 @@ +// 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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6a3e143c --- /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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ef5361c1 --- /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 100644 index 00000000..ba50249f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e9ad457c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "drop-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4e795949 --- /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 100644 index 00000000..c5b1bb0c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-14/src/main.rs @@ -0,0 +1,15 @@ +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 100644 index 00000000..ba50249f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e9ad457c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "drop-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..30dd9958 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/output.txt @@ -0,0 +1,14 @@ +$ cargo run + Compiling drop-example v0.1.0 (file:///projects/drop-example) +error[E0040]: explicit use of destructor method + --> src/main.rs:14:7 + | +14 | c.drop(); + | ^^^^ explicit destructor calls not allowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0040`. +error: Could not compile `drop-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..212d3611 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-15/src/main.rs @@ -0,0 +1,18 @@ +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 100644 index 00000000..ba50249f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e9ad457c --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "drop-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e960cd89 --- /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 100644 index 00000000..c31fd3aa --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-16/src/main.rs @@ -0,0 +1,18 @@ +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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7b3cda4b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/output.txt @@ -0,0 +1,19 @@ +$ cargo run + Compiling cons-list v0.1.0 (file:///projects/cons-list) +error[E0382]: use of moved value: `a` + --> src/main.rs:13:30 + | +9 | let a = Cons(5, + | - move occurs because `a` has type `List`, which does not implement the `Copy` trait +... +12 | let b = Cons(3, Box::new(a)); + | - value moved here +13 | let c = Cons(4, Box::new(a)); + | ^ value used here after move + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. +error: Could not compile `cons-list`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..a9998113 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-17/src/main.rs @@ -0,0 +1,14 @@ +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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..602f7de4 --- /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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6a8cc8ef --- /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 100644 index 00000000..1bd7bc53 --- /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 100644 index 00000000..dd45b536 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b230a232 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f229e8a7 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-20/src/lib.rs @@ -0,0 +1,34 @@ +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 100644 index 00000000..dd45b536 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b230a232 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..80719191 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/output.txt @@ -0,0 +1,16 @@ +$ 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:52:13 + | +51 | fn send(&self, message: &str) { + | ----- help: consider changing this to be a mutable reference: `&mut self` +52 | self.sent_messages.push(String::from(message)); + | ^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. +error: Could not compile `limit-tracker`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..7f84c7be --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-21/src/lib.rs @@ -0,0 +1,67 @@ +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 100644 index 00000000..dd45b536 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b230a232 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ac2298cf --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-22/src/lib.rs @@ -0,0 +1,74 @@ +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 + +fn main() {} 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 100644 index 00000000..dd45b536 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-23/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..b230a232 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "limit-tracker" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..332995aa --- /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 dev [unoptimized + debuginfo] target(s) in 0.82s + Running target/debug/deps/limit_tracker-54dba9352a1db13d + +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/libcore/result.rs:999:5 +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 + +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 100644 index 00000000..64065e1b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-23/src/lib.rs @@ -0,0 +1,72 @@ +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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-24/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-24/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..bfe217bf --- /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: 6 }, Cons(RefCell { value: 15 }, Nil)) +c after = Cons(RefCell { value: 10 }, 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 100644 index 00000000..cd3717fc --- /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::rc::Rc; +use std::cell::RefCell; + +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(6)), Rc::clone(&a)); + let c = Cons(Rc::new(RefCell::new(10)), 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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-25/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-25/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3829d0bd --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-25/src/main.rs @@ -0,0 +1,20 @@ +use std::rc::Rc; +use std::cell::RefCell; +use crate::List::{Cons, Nil}; + +#[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 100644 index 00000000..94cd138b --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-26/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..86c8e956 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-26/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "cons-list" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8b8eb40b --- /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 100644 index 00000000..128c4626 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-26/src/main.rs @@ -0,0 +1,44 @@ +use std::rc::Rc; +use std::cell::RefCell; +use crate::List::{Cons, Nil}; + +#[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 100644 index 00000000..955b7e0f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-27/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..d6774b81 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-27/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "tree" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8bd71f92 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-27/src/main.rs @@ -0,0 +1,24 @@ +// ANCHOR: here +use std::rc::Rc; +use std::cell::RefCell; + +#[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 100644 index 00000000..955b7e0f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-28/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..d6774b81 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-28/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "tree" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3181f591 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-28/src/main.rs @@ -0,0 +1,33 @@ +// ANCHOR: here +use std::rc::{Rc, Weak}; +use std::cell::RefCell; + +#[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 100644 index 00000000..955b7e0f --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-29/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..d6774b81 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-29/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "tree" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b87447d5 --- /dev/null +++ b/listings/ch15-smart-pointers/listing-15-29/src/main.rs @@ -0,0 +1,54 @@ +use std::rc::{Rc, Weak}; +use std::cell::RefCell; + +#[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 100644 index 00000000..3c5deedf --- /dev/null +++ b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1558eb61 --- /dev/null +++ b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "borrowing" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d28ea466 --- /dev/null +++ b/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt @@ -0,0 +1,16 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`. +error: Could not compile `borrowing`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..8f48d41c --- /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 100644 index 00000000..4d76558f --- /dev/null +++ b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2a9630fe --- /dev/null +++ b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "deref-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..ca43de24 --- /dev/null +++ b/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt @@ -0,0 +1,17 @@ +$ 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 `std::cmp::PartialEq<&{integer}>` is not implemented for `{integer}` + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `deref-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..4e20cae0 --- /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 100644 index 00000000..4685c131 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..68a31e10 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "threads" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6305a98e --- /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 100644 index 00000000..4685c131 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..68a31e10 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "threads" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e37607f1 --- /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 100644 index 00000000..4685c131 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..68a31e10 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "threads" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4eb76cc4 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-03/output.txt @@ -0,0 +1,29 @@ +$ 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 || { + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0373`. +error: Could not compile `threads`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..defc8764 --- /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 100644 index 00000000..4685c131 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..68a31e10 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "threads" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0bccc5f5 --- /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 100644 index 00000000..4685c131 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..68a31e10 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "threads" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a6547dc4 --- /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 100644 index 00000000..dfa06e2a --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8fd8808e --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "message-passing" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d80dac4a --- /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 100644 index 00000000..dfa06e2a --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8fd8808e --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "message-passing" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..40da8014 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-07/src/main.rs @@ -0,0 +1,11 @@ +use std::thread; +use std::sync::mpsc; + +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 100644 index 00000000..dfa06e2a --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8fd8808e --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "message-passing" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..bd950652 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-08/src/main.rs @@ -0,0 +1,14 @@ +use std::thread; +use std::sync::mpsc; + +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 100644 index 00000000..dfa06e2a --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8fd8808e --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "message-passing" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..244f4462 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/output.txt @@ -0,0 +1,18 @@ +$ 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 `std::string::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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. +error: Could not compile `message-passing`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..1d87a5ef --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-09/src/main.rs @@ -0,0 +1,15 @@ +use std::thread; +use std::sync::mpsc; + +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 100644 index 00000000..dfa06e2a --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8fd8808e --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "message-passing" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fb0b042f --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-10/src/main.rs @@ -0,0 +1,25 @@ +use std::thread; +use std::sync::mpsc; +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 100644 index 00000000..dfa06e2a --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..8fd8808e --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "message-passing" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..be335c47 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-11/src/main.rs @@ -0,0 +1,46 @@ +use std::thread; +use std::sync::mpsc; +use std::time::Duration; + +fn main() { + // ANCHOR: here + // --snip-- + + let (tx, rx) = mpsc::channel(); + + let tx1 = mpsc::Sender::clone(&tx); + 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 100644 index 00000000..c834c230 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e7c75ac9 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shared-state" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0c0d6767 --- /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 100644 index 00000000..c834c230 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e7c75ac9 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shared-state" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b86048b9 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-13/output.txt @@ -0,0 +1,19 @@ +$ 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 `std::sync::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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. +error: Could not compile `shared-state`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..4e380a59 --- /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 100644 index 00000000..c834c230 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e7c75ac9 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shared-state" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..04ccf50d --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-14/output.txt @@ -0,0 +1,18 @@ +$ cargo run + Compiling shared-state v0.1.0 (file:///projects/shared-state) +error[E0277]: `std::rc::Rc>` cannot be sent between threads safely + --> src/main.rs:11:22 + | +11 | let handle = thread::spawn(move || { + | ^^^^^^^^^^^^^ `std::rc::Rc>` cannot be sent between threads safely + | + = help: within `[closure@src/main.rs:11:36: 15:10 counter:std::rc::Rc>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc>` + = note: required because it appears within the type `[closure@src/main.rs:11:36: 15:10 counter:std::rc::Rc>]` + = note: required by `std::thread::spawn` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `shared-state`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..d940b1a3 --- /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 100644 index 00000000..c834c230 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e7c75ac9 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shared-state" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..589c6b47 --- /dev/null +++ b/listings/ch16-fearless-concurrency/listing-16-15/src/main.rs @@ -0,0 +1,23 @@ +use std::sync::{Mutex, Arc}; +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 100644 index 00000000..4685c131 --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..68a31e10 --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "threads" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6205e57d --- /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 100644 index 00000000..c834c230 --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..e7c75ac9 --- /dev/null +++ b/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "shared-state" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..dbb13977 --- /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 100644 index 00000000..4685c131 --- /dev/null +++ b/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..68a31e10 --- /dev/null +++ b/listings/ch16-fearless-concurrency/output-only-01-move-drop/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "threads" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..099fae22 --- /dev/null +++ b/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt @@ -0,0 +1,22 @@ +$ 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 `std::vec::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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. +error: Could not compile `threads`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..70f659c5 --- /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 100644 index 00000000..620ef985 --- /dev/null +++ b/listings/ch17-oop/listing-17-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..ab96488d --- /dev/null +++ b/listings/ch17-oop/listing-17-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "averaged-collection" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b5ce2ab6 --- /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 100644 index 00000000..620ef985 --- /dev/null +++ b/listings/ch17-oop/listing-17-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..ab96488d --- /dev/null +++ b/listings/ch17-oop/listing-17-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "averaged-collection" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..57812324 --- /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.toml b/listings/ch17-oop/listing-17-03/Cargo.toml new file mode 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3a5cb779 --- /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 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/listing-17-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0c45e2a6 --- /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 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/listing-17-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..57ebb578 --- /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 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/listing-17-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1abe6ea3 --- /dev/null +++ b/listings/ch17-oop/listing-17-06/src/lib.rs @@ -0,0 +1,18 @@ +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 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/listing-17-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..413dc6ff --- /dev/null +++ b/listings/ch17-oop/listing-17-07/src/lib.rs @@ -0,0 +1,31 @@ +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 + +fn main() {} diff --git a/listings/ch17-oop/listing-17-08/Cargo.lock b/listings/ch17-oop/listing-17-08/Cargo.lock new file mode 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/listing-17-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..960fee23 --- /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 100644 index 00000000..9575d407 --- /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 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/listing-17-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..960fee23 --- /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 100644 index 00000000..ff06f65b --- /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::{Screen, Button}; + +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 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/listing-17-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/listing-17-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] diff --git a/listings/ch17-oop/listing-17-10/output.txt b/listings/ch17-oop/listing-17-10/output.txt new file mode 100644 index 00000000..5faf3ef4 --- /dev/null +++ b/listings/ch17-oop/listing-17-10/output.txt @@ -0,0 +1,16 @@ +$ cargo run + Compiling gui v0.1.0 (file:///projects/gui) +error[E0277]: the trait bound `std::string::String: gui::Draw` is not satisfied + --> src/main.rs:6:13 + | +6 | Box::new(String::from("Hi")), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `gui::Draw` is not implemented for `std::string::String` + | + = note: required for the cast to the object type `dyn gui::Draw` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `gui`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..960fee23 --- /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 100644 index 00000000..a8485dee --- /dev/null +++ b/listings/ch17-oop/listing-17-10/src/main.rs @@ -0,0 +1,11 @@ +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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d99170a9 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b8156c39 --- /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 100644 index 00000000..14b4c082 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0ae3fa6e --- /dev/null +++ b/listings/ch17-oop/listing-17-13/src/lib.rs @@ -0,0 +1,30 @@ +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 {} + +fn main() {} 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 100644 index 00000000..14b4c082 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0d010f50 --- /dev/null +++ b/listings/ch17-oop/listing-17-14/src/lib.rs @@ -0,0 +1,34 @@ +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 {} + +fn main() {} 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 100644 index 00000000..14b4c082 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..806b4e49 --- /dev/null +++ b/listings/ch17-oop/listing-17-15/src/lib.rs @@ -0,0 +1,54 @@ +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 + +fn main() {} 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 100644 index 00000000..14b4c082 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..92cb2981 --- /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 100644 index 00000000..14b4c082 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e514cea8 --- /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 + } +} \ No newline at end of file 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 100644 index 00000000..14b4c082 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1bac8a87 --- /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 100644 index 00000000..14b4c082 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..bfe034ea --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3b82ec05 --- /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 100644 index 00000000..8e793866 --- /dev/null +++ b/listings/ch17-oop/listing-17-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9a395e23 --- /dev/null +++ b/listings/ch17-oop/listing-17-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "blog" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..38500a65 --- /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 100644 index 00000000..720c55e6 --- /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/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.lock b/listings/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.lock new file mode 100644 index 00000000..7f58b0ba --- /dev/null +++ b/listings/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "gui" +version = "0.1.0" + diff --git a/listings/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.toml b/listings/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.toml new file mode 100644 index 00000000..1f61cd20 --- /dev/null +++ b/listings/ch17-oop/no-listing-01-trait-object-of-clone/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "gui" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[dependencies] diff --git a/listings/ch17-oop/no-listing-01-trait-object-of-clone/output.txt b/listings/ch17-oop/no-listing-01-trait-object-of-clone/output.txt new file mode 100644 index 00000000..6e4cf3c5 --- /dev/null +++ b/listings/ch17-oop/no-listing-01-trait-object-of-clone/output.txt @@ -0,0 +1,16 @@ +$ cargo build + Compiling gui v0.1.0 (file:///projects/gui) +error[E0038]: the trait `std::clone::Clone` cannot be made into an object + --> src/lib.rs:2:5 + | +2 | pub components: Vec>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` cannot be made into an object + | + = note: the trait cannot require that `Self : Sized` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. +error: Could not compile `gui`. + +To learn more, run the command again with --verbose. diff --git a/listings/ch17-oop/no-listing-01-trait-object-of-clone/src/lib.rs b/listings/ch17-oop/no-listing-01-trait-object-of-clone/src/lib.rs new file mode 100644 index 00000000..e6b1a37f --- /dev/null +++ b/listings/ch17-oop/no-listing-01-trait-object-of-clone/src/lib.rs @@ -0,0 +1,3 @@ +pub struct Screen { + pub components: Vec>, +} 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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d28c369f --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5f75a4f2 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..02fdecbf --- /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 100644 index 00000000..eb922d62 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..27b0c3fb --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d0935450 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-05/output.txt @@ -0,0 +1,17 @@ +$ 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); + | ^^^^^^ expected a tuple with 3 elements, found one with 2 elements + | + = note: expected type `({integer}, {integer}, {integer})` + found type `(_, _)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. +error: Could not compile `patterns`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..39f768e2 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c5d71e6c --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4eccb808 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5fac6714 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-08/output.txt @@ -0,0 +1,14 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0005`. +error: Could not compile `patterns`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..7baa02a4 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d6274fc0 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..263de395 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-10/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling patterns v0.1.0 (file:///projects/patterns) +warning: irrefutable if-let pattern + --> src/main.rs:2:5 + | +2 | / if let x = 5 { +3 | | println!("{}", x); +4 | | }; + | |_____^ + | + = note: #[warn(irrefutable_let_patterns)] on by default + + 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 100644 index 00000000..cb81772e --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..25eaa79f --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..62f4ccbf --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..5badc159 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8d445d9b --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..259aaca8 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs @@ -0,0 +1,32 @@ +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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..61757a36 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs @@ -0,0 +1,35 @@ +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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..cf1fbe07 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b776c64c --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4bc1ff54 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1ffc46ba --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..98061050 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e2faa345 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7a9d9bb3 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-24/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8490bdd5 --- /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 100644 index 00000000..a233623e --- /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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-25/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..032b3dc0 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-25/output.txt @@ -0,0 +1,15 @@ +$ cargo run + Compiling patterns v0.1.0 (file:///projects/patterns) +error: `..` can only be used once per tuple or tuple struct pattern + --> src/main.rs:5:22 + | +5 | (.., second, ..) => { + | -- ^^ can only be used once per pattern + | | + | previously present here + +error: aborting due to previous error + +error: Could not compile `patterns`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..b90884eb --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-26/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4ec86cba --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-27/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..348e3672 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-28/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..15804553 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-29/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f5b87399 --- /dev/null +++ b/listings/ch18-patterns-and-matching/listing-18-29/src/main.rs @@ -0,0 +1,21 @@ +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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7978e1ad --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e52d815d --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a3ebe7af --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8cebfef5 --- /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 100644 index 00000000..a233623e --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..f77be077 --- /dev/null +++ b/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "patterns" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..67f98ed4 --- /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 100644 index 00000000..da4124d8 --- /dev/null +++ b/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..4eb29e80 --- /dev/null +++ b/listings/ch19-advanced-features/listing-13-21-reproduced/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "counter" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..0e65a017 --- /dev/null +++ b/listings/ch19-advanced-features/listing-13-21-reproduced/src/lib.rs @@ -0,0 +1,28 @@ +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 + self.count += 1; + + if self.count < 6 { + Some(self.count) + } else { + None + } + } +} + +fn main() {} 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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..893f5789 --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..849629a7 --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..02a0be6b --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6ac58442 --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9486066e --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/output.txt @@ -0,0 +1,23 @@ +$ 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:7:11 + | +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], + | - ----- first mutable borrow occurs here + | _____| + | | +7 | | &mut slice[mid..]) + | |___________^^^^^_______- returning this value requires that `*slice` is borrowed for `'1` + | | + | second mutable borrow occurs here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0499`. +error: Could not compile `unsafe-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..549fcfab --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-05/src/main.rs @@ -0,0 +1,15 @@ +// 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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f53f0000 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-06/src/main.rs @@ -0,0 +1,20 @@ +// 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.offset(mid as isize), 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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c5586a28 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-07/src/main.rs @@ -0,0 +1,12 @@ +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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8b56630c --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..82a4b421 --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e8dab68e --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..885c1aa1 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..dbe04620 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7c9479c5 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..89f35727 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-14/src/main.rs @@ -0,0 +1,23 @@ +use std::ops::Add; + +#[derive(Debug, 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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..f38bf475 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d854e287 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..3df65a7c --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..2e9da17d --- /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 100644 index 00000000..fa01c09c --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..087e802b --- /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 100644 index 00000000..44affe0e --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-20/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..cc5b9770 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-20/output.txt @@ -0,0 +1,20 @@ +$ cargo run + Compiling traits-example v0.1.0 (file:///projects/traits-example) +error[E0283]: type annotations required: cannot resolve `_: Animal` + --> src/main.rs:20:43 + | +20 | println!("A baby dog is called a {}", Animal::baby_name()); + | ^^^^^^^^^^^^^^^^^ + | +note: required by `Animal::baby_name` + --> src/main.rs:2:5 + | +2 | fn baby_name() -> String; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. +error: Could not compile `traits-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..8e295c9b --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..4d1ee5ab --- /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 100644 index 00000000..b1df7289 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..febe58b0 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-23/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..eae46c92 --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-24/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-24/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..20f26fce --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-25/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-25/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..af35bed2 --- /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 100644 index 00000000..5f4173e1 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-27/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2bed56c3 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-27/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..91b2cf04 --- /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 100644 index 00000000..7b92445e --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-28/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1829b0fa --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-28/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "macros-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..7c7c4756 --- /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 100644 index 00000000..be8c994f --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-30/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..5a93a685 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-30/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello_macro" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..468c30aa --- /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 100644 index 00000000..be8c994f --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..5a93a685 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello_macro" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..56396d13 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.lock @@ -0,0 +1,44 @@ +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" +"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 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 100644 index 00000000..a6df8313 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +syn = "0.14.4" +quote = "0.6.3" 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 100644 index 00000000..a295f37c --- /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 crate::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 100644 index 00000000..e7479318 --- /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 100644 index 00000000..10b028b2 --- /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 100644 index 00000000..be8c994f --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..5a93a685 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello_macro" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..56396d13 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.lock @@ -0,0 +1,44 @@ +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" +"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 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 100644 index 00000000..a6df8313 --- /dev/null +++ b/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +syn = "0.14.4" +quote = "0.6.3" 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 100644 index 00000000..9d3f10bd --- /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 crate::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 100644 index 00000000..e7479318 --- /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 100644 index 00000000..10b028b2 --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..21ecdbe5 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..429bf9d5 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt @@ -0,0 +1,17 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. +error: Could not compile `traits-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..a1e2fe4c --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c7bbb6a7 --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d3fe32e2 --- /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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..00de3f0b --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-05-write-trait/src/lib.rs @@ -0,0 +1,10 @@ +use std::io::Error; +use std::fmt; + +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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c53a927e --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-06-result-alias/src/lib.rs @@ -0,0 +1,17 @@ +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 + +fn main() {} 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 100644 index 00000000..71ae580c --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..1e3df024 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "traits-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..23622418 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-07-never-type/src/lib.rs @@ -0,0 +1,10 @@ +// ANCHOR: here +fn bar() -> ! { + // --snip-- + // ANCHOR_END: here + panic!(); + // ANCHOR: here +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..6d56008a --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..aa4f937f --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e7768913 --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..075d5110 --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..69186ddf --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c2d00e21 --- /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 100644 index 00000000..7380c3c9 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..9b4ee689 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "types-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e4722267 --- /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 100644 index 00000000..5f4173e1 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2bed56c3 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-15-map-closure/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..9372c0de --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-15-map-closure/src/main.rs @@ -0,0 +1,9 @@ +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 100644 index 00000000..5f4173e1 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2bed56c3 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..66d50f89 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-16-map-function/src/main.rs @@ -0,0 +1,9 @@ +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 100644 index 00000000..5f4173e1 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2bed56c3 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..a237e424 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs @@ -0,0 +1,13 @@ +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 100644 index 00000000..5f4173e1 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2bed56c3 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..8c897e53 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt @@ -0,0 +1,30 @@ +$ cargo build + Compiling functions-example v0.1.0 (file:///projects/functions-example) +error[E0277]: the size for values of type `(dyn std::ops::Fn(i32) -> i32 + 'static)` cannot be known at compilation time + --> src/lib.rs:1:25 + | +1 | fn returns_closure() -> dyn Fn(i32) -> i32 { + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `(dyn std::ops::Fn(i32) -> i32 + 'static)` + = note: to learn more, visit + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> src/lib.rs:2:5 + | +1 | fn returns_closure() -> dyn Fn(i32) -> i32 { + | ------------------ expected `(dyn std::ops::Fn(i32) -> i32 + 'static)` because of return type +2 | |x| x + 1 + | ^^^^^^^^^ expected trait std::ops::Fn, found closure + | + = note: expected type `(dyn std::ops::Fn(i32) -> i32 + 'static)` + found type `[closure@src/lib.rs:2:5: 2:14]` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. +error: Could not compile `functions-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..d699ac34 --- /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 100644 index 00000000..5f4173e1 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..2bed56c3 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "functions-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..b1140774 --- /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 100644 index 00000000..be8c994f --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..5a93a685 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello_macro" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..e7479318 --- /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 100644 index 00000000..757fb877 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.lock @@ -0,0 +1,11 @@ +[[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 100644 index 00000000..4b6c267b --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "pancakes" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..10b028b2 --- /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 100644 index 00000000..be8c994f --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..5a93a685 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello_macro" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..56396d13 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.lock @@ -0,0 +1,44 @@ +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" +"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 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 100644 index 00000000..a6df8313 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "hello_macro_derive" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +syn = "0.14.4" +quote = "0.6.3" 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 100644 index 00000000..2ba3d8a6 --- /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 crate::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 100644 index 00000000..e7479318 --- /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 100644 index 00000000..10b028b2 --- /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 100644 index 00000000..aa769a82 --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.lock @@ -0,0 +1,56 @@ +[[package]] +name = "hello_macro" +version = "0.1.0" + +[[package]] +name = "hello_macro_derive" +version = "0.1.0" +dependencies = [ + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (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 = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum proc-macro2 0.4.29 (registry+https://github.com/rust-lang/crates.io-index)" = "64c827cea7a7ab30ce4593e5e04d7a11617ad6ece2fa230605a78b00ff965316" +"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" +"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 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 100644 index 00000000..cc0addaa --- /dev/null +++ b/listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "pancakes" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..468c30aa --- /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 100644 index 00000000..026e5ee5 --- /dev/null +++ b/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..aabe3bdf --- /dev/null +++ b/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unsafe-example" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..1adca2cd --- /dev/null +++ b/listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt @@ -0,0 +1,16 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0133`. +error: Could not compile `unsafe-example`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..01305be7 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-01/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..d868c3ec --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-02/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..59424646 --- /dev/null +++ b/listings/ch20-web-server/listing-20-02/src/main.rs @@ -0,0 +1,21 @@ +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 512]; + + 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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-03/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..c62319b6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-03/src/main.rs @@ -0,0 +1,26 @@ +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +// ANCHOR: here +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 512]; + + 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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-04/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..b9739ba7 --- /dev/null +++ b/listings/ch20-web-server/listing-20-04/src/main.rs @@ -0,0 +1,24 @@ +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 512]; + + 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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-05/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..073dafc0 --- /dev/null +++ b/listings/ch20-web-server/listing-20-05/src/main.rs @@ -0,0 +1,32 @@ +// ANCHOR: here +use std::fs; +// --snip-- + +// ANCHOR_END: here +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +// ANCHOR: here +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 512]; + stream.read(&mut buffer).unwrap(); + + let contents = fs::read_to_string("hello.html").unwrap(); + + let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", 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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-06/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..3e894322 --- /dev/null +++ b/listings/ch20-web-server/listing-20-06/src/main.rs @@ -0,0 +1,36 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +// ANCHOR: here +// --snip-- + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 512]; + 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\n\r\n{}", 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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-07/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..06e80d0f --- /dev/null +++ b/listings/ch20-web-server/listing-20-07/src/main.rs @@ -0,0 +1,42 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 512]; + 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\n\r\n{}", contents); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + // ANCHOR: here + // --snip-- + + } else { + let status_line = "HTTP/1.1 404 NOT FOUND\r\n\r\n"; + let contents = fs::read_to_string("404.html").unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..00303a42 --- /dev/null +++ b/listings/ch20-web-server/listing-20-08/src/main.rs @@ -0,0 +1,38 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +fn handle_connection(mut stream: TcpStream) { + let mut buffer = [0; 512]; + 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\n\r\n{}", contents); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); + } else { + let status_line = "HTTP/1.1 404 NOT FOUND\r\n\r\n"; + let contents = fs::read_to_string("404.html").unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..fbd2fbf7 --- /dev/null +++ b/listings/ch20-web-server/listing-20-09/src/main.rs @@ -0,0 +1,42 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +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(); + + handle_connection(stream); + } +} + +// ANCHOR: here +// --snip-- + +fn handle_connection(mut stream: TcpStream) { + // --snip-- + + // ANCHOR_END: here + let mut buffer = [0; 512]; + 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\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..8fdbf5d4 --- /dev/null +++ b/listings/ch20-web-server/listing-20-10/src/main.rs @@ -0,0 +1,53 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +// 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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + // --snip-- + // ANCHOR_END: here + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..0d44625b --- /dev/null +++ b/listings/ch20-web-server/listing-20-11/src/main.rs @@ -0,0 +1,44 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..77840969 --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/output.txt @@ -0,0 +1,14 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0433]: failed to resolve: use of undeclared type or module `ThreadPool` + --> src/main.rs:10:16 + | +10 | let pool = ThreadPool::new(4); + | ^^^^^^^^^^ use of undeclared type or module `ThreadPool` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. +error: Could not compile `hello`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..c0644f6e --- /dev/null +++ b/listings/ch20-web-server/listing-20-12/src/main.rs @@ -0,0 +1,45 @@ +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..1ce57a4e --- /dev/null +++ b/listings/ch20-web-server/listing-20-13/src/lib.rs @@ -0,0 +1,31 @@ +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 + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..9ce4b16f --- /dev/null +++ b/listings/ch20-web-server/listing-20-14/src/lib.rs @@ -0,0 +1,44 @@ +// 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..f1b1cd98 --- /dev/null +++ b/listings/ch20-web-server/listing-20-15/src/lib.rs @@ -0,0 +1,61 @@ +// 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 + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..11591d31 --- /dev/null +++ b/listings/ch20-web-server/listing-20-16/src/lib.rs @@ -0,0 +1,69 @@ +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, + } + } +} + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..61748690 --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/output.txt @@ -0,0 +1,17 @@ +$ 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 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. +error: Could not compile `hello`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..80e34c36 --- /dev/null +++ b/listings/ch20-web-server/listing-20-17/src/lib.rs @@ -0,0 +1,73 @@ +use std::thread; +use std::sync::mpsc; + +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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..6302b12c --- /dev/null +++ b/listings/ch20-web-server/listing-20-18/src/lib.rs @@ -0,0 +1,85 @@ +use std::thread; +use std::sync::mpsc; +// 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 + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..1b684136 --- /dev/null +++ b/listings/ch20-web-server/listing-20-19/src/lib.rs @@ -0,0 +1,77 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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, + } + } +} + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..f2d069f4 --- /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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..71eb9c6f --- /dev/null +++ b/listings/ch20-web-server/listing-20-20/src/lib.rs @@ -0,0 +1,76 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..d5584569 --- /dev/null +++ b/listings/ch20-web-server/listing-20-21/src/lib.rs @@ -0,0 +1,73 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..94ed2771 --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/output.txt @@ -0,0 +1,14 @@ +$ 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:55:13 + | +55 | worker.thread.join().unwrap(); + | ^^^^^^^^^^^^^ move occurs because `worker.thread` has type `std::thread::JoinHandle<()>`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. +error: Could not compile `hello`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..01d08c1c --- /dev/null +++ b/listings/ch20-web-server/listing-20-22/src/lib.rs @@ -0,0 +1,84 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..f590a44b --- /dev/null +++ b/listings/ch20-web-server/listing-20-23/src/lib.rs @@ -0,0 +1,114 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +// 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..f2d069f4 --- /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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..319452f6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-24/src/lib.rs @@ -0,0 +1,110 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 &mut 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..1ea31705 --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/src/bin/main.rs @@ -0,0 +1,50 @@ +// ANCHOR: all +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, contents); + + stream.write(response.as_bytes()).unwrap(); + stream.flush().unwrap(); +} +// ANCHOR_END: all 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 100644 index 00000000..637d3ea6 --- /dev/null +++ b/listings/ch20-web-server/listing-20-25/src/lib.rs @@ -0,0 +1,112 @@ +// ANCHOR: here +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 &mut 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), + } + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..61703b4b --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt @@ -0,0 +1,14 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0599]: no function or associated item named `new` found for type `hello::ThreadPool` in the current scope + --> src/bin/main.rs:11:28 + | +11 | let pool = ThreadPool::new(4); + | ^^^ function or associated item not found in `hello::ThreadPool` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. +error: Could not compile `hello`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..39e8c8fa --- /dev/null +++ b/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs @@ -0,0 +1,46 @@ +// ANCHOR: here +use hello::ThreadPool; +// ANCHOR_END: here +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..7312e293 --- /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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..44bc1fab --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt @@ -0,0 +1,14 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0599]: no method named `execute` found for type `hello::ThreadPool` in the current scope + --> src/bin/main.rs:16:14 + | +16 | pool.execute(|| { + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. +error: Could not compile `hello`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..3ff5ad49 --- /dev/null +++ b/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs @@ -0,0 +1,11 @@ +// ANCHOR: here +pub struct ThreadPool; + +impl ThreadPool { + pub fn new(size: usize) -> ThreadPool { + ThreadPool + } +} +// ANCHOR_END: here + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..dc76c43d --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..f3b4ef3f --- /dev/null +++ b/listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs @@ -0,0 +1,21 @@ +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 + +fn main() {} 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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..5fa1d5bf --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt @@ -0,0 +1,27 @@ +$ cargo check + Checking hello v0.1.0 (file:///projects/hello) +error[E0599]: no method named `join` found for type `std::option::Option>` in the current scope + --> src/lib.rs:55:27 + | +55 | worker.thread.join().unwrap(); + | ^^^^ + +error[E0308]: mismatched types + --> src/lib.rs:79:13 + | +79 | thread, + | ^^^^^^ + | | + | expected enum `std::option::Option`, found struct `std::thread::JoinHandle` + | help: try using a variant of the expected type: `Some(thread)` + | + = note: expected type `std::option::Option>` + found type `std::thread::JoinHandle<_>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0599. +For more information about an error, try `rustc --explain E0308`. +error: Could not compile `hello`. + +To learn more, run the command again with --verbose. 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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..dd4d861a --- /dev/null +++ b/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs @@ -0,0 +1,84 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..012fd0a6 --- /dev/null +++ b/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs @@ -0,0 +1,88 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..5845a6fa --- /dev/null +++ b/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs @@ -0,0 +1,86 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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 100644 index 00000000..88d8e915 --- /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 100644 index 00000000..15b9446d --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.lock @@ -0,0 +1,4 @@ +[[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 100644 index 00000000..78dfe6eb --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hello" +version = "0.1.0" +authors = ["Your Name "] +edition = "2018" + +[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 100644 index 00000000..fe442d6b --- /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 100644 index 00000000..f398eaed --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/src/bin/main.rs @@ -0,0 +1,44 @@ +use hello::ThreadPool; +use std::fs; +use std::io::prelude::*; +use std::net::TcpStream; +use std::net::TcpListener; +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; 512]; + 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\r\n\r\n", "hello.html") + } else if buffer.starts_with(sleep) { + thread::sleep(Duration::from_secs(5)); + ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") + } else { + ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") + }; + + let contents = fs::read_to_string(filename).unwrap(); + + let response = format!("{}{}", status_line, 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 100644 index 00000000..52c8b514 --- /dev/null +++ b/listings/ch20-web-server/no-listing-07-define-message-enum/src/lib.rs @@ -0,0 +1,93 @@ +use std::thread; +use std::sync::mpsc; +use std::sync::Arc; +use std::sync::Mutex; + +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), + } + } +} + +fn main() {} diff --git a/src/ch02-00-guessing-game-tutorial.md b/src/ch02-00-guessing-game-tutorial.md index 2ecc1520..55055ca1 100644 --- a/src/ch02-00-guessing-game-tutorial.md +++ b/src/ch02-00-guessing-game-tutorial.md @@ -31,13 +31,7 @@ Look at the generated *Cargo.toml* file: Filename: 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}} ``` If the author information that Cargo obtained from your environment is not @@ -49,20 +43,14 @@ you. Check out the *src/main.rs* file: Filename: src/main.rs ```rust -fn main() { - println!("Hello, world!"); -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs}} ``` Now let’s compile this “Hello, world!” program and run it in the same step using the `cargo run` command: ```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! +{{#include ../listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt}} ``` The `run` command comes in handy when you need to rapidly iterate on a project, @@ -81,20 +69,7 @@ allow the player to input a guess. Enter the code in Listing 2-1 into Filename: 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}} ``` Listing 2-1: Code that gets a guess from the user and @@ -289,15 +264,7 @@ entered into standard input. If you don’t call `expect`, the program will compile, but you’ll get a warning: ```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 +{{#include ../listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt}} ``` Rust warns that you haven’t used the `Result` value returned from `read_line`, @@ -336,10 +303,16 @@ This code would print `x = 5 and y = 10`. Let’s test the first part of the guessing game. Run it using `cargo run`: + + ```text $ 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! Please input your guess. @@ -382,8 +355,7 @@ you: Filename: Cargo.toml ```toml -[dependencies] -rand = "0.5.5" +{{#include ../listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml:9:}} ``` In the *Cargo.toml* file, everything that follows a header is part of a section @@ -401,6 +373,11 @@ version 0.5.5.” Now, without changing any of the code, let’s build the project, as shown in Listing 2-2. + + ```text $ cargo build Updating crates.io index @@ -415,7 +392,7 @@ $ cargo build Compiling rand_core v0.2.2 Compiling rand v0.5.5 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 ``` Listing 2-2: The output from running `cargo build` after @@ -433,9 +410,9 @@ their open source Rust projects for others to use. After updating the registry, Cargo checks the `[dependencies]` section and downloads any crates you don’t have yet. In this case, although we only listed -`rand` as a dependency, Cargo also grabbed `libc` and `rand_core`, because `rand` -depends on those to work. After downloading the crates, Rust compiles them and -then compiles the project with the dependencies available. +`rand` as a dependency, Cargo also grabbed `libc` and `rand_core`, because +`rand` depends on those to work. After downloading the crates, Rust compiles +them and then compiles the project with the dependencies available. If you immediately run `cargo build` again without making any changes, you won’t get any output aside from the `Finished` line. Cargo knows it has already @@ -447,10 +424,15 @@ do, it simply exits. If you open up the *src/main.rs* file, make a trivial change, and then save it and build again, you’ll only see two lines of output: + + ```text $ cargo build Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53s + Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs ``` These lines show Cargo only updates the build with your tiny change to the @@ -489,6 +471,12 @@ But by default, Cargo will only look for versions greater than `0.5.5` and less than `0.6.0`. If the `rand` crate has released two new versions, `0.5.6` and `0.6.0`, you would see the following if you ran `cargo update`: + + ```text $ cargo update Updating crates.io index @@ -527,25 +515,7 @@ Now that you’ve added the `rand` crate to *Cargo.toml*, let’s start using Filename: 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}} ``` Listing 2-3: Adding code to generate a random @@ -580,17 +550,27 @@ program prints the answer as soon as it starts! Try running the program a few times: + + ```text $ 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 @@ -611,22 +591,7 @@ will explain. Filename: 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}} ``` Listing 2-4: Handling the possible return values of @@ -672,19 +637,7 @@ expression ends because it has no need to look at the last arm in this scenario. However, the code in Listing 2-4 won’t compile yet. Let’s try it: ```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`. +{{#include ../listings/ch02-guessing-game-tutorial/listing-02-04/output.txt}} ``` The core of the error states that there are *mismatched types*. Rust has a @@ -705,24 +658,7 @@ do that by adding the following two lines to the `main` function body: Filename: 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}} ``` The two new lines are: @@ -779,10 +715,16 @@ number that we want from the `Ok` value. Let’s run the program now! + + ```text $ 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 @@ -808,22 +750,7 @@ more chances at guessing the number: Filename: 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}} ``` As you can see, we’ve moved everything into a loop from the guess input prompt @@ -839,10 +766,19 @@ Guess to the Secret Number”](#comparing-the-guess-to-the-secret-number): if the user enters a non-number answer, the program will crash. The user can take advantage of that in order to quit, as shown here: + + ```text $ 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 @@ -860,9 +796,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/libcore/result.rs:999:5 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. ``` Typing `quit` actually quits the game, but so will any other non-number input. @@ -876,18 +811,7 @@ Let’s program the game to quit when the user wins by adding a `break` statemen Filename: 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}} ``` Adding the `break` line after `You win!` makes the program exit the loop when @@ -904,19 +828,7 @@ is converted from a `String` to a `u32`, as shown in Listing 2-5. Filename: 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}} ``` Listing 2-5: Ignoring a non-number guess and asking for @@ -946,6 +858,15 @@ program ignores all errors that `parse` might encounter! Now everything in the program should work as expected. Let’s try it: + + ```text $ cargo run Compiling guessing_game v0.1.0 (file:///projects/guessing_game) @@ -976,40 +897,7 @@ secret number. Listing 2-6 shows the final code. Filename: 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}} ``` Listing 2-6: Complete guessing game code diff --git a/src/ch03-01-variables-and-mutability.md b/src/ch03-01-variables-and-mutability.md index d6a73a09..05fea9aa 100644 --- a/src/ch03-01-variables-and-mutability.md +++ b/src/ch03-01-variables-and-mutability.md @@ -17,26 +17,14 @@ code with the following code that won’t compile just yet: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let x = 5; - println!("The value of x is: {}", x); - x = 6; - println!("The value of x is: {}", x); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs}} ``` Save and run the program using `cargo run`. You should receive an error message, as shown in this output: ```text -error[E0384]: cannot assign twice to immutable variable `x` - --> src/main.rs:4:5 - | -2 | let x = 5; - | - first assignment to `x` -3 | println!("The value of x is: {}", x); -4 | x = 6; - | ^^^^^ cannot assign twice to immutable variable +{{#include ../listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt}} ``` This example shows how the compiler helps you find errors in your programs. @@ -72,23 +60,13 @@ For example, let’s change *src/main.rs* to the following: Filename: src/main.rs ```rust -fn main() { - let mut x = 5; - println!("The value of x is: {}", x); - x = 6; - println!("The value of x is: {}", x); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs}} ``` When we run the program now, we get this: ```text -$ cargo run - Compiling variables v0.1.0 (file:///projects/variables) - Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs - Running `target/debug/variables` -The value of x is: 5 -The value of x is: 6 +{{#include ../listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt}} ``` We’re allowed to change the value that `x` binds to from `5` to `6` when `mut` @@ -160,15 +138,7 @@ of the `let` keyword as follows: Filename: src/main.rs ```rust -fn main() { - let x = 5; - - let x = x + 1; - - let x = x * 2; - - println!("The value of x is: {}", x); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs}} ``` This program first binds `x` to a value of `5`. Then it shadows `x` by @@ -178,11 +148,7 @@ previous value by `2` to give `x` a final value of `12`. When we run this program, it will output the following: ```text -$ cargo run - Compiling variables v0.1.0 (file:///projects/variables) - Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs - Running `target/debug/variables` -The value of x is: 12 +{{#include ../listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt}} ``` Shadowing is different from marking a variable as `mut`, because we’ll get a @@ -198,8 +164,7 @@ program asks a user to show how many spaces they want between some text by inputting space characters, but we really want to store that input as a number: ```rust -let spaces = " "; -let spaces = spaces.len(); +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/src/main.rs:here}} ``` This construct is allowed because the first `spaces` variable is a string type @@ -210,21 +175,13 @@ from having to come up with different names, such as `spaces_str` and try to use `mut` for this, as shown here, we’ll get a compile-time error: ```rust,ignore,does_not_compile -let mut spaces = " "; -spaces = spaces.len(); +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/src/main.rs:here}} ``` The error says we’re not allowed to mutate a variable’s type: ```text -error[E0308]: mismatched types - --> src/main.rs:3:14 - | -3 | spaces = spaces.len(); - | ^^^^^^^^^^^^ expected &str, found usize - | - = note: expected type `&str` - found type `usize` +{{#include ../listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt}} ``` Now that we’ve explored how variables work, let’s look at more data types they diff --git a/src/ch03-02-data-types.md b/src/ch03-02-data-types.md index 482e69f7..5c8b162b 100644 --- a/src/ch03-02-data-types.md +++ b/src/ch03-02-data-types.md @@ -21,14 +21,7 @@ error, which means the compiler needs more information from us to know which type we want to use: ```text -error[E0282]: type annotations needed - --> src/main.rs:2:9 - | -2 | let guess = "42".parse().expect("Not a number!"); - | ^^^^^ - | | - | cannot infer type for `_` - | consider giving `guess` a type +{{#include ../listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt}} ``` You’ll see different type annotations for other data types. @@ -133,11 +126,7 @@ Here’s an example that shows floating-point numbers in action: Filename: src/main.rs ```rust -fn main() { - let x = 2.0; // f64 - - let y: f32 = 3.0; // f32 -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-06-floating-point/src/main.rs}} ``` Floating-point numbers are represented according to the IEEE-754 standard. The @@ -152,22 +141,7 @@ The following code shows how you’d use each one in a `let` statement: Filename: src/main.rs ```rust -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; - - // remainder - let remainder = 43 % 5; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs}} ``` Each expression in these statements uses a mathematical operator and evaluates @@ -183,11 +157,7 @@ Rust is specified using `bool`. For example: Filename: src/main.rs ```rust -fn main() { - let t = true; - - let f: bool = false; // with explicit type annotation -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-08-boolean/src/main.rs}} ``` The main way to use Boolean values is through conditionals, such as an `if` @@ -204,11 +174,7 @@ single quotes, as opposed to string literals, which use double quotes.) Filename: src/main.rs ```rust -fn main() { - let c = 'z'; - let z = 'ℤ'; - let heart_eyed_cat = '😻'; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-09-char/src/main.rs}} ``` Rust’s `char` type is four bytes in size and represents a Unicode Scalar Value, @@ -240,9 +206,7 @@ type annotations in this example: Filename: src/main.rs ```rust -fn main() { - let tup: (i32, f64, u8) = (500, 6.4, 1); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs}} ``` The variable `tup` binds to the entire tuple, because a tuple is considered a @@ -252,13 +216,7 @@ use pattern matching to destructure a tuple value, like this: Filename: src/main.rs ```rust -fn main() { - let tup = (500, 6.4, 1); - - let (x, y, z) = tup; - - println!("The value of y is: {}", y); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs}} ``` This program first creates a tuple and binds it to the variable `tup`. It then @@ -274,15 +232,7 @@ want to access. For example: Filename: src/main.rs ```rust -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; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs}} ``` This program creates a tuple, `x`, and then makes new variables for each @@ -302,9 +252,7 @@ inside square brackets: Filename: src/main.rs ```rust -fn main() { - let a = [1, 2, 3, 4, 5]; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-13-arrays/src/main.rs}} ``` Arrays are useful when you want your data allocated on the stack rather than @@ -357,12 +305,7 @@ elements of an array using indexing, like this: Filename: src/main.rs ```rust -fn main() { - let a = [1, 2, 3, 4, 5]; - - let first = a[0]; - let second = a[1]; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs}} ``` In this example, the variable named `first` will get the value `1`, because @@ -378,26 +321,13 @@ compile but exit with an error when it runs: Filename: src/main.rs ```rust,ignore,panics -fn main() { - let a = [1, 2, 3, 4, 5]; - let index = 10; - - let element = a[index]; - - println!("The value of element is: {}", element); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs}} ``` Running this code using `cargo run` produces the following result: ```text -$ cargo run - Compiling arrays v0.1.0 (file:///projects/arrays) - Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs - Running `target/debug/arrays` -thread 'main' panicked at 'index out of bounds: the len is 5 but the index is - 10', src/main.rs:5:19 -note: Run with `RUST_BACKTRACE=1` for a backtrace. +{{#include ../listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/output.txt}} ``` The compilation didn’t produce any errors, but the program resulted in a diff --git a/src/ch03-03-how-functions-work.md b/src/ch03-03-how-functions-work.md index 95007579..491a69b8 100644 --- a/src/ch03-03-how-functions-work.md +++ b/src/ch03-03-how-functions-work.md @@ -12,15 +12,7 @@ Here’s a program that contains an example function definition: Filename: src/main.rs ```rust -fn main() { - println!("Hello, world!"); - - another_function(); -} - -fn another_function() { - println!("Another function."); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs}} ``` Function definitions in Rust start with `fn` and have a set of parentheses @@ -39,12 +31,7 @@ further. Place the `another_function` example in *src/main.rs* and run it. You should see the following output: ```text -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished dev [unoptimized + debuginfo] target(s) in 0.28 secs - Running `target/debug/functions` -Hello, world! -Another function. +{{#include ../listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt}} ``` The lines execute in the order in which they appear in the `main` function. @@ -67,23 +54,13 @@ look like in Rust: Filename: src/main.rs ```rust -fn main() { - another_function(5); -} - -fn another_function(x: i32) { - println!("The value of x is: {}", x); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs}} ``` Try running this program; you should get the following output: ```text -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished dev [unoptimized + debuginfo] target(s) in 1.21 secs - Running `target/debug/functions` -The value of x is: 5 +{{#include ../listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt}} ``` The declaration of `another_function` has one parameter named `x`. The type of @@ -102,14 +79,7 @@ declarations with commas, like this: Filename: src/main.rs ```rust -fn main() { - another_function(5, 6); -} - -fn another_function(x: i32, y: i32) { - println!("The value of x is: {}", x); - println!("The value of y is: {}", y); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs}} ``` This example creates a function with two parameters, both of which are `i32` @@ -122,12 +92,7 @@ project’s *src/main.rs* file with the preceding example and run it using `carg run`: ```text -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs - Running `target/debug/functions` -The value of x is: 5 -The value of y is: 6 +{{#include ../listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt}} ``` Because we called the function with `5` as the value for `x` and `6` is passed @@ -153,9 +118,7 @@ statement. In Listing 3-1, `let y = 6;` is a statement. Filename: src/main.rs ```rust -fn main() { - let y = 6; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/listing-03-01/src/main.rs}} ``` Listing 3-1: A `main` function declaration containing one statement @@ -169,13 +132,14 @@ to another variable, as the following code tries to do; you’ll get an error: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let x = (let y = 6); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/src/main.rs}} ``` When you run this program, the error you’ll get looks like this: + + ```text $ cargo run Compiling functions v0.1.0 (file:///projects/functions) @@ -205,16 +169,7 @@ new scopes, `{}`, is an expression, for example: Filename: src/main.rs ```rust -fn main() { - let x = 5; - - let y = { - let x = 3; - x + 1 - }; - - println!("The value of y is: {}", y); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs}} ``` This expression: @@ -246,15 +201,7 @@ value: Filename: src/main.rs ```rust -fn five() -> i32 { - 5 -} - -fn main() { - let x = five(); - - println!("The value of x is: {}", x); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs}} ``` There are no function calls, macros, or even `let` statements in the `five` @@ -263,11 +210,7 @@ Rust. Note that the function’s return type is specified too, as `-> i32`. Try running this code; the output should look like this: ```text -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs - Running `target/debug/functions` -The value of x is: 5 +{{#include ../listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt}} ``` The `5` in `five` is the function’s return value, which is why the return type @@ -289,15 +232,7 @@ Let’s look at another example: Filename: src/main.rs ```rust -fn main() { - let x = plus_one(5); - - println!("The value of x is: {}", x); -} - -fn plus_one(x: i32) -> i32 { - x + 1 -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs}} ``` Running this code will print `The value of x is: 6`. But if we place a @@ -307,32 +242,13 @@ expression to a statement, we’ll get an error. Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let x = plus_one(5); - - println!("The value of x is: {}", x); -} - -fn plus_one(x: i32) -> i32 { - x + 1; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs}} ``` Compiling this code produces an error, as follows: ```text -error[E0308]: mismatched types - --> src/main.rs:7:28 - | -7 | fn plus_one(x: i32) -> i32 { - | ____________________________^ -8 | | x + 1; - | | - help: consider removing this semicolon -9 | | } - | |_^ expected i32, found () - | - = note: expected type `i32` - found type `()` +{{#include ../listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt}} ``` The main error message, “mismatched types,” reveals the core issue with this diff --git a/src/ch03-04-comments.md b/src/ch03-04-comments.md index d42e38c2..fb982be9 100644 --- a/src/ch03-04-comments.md +++ b/src/ch03-04-comments.md @@ -26,9 +26,7 @@ Comments can also be placed at the end of lines containing code: Filename: src/main.rs ```rust -fn main() { - let lucky_number = 7; // I’m feeling lucky today -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs}} ``` But you’ll more often see them used in this format, with the comment on a @@ -37,10 +35,7 @@ separate line above the code it’s annotating: Filename: src/main.rs ```rust -fn main() { - // I’m feeling lucky today - let lucky_number = 7; -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs}} ``` Rust also has another kind of comment, documentation comments, which we’ll diff --git a/src/ch03-05-control-flow.md b/src/ch03-05-control-flow.md index ac529d92..b37e65fa 100644 --- a/src/ch03-05-control-flow.md +++ b/src/ch03-05-control-flow.md @@ -18,15 +18,7 @@ the `if` expression. In the *src/main.rs* file, input the following: Filename: src/main.rs ```rust -fn main() { - let number = 3; - - if number < 5 { - println!("condition was true"); - } else { - println!("condition was false"); - } -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs}} ``` All `if` expressions start with the keyword `if`, which is followed by a @@ -48,28 +40,20 @@ to the next bit of code. Try running this code; you should see the following output: ```text -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs - Running `target/debug/branches` -condition was true +{{#include ../listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt}} ``` Let’s try changing the value of `number` to a value that makes the condition `false` to see what happens: ```rust,ignore -let number = 7; +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs:here}} ``` Run the program again, and look at the output: ```text -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs - Running `target/debug/branches` -condition was false +{{#include ../listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt}} ``` It’s also worth noting that the condition in this code *must* be a `bool`. If @@ -79,27 +63,14 @@ following code: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let number = 3; - - if number { - println!("number was three"); - } -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs}} ``` The `if` condition evaluates to a value of `3` this time, and Rust throws an error: ```text -error[E0308]: mismatched types - --> src/main.rs:4:8 - | -4 | if number { - | ^^^^^^ expected bool, found integer - | - = note: expected type `bool` - found type `{integer}` +{{#include ../listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt}} ``` The error indicates that Rust expected a `bool` but got an integer. Unlike @@ -112,13 +83,7 @@ expression to the following: Filename: src/main.rs ```rust -fn main() { - let number = 3; - - if number != 0 { - println!("number was something other than zero"); - } -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs}} ``` Running this code will print `number was something other than zero`. @@ -131,30 +96,14 @@ expression. For example: Filename: src/main.rs ```rust -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"); - } -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs}} ``` This program has four possible paths it can take. After running it, you should see the following output: ```text -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs - Running `target/debug/branches` -number is divisible by 3 +{{#include ../listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt}} ``` When this program executes, it checks each `if` expression in turn and executes @@ -176,16 +125,7 @@ statement, as in Listing 3-2. Filename: src/main.rs ```rust -fn main() { - let condition = true; - let number = if condition { - 5 - } else { - 6 - }; - - println!("The value of number is: {}", number); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/listing-03-02/src/main.rs}} ``` Listing 3-2: Assigning the result of an `if` expression @@ -195,11 +135,7 @@ The `number` variable will be bound to a value based on the outcome of the `if` expression. Run this code to see what happens: ```text -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs - Running `target/debug/branches` -The value of number is: 5 +{{#include ../listings/ch03-common-programming-concepts/listing-03-02/output.txt}} ``` Remember that blocks of code evaluate to the last expression in them, and @@ -213,17 +149,7 @@ example, we’ll get an error: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let condition = true; - - let number = if condition { - 5 - } else { - "six" - }; - - println!("The value of number is: {}", number); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs}} ``` When we try to compile this code, we’ll get an error. The `if` and `else` arms @@ -231,19 +157,7 @@ have value types that are incompatible, and Rust indicates exactly where to find the problem in the program: ```text -error[E0308]: if and else have incompatible types - --> src/main.rs:4:18 - | -4 | let number = if condition { - | __________________^ -5 | | 5 -6 | | } else { -7 | | "six" -8 | | }; - | |_____^ expected integer, found &str - | - = note: expected type `{integer}` - found type `&str` +{{#include ../listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt}} ``` The expression in the `if` block evaluates to an integer, and the expression in @@ -275,11 +189,7 @@ like this: Filename: src/main.rs ```rust,ignore -fn main() { - loop { - println!("again!"); - } -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs}} ``` When we run this program, we’ll see `again!` printed over and over continuously @@ -287,10 +197,16 @@ until we stop the program manually. Most terminals support a keyboard shortcut, ctrl-c, to interrupt a program that is stuck in a continual loop. Give it a try: + + ```text $ cargo run Compiling loops v0.1.0 (file:///projects/loops) - Finished dev [unoptimized + debuginfo] target(s) in 0.29 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.29s Running `target/debug/loops` again! again! @@ -321,19 +237,7 @@ the loop; that value will be returned out of the loop so you can use it, as shown here: ```rust -fn main() { - let mut counter = 0; - - let result = loop { - counter += 1; - - if counter == 10 { - break counter * 2; - } - }; - - println!("The result is {}", result); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs}} ``` Before the loop, we declare a variable named `counter` and initialize it to @@ -360,17 +264,7 @@ another message and exits. Filename: src/main.rs ```rust -fn main() { - let mut number = 3; - - while number != 0 { - println!("{}!", number); - - number -= 1; - } - - println!("LIFTOFF!!!"); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/listing-03-03/src/main.rs}} ``` Listing 3-3: Using a `while` loop to run code while a @@ -388,16 +282,7 @@ such as an array. For example, let’s look at Listing 3-4. Filename: src/main.rs ```rust -fn main() { - let a = [10, 20, 30, 40, 50]; - let mut index = 0; - - while index < 5 { - println!("the value is: {}", a[index]); - - index += 1; - } -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/listing-03-04/src/main.rs}} ``` Listing 3-4: Looping through each element of a collection @@ -409,15 +294,7 @@ when `index < 5` is no longer true). Running this code will print every element in the array: ```text -$ cargo run - Compiling loops v0.1.0 (file:///projects/loops) - Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs - Running `target/debug/loops` -the value is: 10 -the value is: 20 -the value is: 30 -the value is: 40 -the value is: 50 +{{#include ../listings/ch03-common-programming-concepts/listing-03-04/output.txt}} ``` All five array values appear in the terminal, as expected. Even though `index` @@ -435,13 +312,7 @@ for each item in a collection. A `for` loop looks like the code in Listing 3-5. Filename: src/main.rs ```rust -fn main() { - let a = [10, 20, 30, 40, 50]; - - for element in a.iter() { - println!("the value is: {}", element); - } -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/listing-03-05/src/main.rs}} ``` Listing 3-5: Looping through each element of a collection @@ -471,12 +342,7 @@ we’ve not yet talked about, `rev`, to reverse the range: Filename: src/main.rs ```rust -fn main() { - for number in (1..4).rev() { - println!("{}!", number); - } - println!("LIFTOFF!!!"); -} +{{#rustdoc_include ../listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs}} ``` This code is a bit nicer, isn’t it? diff --git a/src/ch04-01-what-is-ownership.md b/src/ch04-01-what-is-ownership.md index cf8fd209..00183008 100644 --- a/src/ch04-01-what-is-ownership.md +++ b/src/ch04-01-what-is-ownership.md @@ -30,14 +30,14 @@ strings. > be described in relation to the stack and the heap later in this chapter, so > here is a brief explanation in preparation. > -> Both the stack and the heap are parts of memory that are available to your code -> to use at runtime, but they are structured in different ways. The stack stores -> values in the order it gets them and removes the values in the opposite order. -> This is referred to as *last in, first out*. Think of a stack of plates: when -> you add more plates, you put them on top of the pile, and when you need a -> plate, you take one off the top. Adding or removing plates from the middle or -> bottom wouldn’t work as well! Adding data is called *pushing onto the stack*, -> and removing data is called *popping off the stack*. +> Both the stack and the heap are parts of memory that are available to your +> code to use at runtime, but they are structured in different ways. The stack +> stores values in the order it gets them and removes the values in the +> opposite order. This is referred to as *last in, first out*. Think of a stack +> of plates: when you add more plates, you put them on top of the pile, and +> when you need a plate, you take one off the top. Adding or removing plates +> from the middle or bottom wouldn’t work as well! Adding data is called +> *pushing onto the stack*, and removing data is called *popping off the stack*. > > All data stored on the stack must have a known, fixed size. Data with an > unknown size at compile time or a size that might change must be stored on @@ -117,11 +117,7 @@ which it’s declared until the end of the current *scope*. Listing 4-1 has comments annotating where the variable `s` is valid. ```rust -{ // 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 +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-01/src/main.rs:here}} ``` Listing 4-1: A variable and the scope in which it is @@ -147,7 +143,7 @@ data. We’ll use `String` as the example here and concentrate on the parts of `String` that relate to ownership. These aspects also apply to other complex data types, -whether they are provided by the standard library or created by you. We’ll +whether they are provided by the standard library or created by you. We’ll discuss `String` in more depth in Chapter 8. We’ve already seen string literals, where a string value is hardcoded into our @@ -174,11 +170,7 @@ Module Tree”][paths-module-tree] in Chapter 7. This kind of string *can* be mutated: ```rust -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!` +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs:here}} ``` So, what’s the difference here? Why can `String` be mutated but literals @@ -219,12 +211,7 @@ variable that owns it goes out of scope. Here’s a version of our scope example from Listing 4-1 using a `String` instead of a string literal: ```rust -{ - 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 +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs:here}} ``` There is a natural point at which we can return the memory our `String` needs @@ -249,8 +236,7 @@ Multiple variables can interact with the same data in different ways in Rust. Let’s look at an example using an integer in Listing 4-2. ```rust -let x = 5; -let y = x; +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-02/src/main.rs:here}} ``` Listing 4-2: Assigning the integer value of variable `x` @@ -265,8 +251,7 @@ onto the stack. Now let’s look at the `String` version: ```rust -let s1 = String::from("hello"); -let s2 = s1; +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs:here}} ``` This looks very similar to the previous code, so we might assume that the way @@ -325,27 +310,14 @@ anything when `s1` goes out of scope. Check out what happens when you try to use `s1` after `s2` is created; it won’t work: ```rust,ignore,does_not_compile -let s1 = String::from("hello"); -let s2 = s1; - -println!("{}, world!", s1); +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs:here}} ``` You’ll get an error like this because Rust prevents you from using the invalidated reference: ```text -error[E0382]: use of moved value: `s1` - --> src/main.rs:5:28 - | -3 | let s2 = s1; - | -- value moved here -4 | -5 | println!("{}, world!", s1); - | ^^ value used here after move - | - = note: move occurs because `s1` has type `std::string::String`, which does - not implement the `Copy` trait +{{#include ../listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt}} ``` If you’ve heard the terms *shallow copy* and *deep copy* while working with @@ -377,10 +349,7 @@ programming languages, you’ve probably seen them before. Here’s an example of the `clone` method in action: ```rust -let s1 = String::from("hello"); -let s2 = s1.clone(); - -println!("s1 = {}, s2 = {}", s1, s2); +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs:here}} ``` This works just fine and explicitly produces the behavior shown in Figure 4-3, @@ -396,10 +365,7 @@ There’s another wrinkle we haven’t talked about yet. This code using integer part of which was shown in Listing 4-2, works and is valid: ```rust -let x = 5; -let y = x; - -println!("x = {}, y = {}", x, y); +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-06-copy/src/main.rs:here}} ``` But this code seems to contradict what we just learned: we don’t have a call to @@ -444,29 +410,7 @@ showing where variables go into and out of scope. Filename: src/main.rs ```rust -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. +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-03/src/main.rs}} ``` Listing 4-3: Functions with ownership and scope @@ -485,35 +429,7 @@ similar annotations to those in Listing 4-3. Filename: src/main.rs ```rust -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 goes out of scope but 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("hello"); // some_string comes into scope - - some_string // some_string is returned and - // moves out to the calling - // function -} - -// takes_and_gives_back will take a String and return 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 -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-04/src/main.rs}} ``` Listing 4-4: Transferring ownership of return @@ -535,19 +451,7 @@ It’s possible to return multiple values using a tuple, as shown in Listing 4-5 Filename: src/main.rs ```rust -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) -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-05/src/main.rs}} ``` Listing 4-5: Returning ownership of parameters diff --git a/src/ch04-02-references-and-borrowing.md b/src/ch04-02-references-and-borrowing.md index 985f17f1..5554fc3d 100644 --- a/src/ch04-02-references-and-borrowing.md +++ b/src/ch04-02-references-and-borrowing.md @@ -12,17 +12,7 @@ value: Filename: src/main.rs ```rust -fn main() { - let s1 = String::from("hello"); - - let len = calculate_length(&s1); - - println!("The length of '{}' is {}.", s1, len); -} - -fn calculate_length(s: &String) -> usize { - s.len() -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs:all}} ``` First, notice that all the tuple code in the variable declaration and the @@ -46,12 +36,7 @@ s1` Let’s take a closer look at the function call here: ```rust -# fn calculate_length(s: &String) -> usize { -# s.len() -# } -let s1 = String::from("hello"); - -let len = calculate_length(&s1); +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs:here}} ``` The `&s1` syntax lets us create a reference that *refers* to the value of `s1` @@ -62,10 +47,7 @@ Likewise, the signature of the function uses `&` to indicate that the type of the parameter `s` is a reference. Let’s add some explanatory annotations: ```rust -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. +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs:here}} ``` The scope in which the variable `s` is valid is the same as any function @@ -84,15 +66,7 @@ Listing 4-6. Spoiler alert: it doesn’t work! Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let s = String::from("hello"); - - change(&s); -} - -fn change(some_string: &String) { - some_string.push_str(", world"); -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-06/src/main.rs}} ``` Listing 4-6: Attempting to modify a borrowed value @@ -100,13 +74,7 @@ fn change(some_string: &String) { Here’s the error: ```text -error[E0596]: cannot borrow immutable borrowed content `*some_string` as mutable - --> error.rs:8:5 - | -7 | fn change(some_string: &String) { - | ------- use `&mut String` here to make mutable -8 | some_string.push_str(", world"); - | ^^^^^^^^^^^ cannot borrow as mutable +{{#include ../listings/ch04-understanding-ownership/listing-04-06/output.txt}} ``` Just as variables are immutable by default, so are references. We’re not @@ -119,15 +87,7 @@ We can fix the error in the code from Listing 4-6 with just a small tweak: Filename: src/main.rs ```rust -fn main() { - let mut s = String::from("hello"); - - change(&mut s); -} - -fn change(some_string: &mut String) { - some_string.push_str(", world"); -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs}} ``` First, we had to change `s` to be `mut`. Then we had to create a mutable @@ -141,27 +101,13 @@ fail: Filename: src/main.rs ```rust,ignore,does_not_compile -let mut s = String::from("hello"); - -let r1 = &mut s; -let r2 = &mut s; - -println!("{}, {}", r1, r2); +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs:here}} ``` Here’s the error: ```text -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 +{{#include ../listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt}} ``` This restriction allows for mutation but in a very controlled fashion. It’s @@ -184,43 +130,20 @@ As always, we can use curly brackets to create a new scope, allowing for multiple mutable references, just not *simultaneous* ones: ```rust -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; +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs:here}} ``` A similar rule exists for combining mutable and immutable references. This code results in an error: ```rust,ignore,does_not_compile -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); +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs:here}} ``` Here’s the error: ```text -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 +{{#include ../listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt}} ``` Whew! We *also* cannot have a mutable reference while we have an immutable one. @@ -235,15 +158,7 @@ compile because the last usage of the immutable references occurs before the mutable reference is introduced: ```rust,edition2018 -let mut s = String::from("hello"); - -let r1 = &s; // no problem -let r2 = &s; // no problem -println!("{} and {}", r1, r2); -// r1 and r2 are no longer used after this point - -let r3 = &mut s; // no problem -println!("{}", r3); +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs:here}} ``` The scopes of the immutable references `r1` and `r2` end after the `println!` @@ -271,29 +186,13 @@ compile-time error: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let reference_to_nothing = dangle(); -} - -fn dangle() -> &String { - let s = String::from("hello"); - - &s -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs}} ``` Here’s the error: ```text -error[E0106]: missing lifetime specifier - --> main.rs:5:16 - | -5 | fn dangle() -> &String { - | ^ expected 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 giving it a 'static lifetime +{{#include ../listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt}} ``` This error message refers to a feature we haven’t covered yet: lifetimes. We’ll @@ -311,13 +210,7 @@ Let’s take a closer look at exactly what’s happening at each stage of our Filename: src/main.rs ```rust,ignore,does_not_compile -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! +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs:here}} ``` Because `s` is created inside `dangle`, when the code of `dangle` is finished, @@ -328,11 +221,7 @@ won’t let us do this. The solution here is to return the `String` directly: ```rust -fn no_dangle() -> String { - let s = String::from("hello"); - - s -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs:here}} ``` This works without any problems. Ownership is moved out, and nothing is diff --git a/src/ch04-03-slices.md b/src/ch04-03-slices.md index 969884cf..902cf3a9 100644 --- a/src/ch04-03-slices.md +++ b/src/ch04-03-slices.md @@ -23,17 +23,7 @@ end of the word. Let’s try that, as shown in Listing 4-7. Filename: src/main.rs ```rust -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() -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:here}} ``` Listing 4-7: The `first_word` function that returns a @@ -44,13 +34,13 @@ a value is a space, we’ll convert our `String` to an array of bytes using the `as_bytes` method: ```rust,ignore -let bytes = s.as_bytes(); +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:as_bytes}} ``` Next, we create an iterator over the array of bytes using the `iter` method: ```rust,ignore -for (i, &item) in bytes.iter().enumerate() { +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:iter}} ``` We’ll discuss iterators in more detail in Chapter 13. For now, know that `iter` @@ -71,12 +61,7 @@ using the byte literal syntax. If we find a space, we return the position. Otherwise, we return the length of the string by using `s.len()`: ```rust,ignore - if item == b' ' { - return i; - } -} - -s.len() +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-07/src/main.rs:inside_for}} ``` We now have a way to find out the index of the end of the first word in the @@ -89,28 +74,7 @@ uses the `first_word` function from Listing 4-7. Filename: src/main.rs ```rust -# 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() -# } -# -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! -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-08/src/main.rs:here}} ``` Listing 4-8: Storing the result from calling the @@ -142,10 +106,7 @@ Luckily, Rust has a solution to this problem: string slices. A *string slice* is a reference to part of a `String`, and it looks like this: ```rust -let s = String::from("hello world"); - -let hello = &s[0..5]; -let world = &s[6..11]; +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs:here}} ``` This is similar to taking a reference to the whole `String` but with the extra @@ -214,17 +175,7 @@ slice. The type that signifies “string slice” is written as `&str`: Filename: src/main.rs ```rust -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[..] -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs:here}} ``` We get the index for the end of the word in the same way as we did in Listing @@ -255,31 +206,13 @@ compile-time error: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let mut s = String::from("hello world"); - - let word = first_word(&s); - - s.clear(); // error! - - println!("the first word is: {}", word); -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs:here}} ``` Here’s the compiler error: ```text -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 +{{#include ../listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt}} ``` Recall from the borrowing rules that if we have an immutable reference to @@ -315,7 +248,7 @@ instead because it allows us to use the same function on both `&String` values and `&str` values. ```rust,ignore -fn first_word(s: &str) -> &str { +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-09/src/main.rs:here}} ``` Listing 4-9: Improving the `first_word` function by using @@ -329,32 +262,7 @@ without losing any functionality: Filename: src/main.rs ```rust -# 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[..] -# } -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); -} +{{#rustdoc_include ../listings/ch04-understanding-ownership/listing-04-09/src/main.rs:usage}} ``` ### Other Slices diff --git a/src/ch05-01-defining-structs.md b/src/ch05-01-defining-structs.md index 17fa72a0..c65b101d 100644 --- a/src/ch05-01-defining-structs.md +++ b/src/ch05-01-defining-structs.md @@ -13,12 +13,7 @@ the pieces of data, which we call *fields*. For example, Listing 5-1 shows a struct that stores information about a user account. ```rust -struct User { - username: String, - email: String, - sign_in_count: u64, - active: bool, -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs:here}} ``` Listing 5-1: A `User` struct definition @@ -34,19 +29,7 @@ in that template with particular data to create values of the type. For example, we can declare a particular user as shown in Listing 5-2. ```rust -# struct User { -# username: String, -# email: String, -# sign_in_count: u64, -# active: bool, -# } -# -let user1 = User { - email: String::from("someone@example.com"), - username: String::from("someusername123"), - active: true, - sign_in_count: 1, -}; +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs:here}} ``` Listing 5-2: Creating an instance of the `User` @@ -59,21 +42,7 @@ the dot notation and assigning into a particular field. Listing 5-3 shows how to change the value in the `email` field of a mutable `User` instance. ```rust -# struct User { -# username: String, -# email: String, -# sign_in_count: u64, -# active: bool, -# } -# -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"); +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs:here}} ``` Listing 5-3: Changing the value in the `email` field of a @@ -89,21 +58,7 @@ the given email and username. The `active` field gets the value of `true`, and the `sign_in_count` gets a value of `1`. ```rust -# struct User { -# username: String, -# email: String, -# sign_in_count: u64, -# active: bool, -# } -# -fn build_user(email: String, username: String) -> User { - User { - email: email, - username: username, - active: true, - sign_in_count: 1, - } -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs:here}} ``` Listing 5-4: A `build_user` function that takes an email @@ -122,21 +77,7 @@ Listing 5-4, we can use the *field init shorthand* syntax to rewrite repetition of `email` and `username`, as shown in Listing 5-5. ```rust -# struct User { -# username: String, -# email: String, -# sign_in_count: u64, -# active: bool, -# } -# -fn build_user(email: String, username: String) -> User { - User { - email, - username, - active: true, - sign_in_count: 1, - } -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs:here}} ``` Listing 5-5: A `build_user` function that uses field init @@ -159,26 +100,7 @@ the update syntax. We set new values for `email` and `username` but otherwise use the same values from `user1` that we created in Listing 5-2. ```rust -# struct User { -# username: String, -# email: String, -# sign_in_count: u64, -# active: bool, -# } -# -# let user1 = User { -# email: String::from("someone@example.com"), -# username: String::from("someusername123"), -# active: true, -# sign_in_count: 1, -# }; -# -let user2 = User { - email: String::from("another@example.com"), - username: String::from("anotherusername567"), - active: user1.active, - sign_in_count: user1.sign_in_count, -}; +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs:here}} ``` Listing 5-6: Creating a new `User` instance using some of @@ -189,25 +111,7 @@ shown in Listing 5-7. The syntax `..` specifies that the remaining fields not explicitly set should have the same value as the fields in the given instance. ```rust -# struct User { -# username: String, -# email: String, -# sign_in_count: u64, -# active: bool, -# } -# -# let user1 = User { -# email: String::from("someone@example.com"), -# username: String::from("someusername123"), -# active: true, -# sign_in_count: 1, -# }; -# -let user2 = User { - email: String::from("another@example.com"), - username: String::from("anotherusername567"), - ..user1 -}; +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs:here}} ``` Listing 5-7: Using struct update syntax to set new @@ -232,11 +136,7 @@ followed by the types in the tuple. For example, here are definitions and usages of two tuple structs named `Color` and `Point`: ```rust -struct Color(i32, i32, i32); -struct Point(i32, i32, i32); - -let black = Color(0, 0, 0); -let origin = Point(0, 0, 0); +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs:here}} ``` Note that the `black` and `origin` values are different types, because they’re @@ -271,6 +171,8 @@ itself. We’ll discuss traits in Chapter 10. > > Filename: src/main.rs > +> +> > ```rust,ignore,does_not_compile > struct User { > username: &str, @@ -292,19 +194,35 @@ itself. We’ll discuss traits in Chapter 10. > The compiler will complain that it needs lifetime specifiers: > > ```text +> $ cargo run +> Compiling structs v0.1.0 (file:///projects/structs) > error[E0106]: missing lifetime specifier -> --> +> --> src/main.rs:2:15 > | > 2 | username: &str, > | ^ expected lifetime parameter > > error[E0106]: missing lifetime specifier -> --> +> --> src/main.rs:3:12 > | > 3 | email: &str, > | ^ expected lifetime parameter +> +> error: aborting due to 2 previous errors +> +> For more information about this error, try `rustc --explain E0106`. +> error: could not compile `structs`. +> +> To learn more, run the command again with --verbose. > ``` > > In Chapter 10, we’ll discuss how to fix these errors so you can store > references in structs, but for now, we’ll fix errors like these using owned > types like `String` instead of references like `&str`. + + \ No newline at end of file diff --git a/src/ch05-02-example-structs.md b/src/ch05-02-example-structs.md index 46f88f1b..03f69d98 100644 --- a/src/ch05-02-example-structs.md +++ b/src/ch05-02-example-structs.md @@ -12,19 +12,7 @@ exactly that in our project’s *src/main.rs*. Filename: src/main.rs ```rust -fn main() { - let width1 = 30; - let height1 = 50; - - println!( - "The area of the rectangle is {} square pixels.", - area(width1, height1) - ); -} - -fn area(width: u32, height: u32) -> u32 { - width * height -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs:all}} ``` Listing 5-8: Calculating the area of a rectangle @@ -33,7 +21,7 @@ specified by separate width and height variables Now, run this program using `cargo run`: ```text -The area of the rectangle is 1500 square pixels. +{{#include ../listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt}} ``` Even though Listing 5-8 works and figures out the area of the rectangle by @@ -44,7 +32,7 @@ rectangle. The issue with this code is evident in the signature of `area`: ```rust,ignore -fn area(width: u32, height: u32) -> u32 { +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs:here}} ``` The `area` function is supposed to calculate the area of one rectangle, but the @@ -61,18 +49,7 @@ Listing 5-9 shows another version of our program that uses tuples. Filename: src/main.rs ```rust -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 -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs}} ``` Listing 5-9: Specifying the width and height of the @@ -100,23 +77,7 @@ parts, as shown in Listing 5-10. Filename: src/main.rs ```rust -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 -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs}} ``` Listing 5-10: Defining a `Rectangle` struct @@ -150,16 +111,7 @@ work, however. Filename: src/main.rs ```rust,ignore,does_not_compile -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { width: 30, height: 50 }; - - println!("rect1 is {}", rect1); -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs}} ``` Listing 5-11: Attempting to print a `Rectangle` @@ -168,7 +120,7 @@ instance When we compile this code, we get an error with this core message: ```text -error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` +{{#include ../listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt:3}} ``` The `println!` macro can do many kinds of formatting, and by default, the curly @@ -185,8 +137,7 @@ implementation of `Display`. If we continue reading the errors, we’ll find this helpful note: ```text -= 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 +{{#include ../listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt:9:10}} ``` Let’s try it! The `println!` macro call will now look like `println!("rect1 is @@ -198,14 +149,13 @@ see its value while we’re debugging our code. Compile the code with this change. Drat! We still get an error: ```text -error[E0277]: `Rectangle` doesn't implement `std::fmt::Debug` +{{#include ../listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt:3}} ``` But again, the compiler gives us a helpful note: ```text -= help: the trait `std::fmt::Debug` is not implemented for `Rectangle` -= note: add `#[derive(Debug)]` or manually implement `std::fmt::Debug` +{{#include ../listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt:9:10}} ``` Rust *does* include functionality to print out debugging information, but we @@ -216,17 +166,7 @@ definition, as shown in Listing 5-12. Filename: src/main.rs ```rust -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { width: 30, height: 50 }; - - println!("rect1 is {:?}", rect1); -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs}} ``` Listing 5-12: Adding the annotation to derive the `Debug` @@ -236,7 +176,7 @@ Now when we run the program, we won’t get any errors, and we’ll see the following output: ```text -rect1 is Rectangle { width: 30, height: 50 } +{{#include ../listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt}} ``` Nice! It’s not the prettiest output, but it shows the values of all the fields @@ -246,10 +186,7 @@ those cases, we can use `{:#?}` instead of `{:?}` in the `println!` string. When we use the `{:#?}` style in the example, the output will look like this: ```text -rect1 is Rectangle { - width: 30, - height: 50 -} +{{#include ../listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt}} ``` Rust has provided a number of traits for us to use with the `derive` annotation diff --git a/src/ch05-03-method-syntax.md b/src/ch05-03-method-syntax.md index d8a338c9..f074497c 100644 --- a/src/ch05-03-method-syntax.md +++ b/src/ch05-03-method-syntax.md @@ -17,26 +17,7 @@ in Listing 5-13. Filename: src/main.rs ```rust -#[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() - ); -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs}} ``` Listing 5-13: Defining an `area` method on the @@ -90,6 +71,7 @@ provide. > automatically adds in `&`, `&mut`, or `*` so `object` matches the signature of > the method. In other words, the following are the same: > + > ```rust > # #[derive(Debug,Copy,Clone)] > # struct Point { @@ -130,14 +112,7 @@ method. Filename: src/main.rs ```rust,ignore -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)); -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs}} ``` Listing 5-14: Using the as-yet-unwritten `can_hold` @@ -169,21 +144,7 @@ Listing 5-13, shown in Listing 5-15. Filename: src/main.rs ```rust -# #[derive(Debug)] -# struct Rectangle { -# width: u32, -# height: u32, -# } -# -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 - } -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs:here}} ``` Listing 5-15: Implementing the `can_hold` method on @@ -212,17 +173,7 @@ specify the same value twice: Filename: src/main.rs ```rust -# #[derive(Debug)] -# struct Rectangle { -# width: u32, -# height: u32, -# } -# -impl Rectangle { - fn square(size: u32) -> Rectangle { - Rectangle { width: size, height: size } - } -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs:here}} ``` To call this associated function, we use the `::` syntax with the struct name; @@ -237,23 +188,7 @@ Each struct is allowed to have multiple `impl` blocks. For example, Listing in its own `impl` block. ```rust -# #[derive(Debug)] -# struct Rectangle { -# width: u32, -# height: u32, -# } -# -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 - } -} +{{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs:here}} ``` Listing 5-16: Rewriting Listing 5-15 using multiple `impl` diff --git a/src/ch06-01-defining-an-enum.md b/src/ch06-01-defining-an-enum.md index 0d25afbb..1067af06 100644 --- a/src/ch06-01-defining-an-enum.md +++ b/src/ch06-01-defining-an-enum.md @@ -19,10 +19,7 @@ listing the possible kinds an IP address can be, `V4` and `V6`. These are the variants of the enum: ```rust -enum IpAddrKind { - V4, - V6, -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:def}} ``` `IpAddrKind` is now a custom data type that we can use elsewhere in our code. @@ -32,13 +29,7 @@ enum IpAddrKind { We can create instances of each of the two variants of `IpAddrKind` like this: ```rust -# enum IpAddrKind { -# V4, -# V6, -# } -# -let four = IpAddrKind::V4; -let six = IpAddrKind::V6; +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:instance}} ``` Note that the variants of the enum are namespaced under its identifier, and we @@ -48,26 +39,13 @@ both values `IpAddrKind::V4` and `IpAddrKind::V6` are of the same type: `IpAddrKind`: ```rust -# enum IpAddrKind { -# V4, -# V6, -# } -# -fn route(ip_kind: IpAddrKind) { } +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:fn}} ``` And we can call this function with either variant: ```rust -# enum IpAddrKind { -# V4, -# V6, -# } -# -# fn route(ip_kind: IpAddrKind) { } -# -route(IpAddrKind::V4); -route(IpAddrKind::V6); +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs:fn_call}} ``` Using enums has even more advantages. Thinking more about our IP address type, @@ -76,25 +54,7 @@ only know what *kind* it is. Given that you just learned about structs in Chapter 5, you might tackle this problem as shown in Listing 6-1. ```rust -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"), -}; +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs:here}} ``` Listing 6-1: Storing the data and `IpAddrKind` variant of @@ -115,14 +75,7 @@ variant. This new definition of the `IpAddr` enum says that both `V4` and `V6` variants will have associated `String` values: ```rust -enum IpAddr { - V4(String), - V6(String), -} - -let home = IpAddr::V4(String::from("127.0.0.1")); - -let loopback = IpAddr::V6(String::from("::1")); +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs:here}} ``` We attach data to each variant of the enum directly, so there is no need for an @@ -136,14 +89,7 @@ still express `V6` addresses as one `String` value, we wouldn’t be able to wit a struct. Enums handle this case with ease: ```rust -enum IpAddr { - V4(u8, u8, u8, u8), - V6(String), -} - -let home = IpAddr::V4(127, 0, 0, 1); - -let loopback = IpAddr::V6(String::from("::1")); +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs:here}} ``` We’ve shown several different ways to define data structures to store version @@ -186,12 +132,7 @@ Let’s look at another example of an enum in Listing 6-2: this one has a wide variety of types embedded in its variants. ```rust -enum Message { - Quit, - Move { x: i32, y: i32 }, - Write(String), - ChangeColor(i32, i32, i32), -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs:here}} ``` Listing 6-2: A `Message` enum whose variants each store @@ -211,13 +152,7 @@ type. The following structs could hold the same data that the preceding enum variants hold: ```rust -struct QuitMessage; // unit struct -struct MoveMessage { - x: i32, - y: i32, -} -struct WriteMessage(String); // tuple struct -struct ChangeColorMessage(i32, i32, i32); // tuple struct +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs:here}} ``` But if we used the different structs, which each have their own type, we @@ -229,21 +164,7 @@ define methods on structs using `impl`, we’re also able to define methods on enums. Here’s a method named `call` that we could define on our `Message` enum: ```rust -# enum Message { -# Quit, -# Move { x: i32, y: i32 }, -# Write(String), -# ChangeColor(i32, i32, i32), -# } -# -impl Message { - fn call(&self) { - // method body would be defined here - } -} - -let m = Message::Write(String::from("hello")); -m.call(); +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs:here}} ``` The body of the method would use `self` to get the value that we called the @@ -319,10 +240,7 @@ For now, all you need to know is that `` means the `Some` variant of the using `Option` values to hold number types and string types: ```rust -let some_number = Some(5); -let some_string = Some("a string"); - -let absent_number: Option = None; +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs:here}} ``` If we use `None` rather than `Some`, we need to tell Rust what type of @@ -340,22 +258,13 @@ definitely a valid value. For example, this code won’t compile because it’s trying to add an `i8` to an `Option`: ```rust,ignore,does_not_compile -let x: i8 = 5; -let y: Option = Some(5); - -let sum = x + y; +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs:here}} ``` If we run this code, we get an error message like this: ```text -error[E0277]: the trait bound `i8: std::ops::Add>` is -not satisfied - --> - | -5 | let sum = x + y; - | ^ no implementation for `i8 + std::option::Option` - | +{{#include ../listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt}} ``` Intense! In effect, this error message means that Rust doesn’t understand how diff --git a/src/ch06-02-match.md b/src/ch06-02-match.md index b00459be..f4038086 100644 --- a/src/ch06-02-match.md +++ b/src/ch06-02-match.md @@ -20,21 +20,7 @@ similar way as the counting machine, determine which coin it is and return its value in cents, as shown here in Listing 6-3. ```rust -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, - } -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs:here}} ``` Listing 6-3: An enum and a `match` expression that has @@ -69,24 +55,7 @@ following code would print “Lucky penny!” every time the method was called w a `Coin::Penny` but would still return the last value of the block, `1`: ```rust -# enum Coin { -# Penny, -# Nickel, -# Dime, -# Quarter, -# } -# -fn value_in_cents(coin: Coin) -> u8 { - match coin { - Coin::Penny => { - println!("Lucky penny!"); - 1 - }, - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter => 25, - } -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs:here}} ``` ### Patterns that Bind to Values @@ -103,19 +72,7 @@ our `enum` by changing the `Quarter` variant to include a `UsState` value stored inside it, which we’ve done here in Listing 6-4. ```rust -#[derive(Debug)] // so we can inspect the state in a minute -enum UsState { - Alabama, - Alaska, - // --snip-- -} - -enum Coin { - Penny, - Nickel, - Dime, - Quarter(UsState), -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs:here}} ``` Listing 6-4: A `Coin` enum in which the `Quarter` variant @@ -132,30 +89,7 @@ pattern that matches values of the variant `Coin::Quarter`. When a quarter’s state. Then we can use `state` in the code for that arm, like so: ```rust -# #[derive(Debug)] -# enum UsState { -# Alabama, -# Alaska, -# } -# -# enum Coin { -# Penny, -# Nickel, -# Dime, -# Quarter(UsState), -# } -# -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 - }, - } -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs:here}} ``` If we were to call `value_in_cents(Coin::Quarter(UsState::Alaska))`, `coin` @@ -182,16 +116,7 @@ This function is very easy to write, thanks to `match`, and will look like Listing 6-5. ```rust -fn plus_one(x: Option) -> Option { - match x { - None => None, - Some(i) => Some(i + 1), - } -} - -let five = Some(5); -let six = plus_one(five); -let none = plus_one(None); +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:here}} ``` Listing 6-5: A function that uses a `match` expression on @@ -202,14 +127,14 @@ Let’s examine the first execution of `plus_one` in more detail. When we call value `Some(5)`. We then compare that against each match arm. ```rust,ignore -None => None, +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}} ``` The `Some(5)` value doesn’t match the pattern `None`, so we continue to the next arm. ```rust,ignore -Some(i) => Some(i + 1), +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:second_arm}} ``` Does `Some(5)` match `Some(i)`? Why yes it does! We have the same variant. The @@ -221,7 +146,7 @@ Now let’s consider the second call of `plus_one` in Listing 6-5, where `x` is `None`. We enter the `match` and compare to the first arm. ```rust,ignore -None => None, +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs:first_arm}} ``` It matches! There’s no value to add to, so the program stops and returns the @@ -240,11 +165,7 @@ There’s one other aspect of `match` we need to discuss. Consider this version of our `plus_one` function that has a bug and won’t compile: ```rust,ignore,does_not_compile -fn plus_one(x: Option) -> Option { - match x { - Some(i) => Some(i + 1), - } -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs:here}} ``` We didn’t handle the `None` case, so this code will cause a bug. Luckily, it’s @@ -252,11 +173,7 @@ a bug Rust knows how to catch. If we try to compile this code, we’ll get this error: ```text -error[E0004]: non-exhaustive patterns: `None` not covered - --> - | -6 | match x { - | ^ pattern `None` not covered +{{#include ../listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt}} ``` Rust knows that we didn’t cover every possible case and even knows which @@ -275,14 +192,7 @@ care about the values 1, 3, 5, and 7, we don’t want to have to list out 0, 2, special pattern `_` instead: ```rust -let some_u8_value = 0u8; -match some_u8_value { - 1 => println!("one"), - 3 => println!("three"), - 5 => println!("five"), - 7 => println!("seven"), - _ => (), -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-11-underscore-placeholder/src/main.rs:here}} ``` The `_` pattern will match any value. By putting it after our other arms, the diff --git a/src/ch06-03-if-let.md b/src/ch06-03-if-let.md index 65835463..3eb0cc34 100644 --- a/src/ch06-03-if-let.md +++ b/src/ch06-03-if-let.md @@ -6,11 +6,7 @@ program in Listing 6-6 that matches on an `Option` value but only wants to execute code if the value is 3. ```rust -let some_u8_value = Some(0u8); -match some_u8_value { - Some(3) => println!("three"), - _ => (), -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-06/src/main.rs:here}} ``` Listing 6-6: A `match` that only cares about executing @@ -25,10 +21,7 @@ Instead, we could write this in a shorter way using `if let`. The following code behaves the same as the `match` in Listing 6-6: ```rust -# let some_u8_value = Some(0u8); -if let Some(3) = some_u8_value { - println!("three"); -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-12-if-let/src/main.rs:here}} ``` The syntax `if let` takes a pattern and an expression separated by an equal @@ -53,48 +46,13 @@ announcing the state of the quarters, we could do that with a `match` expression like this: ```rust -# #[derive(Debug)] -# enum UsState { -# Alabama, -# Alaska, -# } -# -# enum Coin { -# Penny, -# Nickel, -# Dime, -# Quarter(UsState), -# } -# let coin = Coin::Penny; -let mut count = 0; -match coin { - Coin::Quarter(state) => println!("State quarter from {:?}!", state), - _ => count += 1, -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs:here}} ``` Or we could use an `if let` and `else` expression like this: ```rust -# #[derive(Debug)] -# enum UsState { -# Alabama, -# Alaska, -# } -# -# enum Coin { -# Penny, -# Nickel, -# Dime, -# Quarter(UsState), -# } -# let coin = Coin::Penny; -let mut count = 0; -if let Coin::Quarter(state) = coin { - println!("State quarter from {:?}!", state); -} else { - count += 1; -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs:here}} ``` If you have a situation in which your program has logic that is too verbose to diff --git a/src/ch07-02-defining-modules-to-control-scope-and-privacy.md b/src/ch07-02-defining-modules-to-control-scope-and-privacy.md index d2674f3f..d46ef9b0 100644 --- a/src/ch07-02-defining-modules-to-control-scope-and-privacy.md +++ b/src/ch07-02-defining-modules-to-control-scope-and-privacy.md @@ -29,22 +29,8 @@ Listing 7-1 into *src/lib.rs* to define some modules and function signatures. Filename: src/lib.rs -```rust,ignore -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() {} - } -} +```rust +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs:here}} ``` Listing 7-1: A `front_of_house` module containing other diff --git a/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md b/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md index ad584b72..d765a663 100644 --- a/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md +++ b/src/ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md @@ -28,19 +28,7 @@ in a bit. Filename: src/lib.rs ```rust,ignore,does_not_compile -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(); -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs}} ``` Listing 7-3: Calling the `add_to_waitlist` function using @@ -80,19 +68,7 @@ Let’s try to compile Listing 7-3 and find out why it won’t compile yet! The error we get is shown in Listing 7-4. ```text -$ 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(); - | ^^^^^^^ - -error[E0603]: module `hosting` is private - --> src/lib.rs:12:21 - | -12 | front_of_house::hosting::add_to_waitlist(); - | ^^^^^^^ +{{#include ../listings/ch07-managing-growing-projects/listing-07-03/output.txt}} ``` Listing 7-4: Compiler errors from building the code in @@ -134,19 +110,7 @@ access to the `add_to_waitlist` function in the child module, so we mark the Filename: src/lib.rs ```rust,ignore,does_not_compile -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(); -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs}} ``` Listing 7-5: Declaring the `hosting` module as `pub` to @@ -156,19 +120,7 @@ Unfortunately, the code in Listing 7-5 still results in an error, as shown in Listing 7-6. ```text -$ 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(); - | ^^^^^^^^^^^^^^^ - -error[E0603]: function `add_to_waitlist` is private - --> src/lib.rs:12:30 - | -12 | front_of_house::hosting::add_to_waitlist(); - | ^^^^^^^^^^^^^^^ +{{#include ../listings/ch07-managing-growing-projects/listing-07-05/output.txt}} ``` Listing 7-6: Compiler errors from building the code in @@ -190,20 +142,7 @@ keyword before its definition, as in Listing 7-7. Filename: src/lib.rs ```rust -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(); -} -# fn main() {} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs:here}} ``` Listing 7-7: Adding the `pub` keyword to `mod hosting` @@ -246,17 +185,7 @@ the path to `serve_order` starting with `super`: Filename: src/lib.rs ```rust -fn serve_order() {} - -mod back_of_house { - fn fix_incorrect_order() { - cook_order(); - super::serve_order(); - } - - fn cook_order() {} -} -# fn main() {} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs:here}} ``` Listing 7-8: Calling a function using a relative path @@ -287,33 +216,7 @@ or even see which fruit they’ll get. Filename: src/lib.rs ```rust -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"); -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs}} ``` Listing 7-9: A struct with some public fields and some @@ -338,17 +241,7 @@ only need the `pub` before the `enum` keyword, as shown in Listing 7-10. Filename: src/lib.rs ```rust -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; -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs}} ``` Listing 7-10: Designating an enum as public makes all its diff --git a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md index 05af46cb..94af9db4 100644 --- a/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md +++ b/src/ch07-04-bringing-paths-into-scope-with-the-use-keyword.md @@ -16,20 +16,7 @@ scope of the `eat_at_restaurant` function so we only have to specify Filename: src/lib.rs ```rust -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(); -} -# fn main() {} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs:here}} ``` Listing 7-11: Bringing a module into scope with @@ -48,20 +35,7 @@ Listing 7-11. Filename: src/lib.rs ```rust -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -use front_of_house::hosting; - -pub fn eat_at_restaurant() { - hosting::add_to_waitlist(); - hosting::add_to_waitlist(); - hosting::add_to_waitlist(); -} -# fn main() {} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs:here}} ``` Listing 7-12: Bringing a module into scope with `use` and @@ -77,20 +51,7 @@ the `add_to_waitlist` function to achieve the same result, as in Listing 7-13. Filename: src/lib.rs ```rust -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(); -} -# fn main() {} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs:here}} ``` Listing 7-13: Bringing the `add_to_waitlist` function @@ -111,12 +72,7 @@ crate. Filename: src/main.rs ```rust -use std::collections::HashMap; - -fn main() { - let mut map = HashMap::new(); - map.insert(1, 2); -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-14/src/main.rs}} ``` Listing 7-14: Bringing `HashMap` into scope in an @@ -133,18 +89,7 @@ different parent modules and how to refer to them. Filename: src/lib.rs ```rust -use std::fmt; -use std::io; - -fn function1() -> fmt::Result { - // --snip-- -# Ok(()) -} - -fn function2() -> io::Result<()> { - // --snip-- -# Ok(()) -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-15/src/lib.rs:here}} ``` Listing 7-15: Bringing two types with the same name into @@ -165,18 +110,7 @@ code in Listing 7-15 by renaming one of the two `Result` types using `as`. Filename: src/lib.rs ```rust -use std::fmt::Result; -use std::io::Result as IoResult; - -fn function1() -> Result { - // --snip-- -# Ok(()) -} - -fn function2() -> IoResult<()> { - // --snip-- -# Ok(()) -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-16/src/lib.rs:here}} ``` Listing 7-16: Renaming a type when it’s brought into @@ -202,20 +136,7 @@ changed to `pub use`. Filename: src/lib.rs ```rust -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(); -} -# fn main() {} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs:here}} ``` Listing 7-17: Making a name available for any code to use @@ -250,8 +171,7 @@ added this line to *Cargo.toml*: Filename: Cargo.toml ```toml -[dependencies] -rand = "0.5.5" +{{#include ../listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml:9:}} ``` Adding `rand` as a dependency in *Cargo.toml* tells Cargo to download the @@ -265,10 +185,7 @@ Number”][rand] section in Chapter 2, we brought the `Rng` trait into scope and called the `rand::thread_rng` function: ```rust,ignore -use rand::Rng; -fn main() { - let secret_number = rand::thread_rng().gen_range(1, 101); -} +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs:ch07-04}} ``` Members of the Rust community have made many packages available at @@ -299,9 +216,7 @@ Listing 2-4 bring items from `std` into scope: Filename: src/main.rs ```rust -use std::io; -use std::cmp::Ordering; -// ---snip--- +{{#include ../listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs:here}} ``` Instead, we can use nested paths to bring the same items into scope in one @@ -312,8 +227,8 @@ differ, as shown in Listing 7-18. Filename: src/main.rs ```rust -use std::{cmp::Ordering, io}; -// ---snip--- +{{#include ../listings/ch07-managing-growing-projects/listing-07-18/src/main.rs:1}} +// --snip-- ``` Listing 7-18: Specifying a nested path to bring multiple @@ -331,8 +246,7 @@ two `use` statements that share a subpath. For example, Listing 7-19 shows two Filename: src/lib.rs ```rust -use std::io; -use std::io::Write; +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-19/src/lib.rs}} ``` Listing 7-19: Two `use` statements where one is a subpath @@ -345,7 +259,7 @@ the nested path, as shown in Listing 7-20. Filename: src/lib.rs ```rust -use std::io::{self, Write}; +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-20/src/lib.rs}} ``` Listing 7-20: Combining the paths in Listing 7-19 into diff --git a/src/ch07-05-separating-modules-into-different-files.md b/src/ch07-05-separating-modules-into-different-files.md index 6b51859a..713ec881 100644 --- a/src/ch07-05-separating-modules-into-different-files.md +++ b/src/ch07-05-separating-modules-into-different-files.md @@ -13,15 +13,7 @@ crates whose crate root file is *src/main.rs*. Filename: src/lib.rs ```rust,ignore -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(); -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs}} ``` Listing 7-21: Declaring the `front_of_house` module whose @@ -33,9 +25,7 @@ And *src/front_of_house.rs* gets the definitions from the body of the Filename: src/front_of_house.rs ```rust -pub mod hosting { - pub fn add_to_waitlist() {} -} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs}} ``` Listing 7-22: Definitions inside the `front_of_house` @@ -50,7 +40,7 @@ declaration of the `hosting` module: Filename: src/front_of_house.rs ``` -pub mod hosting; +{{#rustdoc_include ../listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house.rs}} ``` Then we create a *src/front_of_house* directory and a file @@ -60,7 +50,7 @@ Then we create a *src/front_of_house* directory and a file Filename: src/front_of_house/hosting.rs ``` -pub fn add_to_waitlist() {} +{{#rustdoc_include ../listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs}} ``` The module tree remains the same, and the function calls in `eat_at_restaurant` diff --git a/src/ch08-01-vectors.md b/src/ch08-01-vectors.md index aaf15381..5f604cbc 100644 --- a/src/ch08-01-vectors.md +++ b/src/ch08-01-vectors.md @@ -12,7 +12,7 @@ To create a new, empty vector, we can call the `Vec::new` function, as shown in Listing 8-1. ```rust -let v: Vec = Vec::new(); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-01/src/main.rs:here}} ``` Listing 8-1: Creating a new, empty vector to hold values @@ -35,7 +35,7 @@ that holds the values you give it. Listing 8-2 creates a new `Vec` that holds the values `1`, `2`, and `3`. ```rust -let v = vec![1, 2, 3]; +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-02/src/main.rs:here}} ``` Listing 8-2: Creating a new vector containing @@ -51,12 +51,7 @@ To create a vector and then add elements to it, we can use the `push` method, as shown in Listing 8-3. ```rust -let mut v = Vec::new(); - -v.push(5); -v.push(6); -v.push(7); -v.push(8); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-03/src/main.rs:here}} ``` Listing 8-3: Using the `push` method to add values to a @@ -73,12 +68,7 @@ Like any other `struct`, a vector is freed when it goes out of scope, as annotated in Listing 8-4. ```rust -{ - let v = vec![1, 2, 3, 4]; - - // do stuff with v - -} // <- v goes out of scope and is freed here +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-04/src/main.rs:here}} ``` Listing 8-4: Showing where the vector and its elements @@ -100,15 +90,7 @@ Listing 8-5 shows both methods of accessing a value in a vector, either with indexing syntax or the `get` method. ```rust -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."), -} +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-05/src/main.rs:here}} ``` Listing 8-5: Using indexing syntax or the `get` method to @@ -127,10 +109,7 @@ that holds five elements and then tries to access an element at index 100, as shown in Listing 8-6. ```rust,should_panic,panics -let v = vec![1, 2, 3, 4, 5]; - -let does_not_exist = &v[100]; -let does_not_exist = v.get(100); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-06/src/main.rs:here}} ``` Listing 8-6: Attempting to access the element at index @@ -160,13 +139,7 @@ the first element in a vector and try to add an element to the end, which won’ work. ```rust,ignore,does_not_compile -let mut v = vec![1, 2, 3, 4, 5]; - -let first = &v[0]; - -v.push(6); - -println!("The first element is: {}", first); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-07/src/main.rs:here}} ``` Listing 8-7: Attempting to add an element to a vector @@ -175,17 +148,7 @@ while holding a reference to an item Compiling this code will result in this error: ```text -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 +{{#include ../listings/ch08-common-collections/listing-08-07/output.txt}} ``` The code in Listing 8-7 might look like it should work: why should a reference @@ -208,10 +171,7 @@ all of the elements rather than use indices to access one at a time. Listing in a vector of `i32` values and print them. ```rust -let v = vec![100, 32, 57]; -for i in &v { - println!("{}", i); -} +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-08/src/main.rs:here}} ``` Listing 8-8: Printing each element in a vector by @@ -222,10 +182,7 @@ in order to make changes to all the elements. The `for` loop in Listing 8-9 will add `50` to each element. ```rust -let mut v = vec![100, 32, 57]; -for i in &mut v { - *i += 50; -} +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-09/src/main.rs:here}} ``` Listing 8-9: Iterating over mutable references to @@ -253,17 +210,7 @@ that of the enum. Then we can create a vector that holds that enum and so, ultimately, holds different types. We’ve demonstrated this in Listing 8-10. ```rust -enum SpreadsheetCell { - Int(i32), - Float(f64), - Text(String), -} - -let row = vec![ - SpreadsheetCell::Int(3), - SpreadsheetCell::Text(String::from("blue")), - SpreadsheetCell::Float(10.12), -]; +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-10/src/main.rs:here}} ``` Listing 8-10: Defining an `enum` to store values of diff --git a/src/ch08-02-strings.md b/src/ch08-02-strings.md index f09ebbb9..bcee93eb 100644 --- a/src/ch08-02-strings.md +++ b/src/ch08-02-strings.md @@ -48,7 +48,7 @@ as well, starting with the `new` function to create a string, shown in Listing 8-11. ```rust -let mut s = String::new(); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-11/src/main.rs:here}} ``` Listing 8-11: Creating a new, empty `String` @@ -60,12 +60,7 @@ that implements the `Display` trait, as string literals do. Listing 8-12 shows two examples. ```rust -let data = "initial contents"; - -let s = data.to_string(); - -// the method also works on a literal directly: -let s = "initial contents".to_string(); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-12/src/main.rs:here}} ``` Listing 8-12: Using the `to_string` method to create a @@ -78,7 +73,7 @@ literal. The code in Listing 8-13 is equivalent to the code from Listing 8-12 that uses `to_string`. ```rust -let s = String::from("initial contents"); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-13/src/main.rs:here}} ``` Listing 8-13: Using the `String::from` function to create @@ -93,17 +88,7 @@ Remember that strings are UTF-8 encoded, so we can include any properly encoded data in them, as shown in Listing 8-14. ```rust -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á"); -let hello = String::from("Здравствуйте"); -let hello = String::from("Hola"); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-14/src/main.rs:here}} ``` Listing 8-14: Storing greetings in different languages in @@ -123,8 +108,7 @@ We can grow a `String` by using the `push_str` method to append a string slice, as shown in Listing 8-15. ```rust -let mut s = String::from("foo"); -s.push_str("bar"); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-15/src/main.rs:here}} ``` Listing 8-15: Appending a string slice to a `String` @@ -136,10 +120,7 @@ parameter. For example, the code in Listing 8-16 shows that it would be unfortunate if we weren’t able to use `s2` after appending its contents to `s1`. ```rust -let mut s1 = String::from("foo"); -let s2 = "bar"; -s1.push_str(s2); -println!("s2 is {}", s2); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-16/src/main.rs:here}} ``` Listing 8-16: Using a string slice after appending its @@ -153,8 +134,7 @@ The `push` method takes a single character as a parameter and adds it to the the `push` method. ```rust -let mut s = String::from("lo"); -s.push('l'); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-17/src/main.rs:here}} ``` Listing 8-17: Adding one character to a `String` value @@ -168,9 +148,7 @@ Often, you’ll want to combine two existing strings. One way is to use the `+` operator, as shown in Listing 8-18. ```rust -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 +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-18/src/main.rs:here}} ``` Listing 8-18: Using the `+` operator to combine two @@ -219,11 +197,7 @@ If we need to concatenate multiple strings, the behavior of the `+` operator gets unwieldy: ```rust -let s1 = String::from("tic"); -let s2 = String::from("tac"); -let s3 = String::from("toe"); - -let s = s1 + "-" + &s2 + "-" + &s3; +{{#rustdoc_include ../listings/ch08-common-collections/no-listing-01-concat-multiple-strings/src/main.rs:here}} ``` At this point, `s` will be `tic-tac-toe`. With all of the `+` and `"` @@ -231,11 +205,7 @@ characters, it’s difficult to see what’s going on. For more complicated stri combining, we can use the `format!` macro: ```rust -let s1 = String::from("tic"); -let s2 = String::from("tac"); -let s3 = String::from("toe"); - -let s = format!("{}-{}-{}", s1, s2, s3); +{{#rustdoc_include ../listings/ch08-common-collections/no-listing-02-format/src/main.rs:here}} ``` This code also sets `s` to `tic-tac-toe`. The `format!` macro works in the same @@ -251,8 +221,7 @@ if you try to access parts of a `String` using indexing syntax in Rust, you’ll get an error. Consider the invalid code in Listing 8-19. ```rust,ignore,does_not_compile -let s1 = String::from("hello"); -let h = s1[0]; +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-19/src/main.rs:here}} ``` Listing 8-19: Attempting to use indexing syntax with a @@ -261,13 +230,7 @@ String This code will result in the following error: ```text -error[E0277]: the trait bound `std::string::String: std::ops::Index<{integer}>` is not satisfied - --> - | -3 | let h = s1[0]; - | ^^^^^ the type `std::string::String` cannot be indexed by `{integer}` - | - = help: the trait `std::ops::Index<{integer}>` is not implemented for `std::string::String` +{{#include ../listings/ch08-common-collections/listing-08-19/output.txt}} ``` The error and the note tell the story: Rust strings don’t support indexing. But @@ -280,7 +243,7 @@ A `String` is a wrapper over a `Vec`. Let’s look at some of our properly encoded UTF-8 example strings from Listing 8-14. First, this one: ```rust -let len = String::from("Hola").len(); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-14/src/main.rs:spanish}} ``` In this case, `len` will be 4, which means the vector storing the string “Hola” @@ -289,7 +252,7 @@ what about the following line? (Note that this string begins with the capital Cyrillic letter Ze, not the Arabic number 3.) ```rust -let len = String::from("Здравствуйте").len(); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-14/src/main.rs:russian}} ``` Asked how long the string is, you might say 12. However, Rust’s answer is 24: @@ -380,7 +343,7 @@ What would happen if we used `&hello[0..1]`? The answer: Rust would panic at runtime in the same way as if an invalid index were accessed in a vector: ```text -thread 'main' panicked at 'byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of `Здравствуйте`', src/libcore/str/mod.rs:2188:4 +{{#include ../listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt}} ``` You should use ranges to create string slices with caution, because doing so diff --git a/src/ch08-03-hash-maps.md b/src/ch08-03-hash-maps.md index f140805d..d76b4445 100644 --- a/src/ch08-03-hash-maps.md +++ b/src/ch08-03-hash-maps.md @@ -25,12 +25,7 @@ Blue and Yellow. The Blue team starts with 10 points, and the Yellow team starts with 50. ```rust -use std::collections::HashMap; - -let mut scores = HashMap::new(); - -scores.insert(String::from("Blue"), 10); -scores.insert(String::from("Yellow"), 50); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-20/src/main.rs:here}} ``` Listing 8-20: Creating a new hash map and inserting some @@ -56,12 +51,7 @@ where “Blue” is paired with 10, and so forth. Then we could use the `collect method to turn that vector of tuples into a hash map, as shown in Listing 8-21. ```rust -use std::collections::HashMap; - -let teams = vec![String::from("Blue"), String::from("Yellow")]; -let initial_scores = vec![10, 50]; - -let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect(); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-21/src/main.rs:here}} ``` Listing 8-21: Creating a hash map from a list of teams @@ -80,15 +70,7 @@ into the hash map. For owned values like `String`, the values will be moved and the hash map will be the owner of those values, as demonstrated in Listing 8-22. ```rust -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! +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-22/src/main.rs:here}} ``` Listing 8-22: Showing that keys and values are owned by @@ -110,15 +92,7 @@ We can get a value out of the hash map by providing its key to the `get` method, as shown in Listing 8-23. ```rust -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); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-23/src/main.rs:here}} ``` Listing 8-23: Accessing the score for the Blue team @@ -134,16 +108,7 @@ We can iterate over each key/value pair in a hash map in a similar manner as we do with vectors, using a `for` loop: ```rust -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); -} +{{#rustdoc_include ../listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs:here}} ``` This code will print each pair in an arbitrary order: @@ -173,14 +138,7 @@ only contain one key/value pair because we’re inserting the value for the Blue team’s key both times. ```rust -use std::collections::HashMap; - -let mut scores = HashMap::new(); - -scores.insert(String::from("Blue"), 10); -scores.insert(String::from("Blue"), 25); - -println!("{:?}", scores); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-24/src/main.rs:here}} ``` Listing 8-24: Replacing a value stored with a particular @@ -201,15 +159,7 @@ and the same for the Blue team. Using the `entry` API, the code looks like Listing 8-25. ```rust -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); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-25/src/main.rs:here}} ``` Listing 8-25: Using the `entry` method to only insert if @@ -237,18 +187,7 @@ seen that word. If it’s the first time we’ve seen a word, we’ll first inse the value 0. ```rust -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); +{{#rustdoc_include ../listings/ch08-common-collections/listing-08-26/src/main.rs:here}} ``` Listing 8-26: Counting occurrences of words using a hash diff --git a/src/ch09-01-unrecoverable-errors-with-panic.md b/src/ch09-01-unrecoverable-errors-with-panic.md index 454b7807..69ec2327 100644 --- a/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/src/ch09-01-unrecoverable-errors-with-panic.md @@ -29,20 +29,13 @@ Let’s try calling `panic!` in a simple program: Filename: src/main.rs ```rust,should_panic,panics -fn main() { - panic!("crash and burn"); -} +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-01-panic/src/main.rs}} ``` When you run the program, you’ll see something like this: ```text -$ 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` for a backtrace. +{{#include ../listings/ch09-error-handling/no-listing-01-panic/output.txt}} ``` The call to `panic!` causes the error message contained in the last two lines. @@ -69,11 +62,7 @@ element by index in a vector. Filename: src/main.rs ```rust,should_panic,panics -fn main() { - let v = vec![1, 2, 3]; - - v[99]; -} +{{#rustdoc_include ../listings/ch09-error-handling/listing-09-01/src/main.rs}} ``` Listing 9-1: Attempting to access an element beyond the @@ -98,12 +87,7 @@ element at an index that doesn’t exist, Rust will stop execution and refuse to continue. Let’s try it and see: ```text -$ 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', libcore/slice/mod.rs:2448:10 -note: Run with `RUST_BACKTRACE=1` for a backtrace. +{{#include ../listings/ch09-error-handling/listing-09-01/output.txt}} ``` This error points at a file we didn’t write, *libcore/slice/mod.rs*. That’s the @@ -123,53 +107,63 @@ library code, or crates that you’re using. Let’s try getting a backtrace by setting the `RUST_BACKTRACE` environment variable to any value except 0. Listing 9-2 shows output similar to what you’ll see. + + ```text $ RUST_BACKTRACE=1 cargo run - Finished dev [unoptimized + debuginfo] target(s) in 0.00s - Running `target/debug/panic` -thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', libcore/slice/mod.rs:2448:10 +thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/slice/mod.rs:2681:10 stack backtrace: - 0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace - at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49 - 1: std::sys_common::backtrace::print - at libstd/sys_common/backtrace.rs:71 - at libstd/sys_common/backtrace.rs:59 - 2: std::panicking::default_hook::{{closure}} - at libstd/panicking.rs:211 - 3: std::panicking::default_hook - at libstd/panicking.rs:227 - 4: as core::panic::BoxMeUp>::get - at libstd/panicking.rs:476 - 5: std::panicking::continue_panic_fmt - at libstd/panicking.rs:390 - 6: std::panicking::try::do_call - at libstd/panicking.rs:325 - 7: core::ptr::drop_in_place - at libcore/panicking.rs:77 - 8: core::ptr::drop_in_place - at libcore/panicking.rs:59 - 9: >::index - at libcore/slice/mod.rs:2448 - 10: core::slice:: for [T]>::index - at libcore/slice/mod.rs:2316 - 11: as core::ops::index::Index>::index - at liballoc/vec.rs:1653 - 12: panic::main + 0: backtrace::backtrace::libunwind::trace + at /Users/vsts/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88 + 1: backtrace::backtrace::trace_unsynchronized + at /Users/vsts/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66 + 2: std::sys_common::backtrace::_print + at src/libstd/sys_common/backtrace.rs:47 + 3: std::sys_common::backtrace::print + at src/libstd/sys_common/backtrace.rs:36 + 4: std::panicking::default_hook::{{closure}} + at src/libstd/panicking.rs:200 + 5: std::panicking::default_hook + at src/libstd/panicking.rs:214 + 6: std::panicking::rust_panic_with_hook + at src/libstd/panicking.rs:477 + 7: std::panicking::continue_panic_fmt + at src/libstd/panicking.rs:384 + 8: rust_begin_unwind + at src/libstd/panicking.rs:311 + 9: core::panicking::panic_fmt + at src/libcore/panicking.rs:85 + 10: core::panicking::panic_bounds_check + at src/libcore/panicking.rs:61 + 11: >::index + at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/slice/mod.rs:2681 + 12: core::slice:: for [T]>::index + at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/slice/mod.rs:2538 + 13: as core::ops::index::Index>::index + at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/liballoc/vec.rs:1756 + 14: panic::main at src/main.rs:4 - 13: std::rt::lang_start::{{closure}} - at libstd/rt.rs:74 - 14: std::panicking::try::do_call - at libstd/rt.rs:59 - at libstd/panicking.rs:310 - 15: macho_symbol_search - at libpanic_unwind/lib.rs:102 - 16: std::alloc::default_alloc_error_hook - at libstd/panicking.rs:289 - at libstd/panic.rs:392 - at libstd/rt.rs:58 - 17: std::rt::lang_start - at libstd/rt.rs:74 - 18: panic::main + 15: std::rt::lang_start::{{closure}} + at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libstd/rt.rs:64 + 16: std::rt::lang_start_internal::{{closure}} + at src/libstd/rt.rs:49 + 17: std::panicking::try::do_call + at src/libstd/panicking.rs:296 + 18: __rust_maybe_catch_panic + at src/libpanic_unwind/lib.rs:82 + 19: std::panicking::try + at src/libstd/panicking.rs:275 + 20: std::panic::catch_unwind + at src/libstd/panic.rs:394 + 21: std::rt::lang_start_internal + at src/libstd/rt.rs:48 + 22: std::rt::lang_start + at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libstd/rt.rs:64 + 23: panic::main ``` Listing 9-2: The backtrace generated by a call to @@ -181,7 +175,7 @@ information, debug symbols must be enabled. Debug symbols are enabled by default when using `cargo build` or `cargo run` without the `--release` flag, as we have here. -In the output in Listing 9-2, line 12 of the backtrace points to the line in +In the output in Listing 9-2, line 14 of the backtrace points to the line in our project that’s causing the problem: line 4 of *src/main.rs*. If we don’t want our program to panic, the location pointed to by the first line mentioning a file we wrote is where we should start investigating. In Listing 9-1, where diff --git a/src/ch09-02-recoverable-errors-with-result.md b/src/ch09-02-recoverable-errors-with-result.md index 8461e2bf..26f9e512 100644 --- a/src/ch09-02-recoverable-errors-with-result.md +++ b/src/ch09-02-recoverable-errors-with-result.md @@ -34,11 +34,7 @@ fail. In Listing 9-3 we try to open a file. Filename: src/main.rs ```rust -use std::fs::File; - -fn main() { - let f = File::open("hello.txt"); -} +{{#rustdoc_include ../listings/ch09-error-handling/listing-09-03/src/main.rs}} ``` Listing 9-3: Opening a file @@ -52,21 +48,13 @@ type of `f` *is*. Let’s try it! We know that the return type of `File::open` isn’t of type `u32`, so let’s change the `let f` statement to this: ```rust,ignore,does_not_compile -let f: u32 = File::open("hello.txt"); +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/src/main.rs:here}} ``` Attempting to compile now gives us the following output: ```text -error[E0308]: mismatched types - --> src/main.rs:4:18 - | -4 | let f: u32 = File::open("hello.txt"); - | ^^^^^^^^^^^^^^^^^^^^^^^ expected u32, found enum -`std::result::Result` - | - = note: expected type `u32` - found type `std::result::Result` +{{#include ../listings/ch09-error-handling/no-listing-02-ask-compiler-for-type/output.txt}} ``` This tells us the return type of the `File::open` function is a `Result`. @@ -95,18 +83,7 @@ Chapter 6. Filename: src/main.rs ```rust,should_panic -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) - }, - }; -} +{{#rustdoc_include ../listings/ch09-error-handling/listing-09-04/src/main.rs}} ``` Listing 9-4: Using a `match` expression to handle the @@ -127,8 +104,7 @@ there’s no file named *hello.txt* in our current directory and we run this code, we’ll see the following output from the `panic!` macro: ```text -thread 'main' panicked at 'Problem opening the file: Error { repr: -Os { code: 2, message: "No such file or directory" } }', src/main.rs:9:12 +{{#include ../listings/ch09-error-handling/listing-09-04/output.txt}} ``` As usual, this output tells us exactly what has gone wrong. @@ -149,23 +125,7 @@ at Listing 9-5, which adds an inner `match` expression. tests to fail lol --> ```rust,ignore -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), - }, - }; -} +{{#rustdoc_include ../listings/ch09-error-handling/listing-09-05/src/main.rs}} ``` Listing 9-5: Handling different kinds of errors in @@ -195,20 +155,7 @@ E>` type has many methods that accept a closure and are implemented using more seasoned Rustacean might write this code instead of Listing 9-5: ```rust,ignore -use std::fs::File; -use std::io::ErrorKind; - -fn main() { - let f = File::open("hello.txt").unwrap_or_else(|error| { - if error.kind() == ErrorKind::NotFound { - File::create("hello.txt").unwrap_or_else(|error| { - panic!("Problem creating the file: {:?}", error); - }) - } else { - panic!("Problem opening the file: {:?}", error); - } - }); -} +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-03-closures/src/main.rs}} ``` Although this code has the same behavior as Listing 9-5, it doesn’t contain any @@ -230,11 +177,7 @@ call the `panic!` macro for us. Here is an example of `unwrap` in action: Filename: src/main.rs ```rust,should_panic -use std::fs::File; - -fn main() { - let f = File::open("hello.txt").unwrap(); -} +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs}} ``` If we run this code without a *hello.txt* file, we’ll see an error message from @@ -254,11 +197,7 @@ panic easier. The syntax of `expect` looks like this: Filename: src/main.rs ```rust,should_panic -use std::fs::File; - -fn main() { - let f = File::open("hello.txt").expect("Failed to open hello.txt"); -} +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-05-expect/src/main.rs}} ``` We use `expect` in the same way as `unwrap`: to return the file handle or call @@ -292,26 +231,12 @@ to the code that called this function. Filename: src/main.rs + + ```rust -use std::io; -use std::io::Read; -use std::fs::File; - -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), - } -} +{{#include ../listings/ch09-error-handling/listing-09-06/src/main.rs:here}} ``` Listing 9-6: A function that returns errors to the @@ -372,17 +297,12 @@ same functionality as it had in Listing 9-6, but this implementation uses the Filename: src/main.rs -```rust -use std::io; -use std::io::Read; -use std::fs::File; + -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) -} +```rust +{{#include ../listings/ch09-error-handling/listing-09-07/src/main.rs:here}} ``` Listing 9-7: A function that returns errors to the @@ -420,18 +340,12 @@ method calls immediately after the `?`, as shown in Listing 9-8. Filename: src/main.rs + + ```rust -use std::io; -use std::io::Read; -use std::fs::File; - -fn read_username_from_file() -> Result { - let mut s = String::new(); - - File::open("hello.txt")?.read_to_string(&mut s)?; - - Ok(s) -} +{{#include ../listings/ch09-error-handling/listing-09-08/src/main.rs:here}} ``` Listing 9-8: Chaining method calls after the `?` @@ -451,13 +365,12 @@ there’s a way to make this even shorter. Filename: src/main.rs -```rust -use std::io; -use std::fs; + -fn read_username_from_file() -> Result { - fs::read_to_string("hello.txt") -} +```rust +{{#include ../listings/ch09-error-handling/listing-09-09/src/main.rs:here}} ``` Listing 9-9: Using `fs::read_to_string` instead of @@ -482,26 +395,13 @@ Let’s look at what happens if we use the `?` operator in the `main` function, which you’ll recall has a return type of `()`: ```rust,ignore,does_not_compile -use std::fs::File; - -fn main() { - let f = File::open("hello.txt")?; -} +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-06-question-mark-in-main/src/main.rs}} ``` When we compile this code, we get the following error message: ```text -error[E0277]: the `?` operator can only be used in a function that returns -`Result` or `Option` (or another type that implements `std::ops::Try`) - --> src/main.rs:4:13 - | -4 | let f = File::open("hello.txt")?; - | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot use the `?` operator in a - function that returns `()` - | - = help: the trait `std::ops::Try` is not implemented for `()` - = note: required by `std::ops::Try::from_error` +{{#include ../listings/ch09-error-handling/no-listing-06-question-mark-in-main/output.txt}} ``` This error points out that we’re only allowed to use the `?` operator in a @@ -519,14 +419,7 @@ type must be. One valid return type for main is `()`, and conveniently, another valid return type is `Result`, as shown here: ```rust,ignore -use std::error::Error; -use std::fs::File; - -fn main() -> Result<(), Box> { - let f = File::open("hello.txt")?; - - Ok(()) -} +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-07-main-returning-result/src/main.rs}} ``` The `Box` type is called a trait object, which we’ll talk about in diff --git a/src/ch09-03-to-panic-or-not-to-panic.md b/src/ch09-03-to-panic-or-not-to-panic.md index a8f6965b..e5af81d0 100644 --- a/src/ch09-03-to-panic-or-not-to-panic.md +++ b/src/ch09-03-to-panic-or-not-to-panic.md @@ -48,9 +48,7 @@ have an `Err` variant, it’s perfectly acceptable to call `unwrap`. Here’s an example: ```rust -use std::net::IpAddr; - -let home: IpAddr = "127.0.0.1".parse().unwrap(); +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs:here}} ``` We’re creating an `IpAddr` instance by parsing a hardcoded string. We can see @@ -133,22 +131,7 @@ One way to do this would be to parse the guess as an `i32` instead of only a number being in range, like so: ```rust,ignore -loop { - // --snip-- - - 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-- -} +{{#rustdoc_include ../listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs:here}} ``` The `if` expression checks whether our value is out of range, tells the user @@ -169,26 +152,13 @@ confidently use the values they receive. Listing 9-10 shows one way to define a `Guess` type that will only create an instance of `Guess` if the `new` function receives a value between 1 and 100. + + ```rust -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 - } -} +{{#include ../listings/ch09-error-handling/listing-09-10/src/main.rs:here}} ``` Listing 9-10: A `Guess` type that will only continue with diff --git a/src/ch10-00-generics.md b/src/ch10-00-generics.md index b411210b..032f4374 100644 --- a/src/ch10-00-generics.md +++ b/src/ch10-00-generics.md @@ -41,20 +41,7 @@ Listing 10-1. Filename: src/main.rs ```rust -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); -# assert_eq!(largest, 100); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs:here}} ``` Listing 10-1: Code to find the largest number in a list @@ -76,31 +63,7 @@ program, as shown in Listing 10-2. Filename: src/main.rs ```rust -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); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs}} ``` Listing 10-2: Code to find the largest number in *two* @@ -122,31 +85,7 @@ number in two different lists. Filename: src/main.rs ```rust -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); -# assert_eq!(result, 100); - - let number_list = vec![102, 34, 6000, 89, 54, 2, 43, 8]; - - let result = largest(&number_list); - println!("The largest number is {}", result); -# assert_eq!(result, 6000); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs:here}} ``` Listing 10-3: Abstracted code to find the largest number diff --git a/src/ch10-01-syntax.md b/src/ch10-01-syntax.md index f69165e2..3d86ebfa 100644 --- a/src/ch10-01-syntax.md +++ b/src/ch10-01-syntax.md @@ -18,43 +18,7 @@ both find the largest value in a slice. Filename: src/main.rs ```rust -fn largest_i32(list: &[i32]) -> i32 { - let mut largest = list[0]; - - for &item in list.iter() { - if item > largest { - largest = item; - } - } - - largest -} - -fn largest_char(list: &[char]) -> char { - let mut largest = list[0]; - - for &item in list.iter() { - 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); -# assert_eq!(result, 100); - - let char_list = vec!['y', 'm', 'a', 'q']; - - let result = largest_char(&char_list); - println!("The largest char is {}", result); -# assert_eq!(result, 'y'); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs:here}} ``` Listing 10-4: Two functions that differ only in their @@ -95,29 +59,7 @@ compile yet, but we’ll fix it later in this chapter. Filename: src/main.rs ```rust,ignore,does_not_compile -fn largest(list: &[T]) -> T { - let mut largest = list[0]; - - for &item in list.iter() { - 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); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs}} ``` Listing 10-5: A definition of the `largest` function that @@ -126,13 +68,7 @@ uses generic type parameters but doesn’t compile yet If we compile this code right now, we’ll get this error: ```text -error[E0369]: binary operation `>` cannot be applied to type `T` - --> src/main.rs:5:12 - | -5 | if item > largest { - | ^^^^^^^^^^^^^^ - | - = note: an implementation of `std::cmp::PartialOrd` might be missing for `T` +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt}} ``` The note mentions `std::cmp::PartialOrd`, which is a *trait*. We’ll talk about @@ -155,15 +91,7 @@ struct to hold `x` and `y` coordinate values of any type. Filename: src/main.rs ```rust -struct Point { - x: T, - y: T, -} - -fn main() { - let integer = Point { x: 5, y: 10 }; - let float = Point { x: 1.0, y: 4.0 }; -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-06/src/main.rs}} ``` Listing 10-6: A `Point` struct that holds `x` and `y` @@ -184,14 +112,7 @@ Listing 10-7, our code won’t compile. Filename: src/main.rs ```rust,ignore,does_not_compile -struct Point { - x: T, - y: T, -} - -fn main() { - let wont_work = Point { x: 5, y: 4.0 }; -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs}} ``` Listing 10-7: The fields `x` and `y` must be the same @@ -203,15 +124,7 @@ compiler know that the generic type `T` will be an integer for this instance of same type as `x`, we’ll get a type mismatch error like this: ```text -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 - | - = note: expected type `{integer}` - found type `{float}` +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt}} ``` To define a `Point` struct where `x` and `y` are both generics but could have @@ -222,16 +135,7 @@ Listing 10-8, we can change the definition of `Point` to be generic over types Filename: src/main.rs ```rust -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 }; -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs}} ``` Listing 10-8: A `Point` generic over two types so @@ -294,22 +198,7 @@ struct we defined in Listing 10-6 with a method named `x` implemented on it. Filename: src/main.rs ```rust -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()); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-09/src/main.rs}} ``` Listing 10-9: Implementing a method named `x` on the @@ -328,17 +217,10 @@ We could, for example, implement methods only on `Point` instances rather than on `Point` instances with any generic type. In Listing 10-10 we use the concrete type `f32`, meaning we don’t declare any types after `impl`. +Filename: src/main.rs + ```rust -# struct Point { -# x: T, -# y: T, -# } -# -impl Point { - fn distance_from_origin(&self) -> f32 { - (self.x.powi(2) + self.y.powi(2)).sqrt() - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs:here}} ``` Listing 10-10: An `impl` block that only applies to a @@ -361,28 +243,7 @@ value from the passed-in `Point` (of type `W`). Filename: src/main.rs ```rust -struct Point { - x: T, - y: U, -} - -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); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs}} ``` Listing 10-11: A method that uses different generic types diff --git a/src/ch10-02-traits.md b/src/ch10-02-traits.md index 19e873bb..0e01361d 100644 --- a/src/ch10-02-traits.md +++ b/src/ch10-02-traits.md @@ -30,9 +30,7 @@ need a summary from each type, and we need to request that summary by calling a Filename: src/lib.rs ```rust -pub trait Summary { - fn summarize(&self) -> String; -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs}} ``` Listing 10-12: A `Summary` trait that consists of the @@ -65,35 +63,7 @@ already limited to 280 characters. Filename: src/lib.rs ```rust -# 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) - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs:here}} ``` Listing 10-13: Implementing the `Summary` trait on the @@ -112,14 +82,7 @@ After implementing the trait, we can call the methods on instances of `NewsArticle` and `Tweet` in the same way we call regular methods, like this: ```rust,ignore -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()); +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs:here}} ``` This code prints `1 new tweet: horse_ebooks: of course, as you probably already @@ -168,11 +131,7 @@ in Listing 10-12. Filename: src/lib.rs ```rust -pub trait Summary { - fn summarize(&self) -> String { - String::from("(Read more...)") - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs:here}} ``` Listing 10-14: Definition of a `Summary` trait with a @@ -188,15 +147,7 @@ directly, we’ve provided a default implementation and specified that the `summarize` method on an instance of `NewsArticle`, like this: ```rust,ignore -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()); +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs:here}} ``` This code prints `New article available! (Read more...)`. @@ -216,24 +167,14 @@ a small part of it. For example, we could define the `Summary` trait to have a `summarize_author` method: ```rust -pub trait Summary { - fn summarize_author(&self) -> String; - - fn summarize(&self) -> String { - format!("(Read more from {}...)", self.summarize_author()) - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs:here}} ``` To use this version of `Summary`, we only need to define `summarize_author` when we implement the trait on a type: ```rust,ignore -impl Summary for Tweet { - fn summarize_author(&self) -> String { - format!("@{}", self.username) - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs:impl}} ``` After we define `summarize_author`, we can call `summarize` on instances of the @@ -243,14 +184,7 @@ definition of `summarize_author` that we’ve provided. Because we’ve implemen `summarize` method without requiring us to write any more code. ```rust,ignore -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()); +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs:here}} ``` This code prints `1 new tweet: (Read more from @horse_ebooks...)`. @@ -270,9 +204,7 @@ implements the `Summary` trait. To do this, we can use the `impl Trait` syntax, like this: ```rust,ignore -pub fn notify(item: impl Summary) { - println!("Breaking news! {}", item.summarize()); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs:here}} ``` Instead of a concrete type for the `item` parameter, we specify the `impl` @@ -373,14 +305,7 @@ We can also use the `impl Trait` syntax in the return position to return a value of some type that implements a trait, as shown here: ```rust,ignore -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, - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs:here}} ``` By using `impl Summary` for the return type, we specify that the @@ -400,24 +325,7 @@ example, this code that returns either a `NewsArticle` or a `Tweet` with the return type specified as `impl Summary` wouldn’t work: ```rust,ignore,does_not_compile -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, - } - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs:here}} ``` Returning either a `NewsArticle` or a `Tweet` isn’t allowed due to restrictions @@ -435,13 +343,7 @@ the `largest` function that uses a generic type parameter! Last time we tried to run that code, we received this error: ```text -error[E0369]: binary operation `>` cannot be applied to type `T` - --> src/main.rs:5:12 - | -5 | if item > largest { - | ^^^^^^^^^^^^^^ - | - = note: an implementation of `std::cmp::PartialOrd` might be missing for `T` +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt}} ``` In the body of `largest` we wanted to compare two values of type `T` using the @@ -453,29 +355,13 @@ into scope because it’s in the prelude. Change the signature of `largest` to look like this: ```rust,ignore -fn largest(list: &[T]) -> T { +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/src/main.rs:here}} ``` This time when we compile the code, we get a different set of errors: ```text -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 - | help: consider using a reference instead: `&list[0]` - -error[E0507]: cannot move out of borrowed content - --> src/main.rs:4:9 - | -4 | for &item in list.iter() { - | ^---- - | || - | |hint: to prevent move, use `ref item` or `ref mut item` - | cannot move out of borrowed content +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-fixing-listing-10-05/output.txt}} ``` The key line in this error is `cannot move out of type [T], a non-copy slice`. @@ -498,29 +384,7 @@ values in the slice that we pass into the function implement the `PartialOrd` Filename: src/main.rs ```rust -fn largest(list: &[T]) -> T { - let mut largest = list[0]; - - for &item in list.iter() { - 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); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/main.rs}} ``` Listing 10-15: A working definition of the `largest` @@ -550,32 +414,10 @@ traits. For example, the type `Pair` in Listing 10-16 always implements the inner type `T` implements the `PartialOrd` trait that enables comparison *and* the `Display` trait that enables printing. +Filename: src/lib.rs + ```rust -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); - } - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/src/lib.rs}} ``` Listing 10-16: Conditionally implement methods on a diff --git a/src/ch10-03-lifetime-syntax.md b/src/ch10-03-lifetime-syntax.md index 383a4ec4..c0070394 100644 --- a/src/ch10-03-lifetime-syntax.md +++ b/src/ch10-03-lifetime-syntax.md @@ -25,16 +25,7 @@ Consider the program in Listing 10-17, which has an outer scope and an inner scope. ```rust,ignore,does_not_compile -{ - let r; - - { - let x = 5; - r = &x; - } - - println!("r: {}", r); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/src/main.rs:here}} ``` Listing 10-17: An attempt to use a reference whose value @@ -55,16 +46,7 @@ compile because the value `r` is referring to has gone out of scope before we try to use it. Here is the error message: ```text -error[E0597]: `x` does not live long enough - --> src/main.rs:7:5 - | -6 | r = &x; - | - borrow occurs here -7 | } - | ^ `x` dropped here while still borrowed -... -10 | } - | - borrowed value needs to live until here +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/output.txt}} ``` The variable `x` doesn’t “live long enough.” The reason is that `x` will be out @@ -82,16 +64,7 @@ whether all borrows are valid. Listing 10-18 shows the same code as Listing 10-17 but with annotations showing the lifetimes of the variables. ```rust,ignore,does_not_compile -{ - let r; // ---------+-- 'a - // | - { // | - let x = 5; // -+-- 'b | - r = &x; // | | - } // -+ | - // | - println!("r: {}", r); // | -} // ---------+ +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/src/main.rs:here}} ``` Listing 10-18: Annotations of the lifetimes of `r` and @@ -108,14 +81,7 @@ Listing 10-19 fixes the code so it doesn’t have a dangling reference and compiles without any errors. ```rust -{ - let x = 5; // ----------+-- 'b - // | - let r = &x; // --+-- 'a | - // | | - println!("r: {}", r); // | | - // --+ | -} // ----------+ +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs:here}} ``` Listing 10-19: A valid reference because the data has a @@ -139,13 +105,7 @@ longest string is abcd`. Filename: src/main.rs ```rust,ignore -fn main() { - let string1 = String::from("abcd"); - let string2 = "xyz"; - - let result = longest(string1.as_str(), string2); - println!("The longest string is {}", result); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs}} ``` Listing 10-20: A `main` function that calls the `longest` @@ -167,13 +127,7 @@ won’t compile. Filename: src/main.rs ```rust,ignore,does_not_compile -fn longest(x: &str, y: &str) -> &str { - if x.len() > y.len() { - x - } else { - y - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs:here}} ``` Listing 10-21: An implementation of the `longest` @@ -183,14 +137,7 @@ compile Instead, we get the following error that talks about lifetimes: ```text -error[E0106]: missing lifetime specifier - --> src/main.rs:1:33 - | -1 | fn longest(x: &str, y: &str) -> &str { - | ^ expected 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` +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/output.txt}} ``` The help text reveals that the return type needs a generic lifetime parameter @@ -257,13 +204,7 @@ Listing 10-22. Filename: src/main.rs ```rust -fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { - if x.len() > y.len() { - x - } else { - y - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs:here}} ``` Listing 10-22: The `longest` function definition @@ -310,23 +251,7 @@ a straightforward example. Filename: src/main.rs ```rust -# fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { -# if x.len() > y.len() { -# x -# } else { -# y -# } -# } -# -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); - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs:here}} ``` Listing 10-23: Using the `longest` function with @@ -349,15 +274,7 @@ compile. Filename: src/main.rs ```rust,ignore,does_not_compile -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); -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs:here}} ``` Listing 10-24: Attempting to use `result` after `string2` @@ -366,16 +283,7 @@ has gone out of scope When we try to compile this code, we’ll get this error: ```text -error[E0597]: `string2` does not live long enough - --> src/main.rs:15:5 - | -14 | result = longest(string1.as_str(), string2.as_str()); - | ------- borrow occurs here -15 | } - | ^ `string2` dropped here while still borrowed -16 | println!("The longest string is {}", result); -17 | } - | - borrowed value needs to live until here +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/output.txt}} ``` The error shows that for `result` to be valid for the `println!` statement, @@ -408,9 +316,7 @@ following code will compile: Filename: src/main.rs ```rust -fn longest<'a>(x: &'a str, y: &str) -> &'a str { - x -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs:here}} ``` In this example, we’ve specified a lifetime parameter `'a` for the parameter @@ -427,10 +333,7 @@ this attempted implementation of the `longest` function that won’t compile: Filename: src/main.rs ```rust,ignore,does_not_compile -fn longest<'a>(x: &str, y: &str) -> &'a str { - let result = String::from("really long string"); - result.as_str() -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs:here}} ``` Here, even though we’ve specified a lifetime parameter `'a` for the return @@ -439,23 +342,7 @@ lifetime is not related to the lifetime of the parameters at all. Here is the error message we get: ```text -error[E0597]: `result` does not live long enough - --> src/main.rs:3:5 - | -3 | result.as_str() - | ^^^^^^ does not live long enough -4 | } - | - borrowed value only lives until here - | -note: borrowed value must be valid for the lifetime 'a as defined on the -function body at 1:1... - --> src/main.rs:1:1 - | -1 | / fn longest<'a>(x: &str, y: &str) -> &'a str { -2 | | let result = String::from("really long string"); -3 | | result.as_str() -4 | | } - | |_^ +{{#include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt}} ``` The problem is that `result` goes out of scope and gets cleaned up at the end @@ -481,17 +368,7 @@ struct named `ImportantExcerpt` that holds a string slice. Filename: src/main.rs ```rust -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 }; -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs}} ``` Listing 10-25: A struct that holds a reference, so its @@ -521,17 +398,7 @@ Chapter 4 we had a function in Listing 4-9, which is shown again in Listing Filename: src/lib.rs ```rust -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[..] -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/listing-10-26/src/main.rs:here}} ``` Listing 10-26: A function we defined in Listing 4-9 that @@ -671,15 +538,7 @@ First, we’ll use a method named `level` whose only parameter is a reference to `self` and whose return value is an `i32`, which is not a reference to anything: ```rust -# struct ImportantExcerpt<'a> { -# part: &'a str, -# } -# -impl<'a> ImportantExcerpt<'a> { - fn level(&self) -> i32 { - 3 - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs:1st}} ``` The lifetime parameter declaration after `impl` and its use after the type name @@ -689,16 +548,7 @@ to `self` because of the first elision rule. Here is an example where the third lifetime elision rule applies: ```rust -# struct ImportantExcerpt<'a> { -# part: &'a str, -# } -# -impl<'a> ImportantExcerpt<'a> { - fn announce_and_return_part(&self, announcement: &str) -> &str { - println!("Attention please: {}", announcement); - self.part - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs:3rd}} ``` There are two input lifetimes, so Rust applies the first lifetime elision rule @@ -734,18 +584,7 @@ Let’s briefly look at the syntax of specifying generic type parameters, trait bounds, and lifetimes all in one function! ```rust -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 - } -} +{{#rustdoc_include ../listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs:here}} ``` This is the `longest` function from Listing 10-22 that returns the longer of diff --git a/src/ch11-01-writing-tests.md b/src/ch11-01-writing-tests.md index 42a53918..a2f62ce4 100644 --- a/src/ch11-01-writing-tests.md +++ b/src/ch11-01-writing-tests.md @@ -47,14 +47,7 @@ Listing 11-1. Filename: src/lib.rs ```rust -# fn main() {} -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs:here}} ``` Listing 11-1: The test module and function generated @@ -75,21 +68,7 @@ The `cargo test` command runs all tests in our project, as shown in Listing 11-2. ```text -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished dev [unoptimized + debuginfo] target(s) in 0.22 secs - Running target/debug/deps/adder-ce99bcc2479f4607 - -running 1 test -test tests::it_works ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/listing-11-01/output.txt}} ``` Listing 11-2: The output from running the automatically @@ -129,24 +108,14 @@ so: Filename: src/lib.rs ```rust -# fn main() {} -#[cfg(test)] -mod tests { - #[test] - fn exploration() { - assert_eq!(2 + 2, 4); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs:here}} ``` Then run `cargo test` again. The output now shows `exploration` instead of `it_works`: ```text -running 1 test -test tests::exploration ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt}} ``` Let’s add another test, but this time we’ll make a test that fails! Tests fail @@ -159,19 +128,7 @@ which is to call the `panic!` macro. Enter the new test, `another`, so your Filename: src/lib.rs ```rust,panics -# fn main() {} -#[cfg(test)] -mod tests { - #[test] - fn exploration() { - assert_eq!(2 + 2, 4); - } - - #[test] - fn another() { - panic!("Make this test fail"); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs:here}} ``` Listing 11-3: Adding a second test that will fail because @@ -181,22 +138,7 @@ Run the tests again using `cargo test`. The output should look like Listing 11-4, which shows that our `exploration` test passed and `another` failed. ```text -running 2 tests -test tests::exploration ... ok -test tests::another ... FAILED - -failures: - ----- tests::another stdout ---- -thread 'tests::another' panicked at 'Make this test fail', src/lib.rs:10:9 -note: Run with `RUST_BACKTRACE=1` for a backtrace. - -failures: - tests::another - -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out - -error: test failed +{{#include ../listings/ch11-writing-automated-tests/listing-11-03/output.txt}} ``` Listing 11-4: Test results when one test passes and one @@ -236,18 +178,7 @@ method, which are repeated here in Listing 11-5. Let’s put this code in the Filename: src/lib.rs ```rust -# fn main() {} -#[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 - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs:here}} ``` Listing 11-5: Using the `Rectangle` struct and its @@ -262,19 +193,7 @@ has a width of 5 and a height of 1. Filename: src/lib.rs ```rust -# fn main() {} -#[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)); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs:here}} ``` Listing 11-6: A test for `can_hold` that checks whether a @@ -295,10 +214,7 @@ passed it the result of calling `larger.can_hold(&smaller)`. This expression is supposed to return `true`, so our test should pass. Let’s find out! ```text -running 1 test -test tests::larger_can_hold_smaller ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/listing-11-06/output.txt}} ``` It does pass! Let’s add another test, this time asserting that a smaller @@ -307,24 +223,7 @@ rectangle cannot hold a larger rectangle: Filename: src/lib.rs ```rust -# fn main() {} -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn larger_can_hold_smaller() { - // --snip-- - } - - #[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)); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs:here}} ``` Because the correct result of the `can_hold` function in this case is `false`, @@ -332,11 +231,7 @@ we need to negate that result before we pass it to the `assert!` macro. As a result, our test will pass if `can_hold` returns `false`: ```text -running 2 tests -test tests::smaller_cannot_hold_larger ... ok -test tests::larger_can_hold_smaller ... ok - -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt}} ``` Two tests that pass! Now let’s see what happens to our test results when we @@ -345,39 +240,13 @@ method by replacing the greater than sign with a less than sign when it compares the widths: ```rust,not_desired_behavior -# fn main() {} -# #[derive(Debug)] -# struct Rectangle { -# width: u32, -# height: u32, -# } -// --snip-- - -impl Rectangle { - fn can_hold(&self, other: &Rectangle) -> bool { - self.width < other.width && self.height > other.height - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs:here}} ``` Running the tests now produces the following: ```text -running 2 tests -test tests::smaller_cannot_hold_larger ... ok -test tests::larger_can_hold_smaller ... FAILED - -failures: - ----- tests::larger_can_hold_smaller stdout ---- -thread 'tests::larger_can_hold_smaller' panicked at 'assertion failed: -larger.can_hold(&smaller)', src/lib.rs:22:9 -note: Run with `RUST_BACKTRACE=1` for a backtrace. - -failures: - tests::larger_can_hold_smaller - -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt}} ``` Our tests caught the bug! Because `larger.width` is 8 and `smaller.width` is @@ -404,20 +273,7 @@ parameter and returns the result. Then we test this function using the Filename: src/lib.rs ```rust -# fn main() {} -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)); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs:here}} ``` Listing 11-7: Testing the function `add_two` using the @@ -426,10 +282,7 @@ mod tests { Let’s check that it passes! ```text -running 1 test -test tests::it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/listing-11-07/output.txt}} ``` The first argument we gave to the `assert_eq!` macro, `4`, is equal to the @@ -441,30 +294,13 @@ uses `assert_eq!` fails. Change the implementation of the `add_two` function to instead add `3`: ```rust,not_desired_behavior -# fn main() {} -pub fn add_two(a: i32) -> i32 { - a + 3 -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs:here}} ``` Run the tests again: ```text -running 1 test -test tests::it_adds_two ... FAILED - -failures: - ----- tests::it_adds_two stdout ---- -thread 'tests::it_adds_two' panicked at 'assertion failed: `(left == right)` - left: `4`, - right: `5`', src/lib.rs:11:9 -note: Run with `RUST_BACKTRACE=1` for a backtrace. - -failures: - tests::it_adds_two - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt}} ``` Our test caught the bug! The `it_adds_two` test failed, displaying the message @@ -523,21 +359,7 @@ want to test that the name we pass into the function appears in the output: Filename: src/lib.rs ```rust -# fn main() {} -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")); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs:here}} ``` The requirements for this program haven’t been agreed upon yet, and we’re @@ -551,27 +373,13 @@ Let’s introduce a bug into this code by changing `greeting` to not include `name` to see what this test failure looks like: ```rust,not_desired_behavior -# fn main() {} -pub fn greeting(name: &str) -> String { - String::from("Hello!") -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs:here}} ``` Running this test produces the following: ```text -running 1 test -test tests::greeting_contains_name ... FAILED - -failures: - ----- tests::greeting_contains_name stdout ---- -thread 'tests::greeting_contains_name' panicked at 'assertion failed: -result.contains("Carol")', src/lib.rs:12:9 -note: Run with `RUST_BACKTRACE=1` for a backtrace. - -failures: - tests::greeting_contains_name +{{#include ../listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt}} ``` This result just indicates that the assertion failed and which line the @@ -581,23 +389,13 @@ giving it a custom failure message made from a format string with a placeholder filled in with the actual value we got from the `greeting` function: ```rust,ignore -#[test] -fn greeting_contains_name() { - let result = greeting("Carol"); - assert!( - result.contains("Carol"), - "Greeting did not contain name, value was `{}`", result - ); -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs:here}} ``` Now when we run the test, we’ll get a more informative error message: ```text ----- tests::greeting_contains_name stdout ---- -thread 'tests::greeting_contains_name' panicked at 'Greeting did not -contain name, value was `Hello!`', src/lib.rs:12:9 -note: Run with `RUST_BACKTRACE=1` for a backtrace. +{{#include ../listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt}} ``` We can see the value we actually got in the test output, which would help us @@ -623,33 +421,7 @@ happen when we expect them to. Filename: src/lib.rs ```rust -# fn main() {} -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); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs:here}} ``` Listing 11-8: Testing that a condition will cause a @@ -660,48 +432,20 @@ before the test function it applies to. Let’s look at the result when this tes passes: ```text -running 1 test -test tests::greater_than_100 ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/listing-11-08/output.txt}} ``` Looks good! Now let’s introduce a bug in our code by removing the condition that the `new` function will panic if the value is greater than 100: ```rust,not_desired_behavior -# fn main() {} -# pub struct Guess { -# value: i32, -# } -# -// --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 - } - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs:here}} ``` When we run the test in Listing 11-8, it will fail: ```text -running 1 test -test tests::greater_than_100 ... FAILED - -failures: - -failures: - tests::greater_than_100 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt}} ``` We don’t get a very helpful message in this case, but when we look at the test @@ -720,39 +464,7 @@ different messages depending on whether the value is too small or too large. Filename: src/lib.rs ```rust -# fn main() {} -# pub struct Guess { -# value: i32, -# } -# -// --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); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs:here}} ``` Listing 11-9: Testing that a condition will cause a @@ -773,32 +485,13 @@ fails, let’s again introduce a bug into our code by swapping the bodies of the `if value < 1` and the `else if value > 100` blocks: ```rust,ignore,not_desired_behavior -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); -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs:here}} ``` This time when we run the `should_panic` test, it will fail: ```text -running 1 test -test tests::greater_than_100 ... FAILED - -failures: - ----- tests::greater_than_100 stdout ---- -thread 'tests::greater_than_100' panicked at 'Guess value must be -greater than or equal to 1, got 200.', src/lib.rs:11:13 -note: Run with `RUST_BACKTRACE=1` for a backtrace. -note: Panic did not include expected string '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 +{{#include ../listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt}} ``` The failure message indicates that this test did indeed panic as we expected, @@ -814,17 +507,7 @@ that use `Result`! Here’s the test from Listing 11-1, rewritten to use `Result` and return an `Err` instead of panicking: ```rust -#[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")) - } - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs}} ``` The `it_works` function now has a return type, `Result<(), String>`. In the diff --git a/src/ch11-02-running-tests.md b/src/ch11-02-running-tests.md index 26293d19..ff29fc42 100644 --- a/src/ch11-02-running-tests.md +++ b/src/ch11-02-running-tests.md @@ -62,27 +62,7 @@ parameter and returns 10, as well as a test that passes and a test that fails. Filename: src/lib.rs ```rust,panics -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); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs}} ``` Listing 11-10: Tests for a function that calls @@ -91,23 +71,7 @@ mod tests { When we run these tests with `cargo test`, we’ll see the following output: ```text -running 2 tests -test tests::this_test_will_pass ... ok -test tests::this_test_will_fail ... FAILED - -failures: - ----- tests::this_test_will_fail stdout ---- -I got the value 8 -thread 'tests::this_test_will_fail' panicked at 'assertion failed: `(left == right)` - left: `5`, - right: `10`', src/lib.rs:19:9 -note: Run with `RUST_BACKTRACE=1` for a backtrace. - -failures: - tests::this_test_will_fail - -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/listing-11-10/output.txt}} ``` Note that nowhere in this output do we see `I got the value 4`, which is what @@ -155,6 +119,10 @@ failures: test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out ``` + + ### Running a Subset of Tests by Name Sometimes, running a full test suite can take a long time. If you’re working on @@ -168,29 +136,7 @@ To demonstrate how to run a subset of tests, we’ll create three tests for our Filename: src/lib.rs ```rust -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)); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs}} ``` Listing 11-11: Three tests with three different @@ -200,12 +146,7 @@ If we run the tests without passing any arguments, as we saw earlier, all the tests will run in parallel: ```text -running 3 tests -test tests::add_two_and_two ... ok -test tests::add_three_and_two ... ok -test tests::one_hundred ... ok - -test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/listing-11-11/output.txt}} ``` #### Running Single Tests @@ -213,14 +154,7 @@ test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out We can pass the name of any test function to `cargo test` to run only that test: ```text -$ cargo test one_hundred - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - Running target/debug/deps/adder-06a75b4a1f2515e9 - -running 1 test -test tests::one_hundred ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out +{{#include ../listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt}} ``` Only the test with the name `one_hundred` ran; the other two tests didn’t match @@ -237,15 +171,7 @@ will be run. For example, because two of our tests’ names contain `add`, we ca run those two by running `cargo test add`: ```text -$ cargo test add - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - Running target/debug/deps/adder-06a75b4a1f2515e9 - -running 2 tests -test tests::add_two_and_two ... ok -test tests::add_three_and_two ... ok - -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out +{{#include ../listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt}} ``` This command ran all tests with `add` in the name and filtered out the test @@ -264,46 +190,21 @@ here: Filename: src/lib.rs ```rust -#[test] -fn it_works() { - assert_eq!(2 + 2, 4); -} - -#[test] -#[ignore] -fn expensive_test() { - // code that takes an hour to run -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs:here}} ``` After `#[test]` we add the `#[ignore]` line to the test we want to exclude. Now when we run our tests, `it_works` runs, but `expensive_test` doesn’t: ```text -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished dev [unoptimized + debuginfo] target(s) in 0.24 secs - Running target/debug/deps/adder-ce99bcc2479f4607 - -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 +{{#include ../listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt}} ``` The `expensive_test` function is listed as `ignored`. If we want to run only the ignored tests, we can use `cargo test -- --ignored`: ```text -$ cargo test -- --ignored - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - Running target/debug/deps/adder-ce99bcc2479f4607 - -running 1 test -test expensive_test ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out +{{#include ../listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt}} ``` By controlling which tests run, you can make sure your `cargo test` results diff --git a/src/ch11-03-test-organization.md b/src/ch11-03-test-organization.md index 2af6a0e0..9ac94975 100644 --- a/src/ch11-03-test-organization.md +++ b/src/ch11-03-test-organization.md @@ -38,13 +38,7 @@ this chapter, Cargo generated this code for us: Filename: src/lib.rs ```rust -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs:here}} ``` This code is the automatically generated test module. The attribute `cfg` @@ -67,25 +61,7 @@ Consider the code in Listing 11-12 with the private function `internal_adder`. Filename: src/lib.rs ```rust -# fn main() {} - -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)); - } -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs:here}} ``` Listing 11-12: Testing a private function @@ -120,12 +96,7 @@ Let’s create an integration test. With the code in Listing 11-12 still in the Filename: tests/integration_test.rs ```rust,ignore -use adder; - -#[test] -fn it_adds_two() { - assert_eq!(4, adder::add_two(2)); -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs}} ``` Listing 11-13: An integration test of a function in the @@ -140,28 +111,7 @@ We don’t need to annotate any code in *tests/integration_test.rs* with in this directory only when we run `cargo test`. Run `cargo test` now: ```text -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished dev [unoptimized + debuginfo] target(s) in 0.31 secs - Running target/debug/deps/adder-abcabcabc - -running 1 test -test tests::internal ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - - Running target/debug/deps/integration_test-ce99bcc2479f4607 - -running 1 test -test it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/listing-11-13/output.txt}} ``` The three sections of output include the unit tests, the integration test, and @@ -187,14 +137,7 @@ particular integration test file, use the `--test` argument of `cargo test` followed by the name of the file: ```text -$ cargo test --test integration_test - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - Running target/debug/integration_test-952a27e0126bb565 - -running 1 test -test it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt}} ``` This command runs only the tests in the *tests/integration_test.rs* file. @@ -224,9 +167,7 @@ multiple test files: Filename: tests/common.rs ```rust -pub fn setup() { - // setup code specific to your library's tests would go here -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/common.rs}} ``` When we run the tests again, we’ll see a new section in the test output for the @@ -234,29 +175,7 @@ When we run the tests again, we’ll see a new section in the test output for th did we call the `setup` function from anywhere: ```text -running 1 test -test tests::internal ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - - Running target/debug/deps/common-b8b07b6f1be2db70 - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - - Running target/debug/deps/integration_test-d993c68b431d39df - -running 1 test -test it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +{{#include ../listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt}} ``` Having `common` appear in the test results with `running 0 tests` displayed for @@ -279,15 +198,7 @@ function from the `it_adds_two` test in *tests/integration_test.rs*: Filename: tests/integration_test.rs ```rust,ignore -use adder; - -mod common; - -#[test] -fn it_adds_two() { - common::setup(); - assert_eq!(4, adder::add_two(2)); -} +{{#rustdoc_include ../listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs}} ``` Note that the `mod common;` declaration is the same as the module declaration diff --git a/src/ch12-01-accepting-command-line-arguments.md b/src/ch12-01-accepting-command-line-arguments.md index 5f4f61e8..f327361f 100644 --- a/src/ch12-01-accepting-command-line-arguments.md +++ b/src/ch12-01-accepting-command-line-arguments.md @@ -41,12 +41,7 @@ command line arguments passed to it and then collect the values into a vector. Filename: src/main.rs ```rust -use std::env; - -fn main() { - let args: Vec = env::args().collect(); - println!("{:?}", args); -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-01/src/main.rs}} ``` Listing 12-1: Collecting the command line arguments into @@ -83,13 +78,11 @@ Finally, we print the vector using the debug formatter, `:?`. Let’s try runnin the code first with no arguments and then with two arguments: ```text -$ cargo run ---snip-- -["target/debug/minigrep"] +{{#include ../listings/ch12-an-io-project/listing-12-01/output.txt}} +``` -$ cargo run needle haystack ---snip-- -["target/debug/minigrep", "needle", "haystack"] +```text +{{#include ../listings/ch12-an-io-project/output-only-01-with-args/output.txt}} ``` Notice that the first value in the vector is `"target/debug/minigrep"`, which @@ -110,17 +103,7 @@ throughout the rest of the program. We do that in Listing 12-2. Filename: src/main.rs ```rust,should_panic -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); -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-02/src/main.rs}} ``` Listing 12-2: Creating variables to hold the query @@ -138,12 +121,7 @@ working as we intend. Let’s run this program again with the arguments `test` and `sample.txt`: ```text -$ cargo run test sample.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - Running `target/debug/minigrep test sample.txt` -Searching for test -In file sample.txt +{{#include ../listings/ch12-an-io-project/listing-12-02/output.txt}} ``` Great, the program is working! The values of the arguments we need are being diff --git a/src/ch12-02-reading-a-file.md b/src/ch12-02-reading-a-file.md index 8c4c92ec..0b07e7a7 100644 --- a/src/ch12-02-reading-a-file.md +++ b/src/ch12-02-reading-a-file.md @@ -11,15 +11,7 @@ Who are you?” Filename: poem.txt ```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! +{{#include ../listings/ch12-an-io-project/listing-12-03/poem.txt}} ``` Listing 12-3: A poem by Emily Dickinson makes a good test @@ -31,24 +23,7 @@ shown in Listing 12-4. Filename: src/main.rs ```rust,should_panic -use std::env; -use std::fs; - -fn main() { -# let args: Vec = env::args().collect(); -# -# let query = &args[1]; -# let filename = &args[2]; -# -# println!("Searching for {}", query); - // --snip-- - println!("In file {}", filename); - - let contents = fs::read_to_string(filename) - .expect("Something went wrong reading the file"); - - println!("With text:\n{}", contents); -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-04/src/main.rs:here}} ``` Listing 12-4: Reading the contents of the file specified @@ -70,22 +45,7 @@ we haven’t implemented the searching part yet) and the *poem.txt* file as the second argument: ```text -$ cargo run the poem.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - 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! +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-04/output.txt}} ``` Great! The code read and then printed the contents of the file. But the code diff --git a/src/ch12-03-improving-error-handling-and-modularity.md b/src/ch12-03-improving-error-handling-and-modularity.md index d26c5900..cf5bd88e 100644 --- a/src/ch12-03-improving-error-handling-and-modularity.md +++ b/src/ch12-03-improving-error-handling-and-modularity.md @@ -75,20 +75,7 @@ function `parse_config`, which we’ll define in *src/main.rs* for the moment. Filename: src/main.rs ```rust,ignore -fn main() { - let args: Vec = env::args().collect(); - - let (query, filename) = parse_config(&args); - - // --snip-- -} - -fn parse_config(args: &[String]) -> (&str, &str) { - let query = &args[1]; - let filename = &args[2]; - - (query, filename) -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-05/src/main.rs:here}} ``` Listing 12-5: Extracting a `parse_config` function from @@ -133,34 +120,7 @@ Listing 12-6 shows the improvements to the `parse_config` function. Filename: src/main.rs ```rust,should_panic -# use std::env; -# use std::fs; -# -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-- -} - -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 } -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-06/src/main.rs:here}} ``` Listing 12-6: Refactoring `parse_config` to return an @@ -228,31 +188,7 @@ shows the changes we need to make. Filename: src/main.rs ```rust,should_panic -# use std::env; -# -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::new(&args); - - // --snip-- -} - -# struct Config { -# query: String, -# filename: String, -# } -# -// --snip-- - -impl Config { - fn new(args: &[String]) -> Config { - let query = args[1].clone(); - let filename = args[2].clone(); - - Config { query, filename } - } -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-07/src/main.rs:here}} ``` Listing 12-7: Changing `parse_config` into @@ -271,13 +207,7 @@ panic if the vector contains fewer than three items. Try running the program without any arguments; it will look like this: ```text -$ cargo run - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - Running `target/debug/minigrep` -thread 'main' panicked at 'index out of bounds: the len is 1 -but the index is 1', src/main.rs:25:21 -note: Run with `RUST_BACKTRACE=1` for a backtrace. +{{#include ../listings/ch12-an-io-project/listing-12-07/output.txt}} ``` The line `index out of bounds: the len is 1 but the index is 1` is an error @@ -294,12 +224,7 @@ out of bounds` message. Filename: src/main.rs ```rust,ignore -// --snip-- -fn new(args: &[String]) -> Config { - if args.len() < 3 { - panic!("not enough arguments"); - } - // --snip-- +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-08/src/main.rs:here}} ``` Listing 12-8: Adding a check for the number of @@ -317,12 +242,7 @@ With these extra few lines of code in `new`, let’s run the program without any arguments again to see what the error looks like now: ```text -$ cargo run - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs - Running `target/debug/minigrep` -thread 'main' panicked at 'not enough arguments', src/main.rs:26:13 -note: Run with `RUST_BACKTRACE=1` for a backtrace. +{{#include ../listings/ch12-an-io-project/listing-12-08/output.txt}} ``` This output is better: we now have a reasonable error message. However, we also @@ -350,18 +270,7 @@ next listing. Filename: src/main.rs ```rust,ignore -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 }) - } -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-09/src/main.rs:here}} ``` Listing 12-9: Returning a `Result` from @@ -394,17 +303,7 @@ program that the program exited with an error state. Filename: src/main.rs ```rust,ignore -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-- +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-10/src/main.rs:here}} ``` Listing 12-10: Exiting with an error code if creating a @@ -433,11 +332,7 @@ number that was passed as the exit status code. This is similar to the extra output. Let’s try it: ```text -$ cargo run - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished dev [unoptimized + debuginfo] target(s) in 0.48 secs - Running `target/debug/minigrep` -Problem parsing arguments: not enough arguments +{{#include ../listings/ch12-an-io-project/listing-12-10/output.txt}} ``` Great! This output is much friendlier for our users. @@ -459,23 +354,7 @@ defining the function in *src/main.rs*. Filename: src/main.rs ```rust,ignore -fn main() { - // --snip-- - - 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-- +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-11/src/main.rs:here}} ``` Listing 12-11: Extracting a `run` function containing the @@ -498,17 +377,7 @@ signature and body of `run`. Filename: src/main.rs ```rust,ignore -use std::error::Error; - -// --snip-- - -fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.filename)?; - - println!("With text:\n{}", contents); - - Ok(()) -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-12/src/main.rs:here}} ``` Listing 12-12: Changing the `run` function to return @@ -543,14 +412,7 @@ it doesn’t return a value we need. When you run this code, it will compile but will display a warning: ```text -warning: unused `std::result::Result` that must be used - --> src/main.rs:17:5 - | -17 | run(config); - | ^^^^^^^^^^^^ - | - = note: #[warn(unused_must_use)] on by default - = note: this `Result` may be an `Err` variant, which should be handled +{{#include ../listings/ch12-an-io-project/listing-12-12/output.txt}} ``` Rust tells us that our code ignored the `Result` value and the `Result` value @@ -566,18 +428,7 @@ with `Config::new` in Listing 12-10, but with a slight difference: Filename: src/main.rs ```rust,ignore -fn main() { - // --snip-- - - println!("Searching for {}", config.query); - println!("In file {}", config.filename); - - if let Err(e) = run(config) { - println!("Application error: {}", e); - - process::exit(1); - } -} +{{#rustdoc_include ../listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs:here}} ``` We use `if let` rather than `unwrap_or_else` to check whether `run` returns an @@ -611,23 +462,7 @@ compile until we modify *src/main.rs* in Listing 12-14. Filename: src/lib.rs ```rust,ignore -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-- - } -} - -pub fn run(config: Config) -> Result<(), Box> { - // --snip-- -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-13/src/lib.rs:here}} ``` Listing 12-13: Moving `Config` and `run` into @@ -643,17 +478,7 @@ binary crate in *src/main.rs*, as shown in Listing 12-14. Filename: src/main.rs ```rust,ignore -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - // --snip-- - if let Err(e) = minigrep::run(config) { - // --snip-- - } -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-14/src/main.rs:here}} ``` Listing 12-14: Using the `minigrep` library crate in diff --git a/src/ch12-04-testing-the-librarys-functionality.md b/src/ch12-04-testing-the-librarys-functionality.md index e8ed858d..200af771 100644 --- a/src/ch12-04-testing-the-librarys-functionality.md +++ b/src/ch12-04-testing-the-librarys-functionality.md @@ -41,28 +41,7 @@ yet. Filename: src/lib.rs ```rust -# pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { -# vec![] -# } -# -#[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) - ); - } -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-15/src/lib.rs:here}} ``` Listing 12-15: Creating a failing test for the `search` @@ -82,9 +61,7 @@ containing the line `"safe, fast, productive."` Filename: src/lib.rs ```rust -pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - vec![] -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-16/src/lib.rs:here}} ``` Listing 12-16: Defining just enough of the `search` @@ -109,15 +86,7 @@ If we forget the lifetime annotations and try to compile this function, we’ll get this error: ```text -error[E0106]: missing lifetime specifier - --> src/lib.rs:5:51 - | -5 | pub fn search(query: &str, contents: &str) -> Vec<&str> { - | ^ expected 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` +{{#include ../listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt}} ``` Rust can’t possibly know which of the two arguments we need, so we need to tell @@ -134,31 +103,7 @@ References with Lifetimes”][validating-references-with-lifetimes] + ```text $ CASE_INSENSITIVE=1 cargo run to poem.txt - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs + 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/src/ch12-06-writing-to-stderr-instead-of-stdout.md b/src/ch12-06-writing-to-stderr-instead-of-stdout.md index 0fc1aa28..e2a47702 100644 --- a/src/ch12-06-writing-to-stderr-instead-of-stdout.md +++ b/src/ch12-06-writing-to-stderr-instead-of-stdout.md @@ -57,20 +57,7 @@ instead. Filename: src/main.rs ```rust,ignore -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); - } -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-24/src/main.rs:here}} ``` Listing 12-24: Writing error messages to standard error diff --git a/src/ch13-01-closures.md b/src/ch13-01-closures.md index 56f8ed45..953531e1 100644 --- a/src/ch13-01-closures.md +++ b/src/ch13-01-closures.md @@ -30,14 +30,7 @@ we passed in. Filename: src/main.rs ```rust -use std::thread; -use std::time::Duration; - -fn simulated_expensive_calculation(intensity: u32) -> u32 { - println!("calculating slowly..."); - thread::sleep(Duration::from_secs(2)); - intensity -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-01/src/main.rs:here}} ``` Listing 13-1: A function to stand in for a hypothetical @@ -62,16 +55,7 @@ function we’ll use. Filename: src/main.rs ```rust -fn main() { - let simulated_user_specified_value = 10; - let simulated_random_number = 7; - - generate_workout( - simulated_user_specified_value, - simulated_random_number - ); -} -# fn generate_workout(intensity: u32, random_number: u32) {} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-02/src/main.rs:here}} ``` Listing 13-2: A `main` function with hardcoded values to @@ -92,36 +76,7 @@ changes in this example will be made to this function. Filename: src/main.rs ```rust -# use std::thread; -# use std::time::Duration; -# -# fn simulated_expensive_calculation(num: u32) -> u32 { -# println!("calculating slowly..."); -# thread::sleep(Duration::from_secs(2)); -# num -# } -# -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) - ); - } - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-03/src/main.rs:here}} ``` Listing 13-3: The business logic that prints the workout @@ -163,39 +118,7 @@ function into a variable, as shown in Listing 13-4. Filename: src/main.rs ```rust -# use std::thread; -# use std::time::Duration; -# -# fn simulated_expensive_calculation(num: u32) -> u32 { -# println!("calculating slowly..."); -# thread::sleep(Duration::from_secs(2)); -# num -# } -# -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 - ); - } - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-04/src/main.rs:here}} ``` Listing 13-4: Extracting the calls to @@ -222,15 +145,7 @@ the closure we’re introducing here. Filename: src/main.rs ```rust -# use std::thread; -# use std::time::Duration; -# -let expensive_closure = |num| { - println!("calculating slowly..."); - thread::sleep(Duration::from_secs(2)); - num -}; -# expensive_closure(5); +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-05/src/main.rs:here}} ``` Listing 13-5: Defining a closure and storing it in the @@ -265,36 +180,7 @@ want to use, as shown in Listing 13-6. Filename: src/main.rs ```rust -# use std::thread; -# use std::time::Duration; -# -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) - ); - } - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-06/src/main.rs:here}} ``` Listing 13-6: Calling the `expensive_closure` we’ve @@ -339,14 +225,7 @@ would look like the definition shown in Listing 13-7. Filename: src/main.rs ```rust -# use std::thread; -# use std::time::Duration; -# -let expensive_closure = |num: u32| -> u32 { - println!("calculating slowly..."); - thread::sleep(Duration::from_secs(2)); - num -}; +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-07/src/main.rs:here}} ``` Listing 13-7: Adding optional type annotations of the @@ -383,10 +262,7 @@ first time and a `u32` the second time, we’ll get an error. Filename: src/main.rs ```rust,ignore,does_not_compile -let example_closure = |x| x; - -let s = example_closure(String::from("hello")); -let n = example_closure(5); +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-08/src/main.rs:here}} ``` Listing 13-8: Attempting to call a closure whose types @@ -395,15 +271,7 @@ are inferred with two different types The compiler gives us this error: ```text -error[E0308]: mismatched types - --> src/main.rs - | - | let n = example_closure(5); - | ^ expected struct `std::string::String`, found - integer - | - = note: expected type `std::string::String` - found type `{integer}` +{{#include ../listings/ch13-functional-features/listing-13-08/output.txt}} ``` The first time we call `example_closure` with the `String` value, the compiler @@ -451,12 +319,7 @@ and an optional result value. Filename: src/main.rs ```rust -struct Cacher - where T: Fn(u32) -> u32 -{ - calculation: T, - value: Option, -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-09/src/main.rs:here}} ``` Listing 13-9: Defining a `Cacher` struct that holds a @@ -486,34 +349,7 @@ The logic around the `value` field we’ve just described is defined in Listing Filename: src/main.rs ```rust -# 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 - }, - } - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-10/src/main.rs:here}} ``` Listing 13-10: The caching logic of `Cacher` @@ -544,65 +380,7 @@ Listing 13-11 shows how we can use this `Cacher` struct in the function Filename: src/main.rs ```rust -# 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 -# }, -# } -# } -# } -# -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) - ); - } - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-11/src/main.rs:here}} ``` Listing 13-11: Using `Cacher` in the `generate_workout` @@ -634,15 +412,7 @@ same value for the parameter `arg` to the `value` method. That is, this test of `Cacher` will fail: ```rust,ignore,panics -#[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); -} +{{#rustdoc_include ../listings/ch13-functional-features/no-listing-01-failing-cacher-test/src/lib.rs:here}} ``` This test creates a new `Cacher` instance with a closure that returns the value @@ -654,9 +424,7 @@ Run this test with the `Cacher` implementation in Listing 13-9 and Listing 13-10, and the test will fail on the `assert_eq!` with this message: ```text -thread 'call_with_different_values' panicked at 'assertion failed: `(left == right)` - left: `1`, - right: `2`', src/main.rs +{{#include ../listings/ch13-functional-features/no-listing-01-failing-cacher-test/output.txt}} ``` The problem is that the first time we called `c.value` with 1, the `Cacher` @@ -690,15 +458,7 @@ that uses the `x` variable from the closure’s surrounding environment. Filename: src/main.rs ```rust -fn main() { - let x = 4; - - let equal_to_x = |z| z == x; - - let y = 4; - - assert!(equal_to_x(y)); -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-12/src/main.rs}} ``` Listing 13-12: Example of a closure that refers to a @@ -714,26 +474,13 @@ code won’t compile: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let x = 4; - - fn equal_to_x(z: i32) -> bool { z == x } - - let y = 4; - - assert!(equal_to_x(y)); -} +{{#rustdoc_include ../listings/ch13-functional-features/no-listing-02-functions-cant-capture/src/main.rs}} ``` We get an error: ```text -error[E0434]: can't capture dynamic environment in a fn item; use the || { ... -} closure form instead - --> src/main.rs - | -4 | fn equal_to_x(z: i32) -> bool { z == x } - | ^ +{{#include ../listings/ch13-functional-features/no-listing-02-functions-cant-capture/output.txt}} ``` The compiler even reminds us that this only works with closures! @@ -780,33 +527,13 @@ yet compile. Filename: src/main.rs ```rust,ignore,does_not_compile -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)); -} +{{#rustdoc_include ../listings/ch13-functional-features/no-listing-03-move-closures/src/main.rs}} ``` We receive the following error: ```text -error[E0382]: use of moved value: `x` - --> src/main.rs:6:40 - | -4 | let equal_to_x = move |z| z == x; - | -------- value moved (into closure) here -5 | -6 | println!("can't use x here: {:?}", x); - | ^ value used here after move - | - = note: move occurs because `x` has type `std::vec::Vec`, which does not - implement the `Copy` trait +{{#include ../listings/ch13-functional-features/no-listing-03-move-closures/output.txt}} ``` The `x` value is moved into the closure when the closure is defined, because we diff --git a/src/ch13-02-iterators.md b/src/ch13-02-iterators.md index 493c3696..247d12a3 100644 --- a/src/ch13-02-iterators.md +++ b/src/ch13-02-iterators.md @@ -12,9 +12,7 @@ the `iter` method defined on `Vec`. This code by itself doesn’t do anything useful. ```rust -let v1 = vec![1, 2, 3]; - -let v1_iter = v1.iter(); +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-13/src/main.rs:here}} ``` Listing 13-13: Creating an iterator @@ -30,13 +28,7 @@ called using the iterator in `v1_iter`, each element in the iterator is used in one iteration of the loop, which prints out each value. ```rust -let v1 = vec![1, 2, 3]; - -let v1_iter = v1.iter(); - -for val in v1_iter { - println!("Got: {}", val); -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-14/src/main.rs:here}} ``` Listing 13-14: Using an iterator in a `for` loop @@ -86,17 +78,7 @@ from the vector. Filename: src/lib.rs ```rust -#[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); -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-15/src/lib.rs:here}} ``` Listing 13-15: Calling the `next` method on an @@ -135,16 +117,7 @@ test illustrating a use of the `sum` method: Filename: src/lib.rs ```rust -#[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); -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-16/src/lib.rs:here}} ``` Listing 13-16: Calling the `sum` method to get the total @@ -169,9 +142,7 @@ incremented by 1. However, this code produces a warning: Filename: src/main.rs ```rust,not_desired_behavior -let v1: Vec = vec![1, 2, 3]; - -v1.iter().map(|x| x + 1); +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-17/src/main.rs:here}} ``` Listing 13-17: Calling the iterator adaptor `map` to @@ -180,14 +151,7 @@ create a new iterator The warning we get is this: ```text -warning: unused `std::iter::Map` which must be used: iterator adaptors are lazy -and do nothing unless consumed - --> src/main.rs:4:5 - | -4 | v1.iter().map(|x| x + 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: #[warn(unused_must_use)] on by default +{{#include ../listings/ch13-functional-features/listing-13-17/output.txt}} ``` The code in Listing 13-17 doesn’t do anything; the closure we’ve specified @@ -205,11 +169,7 @@ containing each item from the original vector incremented by 1. Filename: src/main.rs ```rust -let v1: Vec = vec![1, 2, 3]; - -let v2: Vec<_> = v1.iter().map(|x| x + 1).collect(); - -assert_eq!(v2, vec![2, 3, 4]); +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-18/src/main.rs:here}} ``` Listing 13-18: Calling the `map` method to create a new @@ -237,36 +197,7 @@ instances. It will return only shoes that are the specified size. Filename: src/lib.rs ```rust -#[derive(PartialEq, Debug)] -struct Shoe { - size: u32, - style: String, -} - -fn shoes_in_my_size(shoes: Vec, shoe_size: u32) -> Vec { - shoes.into_iter() - .filter(|s| s.size == shoe_size) - .collect() -} - -#[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_my_size(shoes, 10); - - assert_eq!( - in_my_size, - vec![ - Shoe { size: 10, style: String::from("sneaker") }, - Shoe { size: 10, style: String::from("boot") }, - ] - ); -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-19/src/lib.rs}} ``` Listing 13-19: Using the `filter` method with a closure @@ -311,15 +242,7 @@ Listing 13-20 has the definition of the `Counter` struct and an associated Filename: src/lib.rs ```rust -struct Counter { - count: u32, -} - -impl Counter { - fn new() -> Counter { - Counter { count: 0 } - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-20/src/lib.rs}} ``` Listing 13-20: Defining the `Counter` struct and a `new` @@ -339,23 +262,7 @@ iterator is used, as shown in Listing 13-21: Filename: src/lib.rs ```rust -# struct Counter { -# count: u32, -# } -# -impl Iterator for Counter { - type Item = u32; - - fn next(&mut self) -> Option { - self.count += 1; - - if self.count < 6 { - Some(self.count) - } else { - None - } - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-21/src/lib.rs:here}} ``` Listing 13-21: Implementing the `Iterator` trait on our @@ -380,35 +287,7 @@ with the iterator created from a vector in Listing 13-15. Filename: src/lib.rs ```rust -# struct Counter { -# count: u32, -# } -# -# impl Iterator for Counter { -# type Item = u32; -# -# fn next(&mut self) -> Option { -# self.count += 1; -# -# if self.count < 6 { -# Some(self.count) -# } else { -# None -# } -# } -# } -# -#[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); -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-22/src/lib.rs:here}} ``` Listing 13-22: Testing the functionality of the `next` @@ -433,41 +312,7 @@ together, we could do so, as shown in the test in Listing 13-23: Filename: src/lib.rs ```rust -# struct Counter { -# count: u32, -# } -# -# impl Counter { -# fn new() -> Counter { -# Counter { count: 0 } -# } -# } -# -# impl Iterator for Counter { -# // Our iterator will produce u32s -# type Item = u32; -# -# fn next(&mut self) -> Option { -# // increment our count. This is why we started at zero. -# self.count += 1; -# -# // check to see if we've finished counting or not. -# if self.count < 6 { -# Some(self.count) -# } else { -# None -# } -# } -# } -# -#[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); -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-23/src/lib.rs:here}} ``` Listing 13-23: Using a variety of `Iterator` trait diff --git a/src/ch13-03-improving-our-io-project.md b/src/ch13-03-improving-our-io-project.md index e6ee68dc..0473b2cb 100644 --- a/src/ch13-03-improving-our-io-project.md +++ b/src/ch13-03-improving-our-io-project.md @@ -5,7 +5,6 @@ Chapter 12 by using iterators to make places in the code clearer and more concise. Let’s look at how iterators can improve our implementation of the `Config::new` function and the `search` function. - ### Removing a `clone` Using an Iterator In Listing 12-6, we added code that took a slice of `String` values and created @@ -17,20 +16,7 @@ Listing 12-23: Filename: src/lib.rs ```rust,ignore -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 }) - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs:ch13}} ``` Listing 13-24: Reproduction of the `Config::new` function @@ -61,16 +47,7 @@ Open your I/O project’s *src/main.rs* file, which should look like this: Filename: src/main.rs ```rust,ignore -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-- -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs:ch13}} ``` We’ll change the start of the `main` function that we had in Listing 12-24 to @@ -80,14 +57,7 @@ well. Filename: src/main.rs ```rust,ignore -fn main() { - let config = Config::new(env::args()).unwrap_or_else(|err| { - eprintln!("Problem parsing arguments: {}", err); - process::exit(1); - }); - - // --snip-- -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-25/src/main.rs:here}} ``` Listing 13-25: Passing the return value of `env::args` to @@ -106,9 +76,7 @@ body. Filename: src/lib.rs ```rust,ignore -impl Config { - pub fn new(mut args: std::env::Args) -> Result { - // --snip-- +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-26/src/lib.rs:here}} ``` Listing 13-26: Updating the signature of `Config::new` to @@ -131,34 +99,7 @@ Listing 12-23 to use the `next` method: Filename: src/lib.rs ```rust -# fn main() {} -# use std::env; -# -# struct Config { -# query: String, -# filename: String, -# 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 }) - } -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-27/src/lib.rs:here}} ``` Listing 13-27: Changing the body of `Config::new` to use @@ -180,17 +121,7 @@ project, which is reproduced here in Listing 13-28 as it was in Listing 12-19: Filename: src/lib.rs ```rust,ignore -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 -} +{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-19/src/lib.rs:ch13}} ``` Listing 13-28: The implementation of the `search` @@ -206,11 +137,7 @@ concurrent access to the `results` vector. Listing 13-29 shows this change: Filename: src/lib.rs ```rust,ignore -pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - contents.lines() - .filter(|line| line.contains(query)) - .collect() -} +{{#rustdoc_include ../listings/ch13-functional-features/listing-13-29/src/lib.rs:here}} ``` Listing 13-29: Using iterator adaptor methods in the diff --git a/src/ch14-01-release-profiles.md b/src/ch14-01-release-profiles.md index ab240051..24a36aef 100644 --- a/src/ch14-01-release-profiles.md +++ b/src/ch14-01-release-profiles.md @@ -12,11 +12,18 @@ and the `release` profile has good defaults for release builds. These profile names might be familiar from the output of your builds: + + ```text $ cargo build - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.0s $ cargo build --release - Finished release [optimized] target(s) in 0.0 secs + Finished release [optimized] target(s) in 0.0s ``` The `dev` and `release` shown in this build output indicate that the compiler diff --git a/src/ch14-02-publishing-to-crates-io.md b/src/ch14-02-publishing-to-crates-io.md index f1b10f7c..4e5c2206 100644 --- a/src/ch14-02-publishing-to-crates-io.md +++ b/src/ch14-02-publishing-to-crates-io.md @@ -29,19 +29,7 @@ for an `add_one` function in a crate named `my_crate`: Filename: src/lib.rs ```rust,ignore -/// 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 -} +{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-01/src/lib.rs}} ``` Listing 14-1: A documentation comment for a @@ -96,6 +84,12 @@ that don’t work because the code has changed since the documentation was written. If we run `cargo test` with the documentation for the `add_one` function from Listing 14-1, we will see a section in the test results like this: + + ```text Doc-tests my_crate @@ -125,13 +119,7 @@ shown in Listing 14-2: Filename: src/lib.rs ```rust,ignore -//! # My Crate -//! -//! `my_crate` is a collection of utilities to make performing certain -//! calculations more convenient. - -/// Adds one to the number given. -// --snip-- +{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-02/src/lib.rs:here}} ``` Listing 14-2: Documentation for the `my_crate` crate as a @@ -189,37 +177,7 @@ function named `mix`, as shown in Listing 14-3: Filename: src/lib.rs ```rust -//! # 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-- -# SecondaryColor::Orange - } -} -# fn main() {} +{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-03/src/lib.rs:here}} ``` Listing 14-3: An `art` library with items organized into @@ -245,14 +203,7 @@ currently defined. Listing 14-4 shows an example of a crate that uses the Filename: src/main.rs ```rust,ignore -use art::kinds::PrimaryColor; -use art::utils::mix; - -fn main() { - let red = PrimaryColor::Red; - let yellow = PrimaryColor::Yellow; - mix(red, yellow); -} +{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-04/src/main.rs}} ``` Listing 14-4: A crate using the `art` crate’s items with @@ -276,21 +227,7 @@ items at the top level, as shown in Listing 14-5: Filename: src/lib.rs ```rust,ignore -//! # 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-- -} - -pub mod utils { - // --snip-- -} +{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-05/src/lib.rs:here}} ``` Listing 14-5: Adding `pub use` statements to re-export @@ -312,12 +249,7 @@ structure in Listing 14-5, as shown in Listing 14-6: Filename: src/main.rs ```rust,ignore -use art::PrimaryColor; -use art::mix; - -fn main() { - // --snip-- -} +{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-06/src/main.rs:here}} ``` Listing 14-6: A program using the re-exported items from @@ -380,13 +312,19 @@ name = "guessing_game" Even if you’ve chosen a unique name, when you run `cargo publish` to publish the crate at this point, you’ll get a warning and then an error: + + ```text $ cargo publish - Updating registry `https://github.com/rust-lang/crates.io-index` -warning: manifest has no description, license, license-file, documentation, -homepage or repository. + Updating crates.io index +warning: manifest has no description, license, license-file, documentation, homepage or repository. +See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info. --snip-- -error: api errors: missing or empty metadata fields: description, license. +error: api errors (status 200 OK): missing or empty metadata fields: description, license. Please see https://doc.rust-lang.org/cargo/reference/manifest.html for how to upload metadata ``` The reason is that you’re missing some crucial information: a description and @@ -461,15 +399,21 @@ no limit to the number of crate versions you can publish. Run the `cargo publish` command again. It should succeed now: + + ```text $ cargo publish - Updating registry `https://github.com/rust-lang/crates.io-index` -Packaging guessing_game v0.1.0 (file:///projects/guessing_game) -Verifying guessing_game v0.1.0 (file:///projects/guessing_game) -Compiling guessing_game v0.1.0 + Updating crates.io index + Packaging guessing_game v0.1.0 (file:///projects/guessing_game) + Verifying guessing_game v0.1.0 (file:///projects/guessing_game) + Compiling guessing_game v0.1.0 (file:///projects/guessing_game/target/package/guessing_game-0.1.0) - Finished dev [unoptimized + debuginfo] target(s) in 0.19 secs -Uploading guessing_game v0.1.0 (file:///projects/guessing_game) + Finished dev [unoptimized + debuginfo] target(s) in 0.19s + Uploading guessing_game v0.1.0 (file:///projects/guessing_game) ``` Congratulations! You’ve now shared your code with the Rust community, and diff --git a/src/ch14-03-cargo-workspaces.md b/src/ch14-03-cargo-workspaces.md index a662ac21..070a523a 100644 --- a/src/ch14-03-cargo-workspaces.md +++ b/src/ch14-03-cargo-workspaces.md @@ -33,19 +33,22 @@ by specifying the path to our binary crate; in this case, that path is *adder*: Filename: Cargo.toml ```toml -[workspace] - -members = [ - "adder", -] +{{#include ../listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/Cargo.toml}} ``` Next, we’ll create the `adder` binary crate by running `cargo new` within the *add* directory: + + ```text $ cargo new adder - Created binary (application) `adder` project + Created binary (application) `adder` package ``` At this point, we can build the workspace by running `cargo build`. The files @@ -81,19 +84,21 @@ Change the top-level *Cargo.toml* to specify the *add-one* path in the Filename: Cargo.toml ```toml -[workspace] - -members = [ - "adder", - "add-one", -] +{{#include ../listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/Cargo.toml}} ``` Then generate a new library crate named `add-one`: + + ```text $ cargo new add-one --lib - Created library `add-one` project + Created library `add-one` package ``` Your *add* directory should now have these directories and files: @@ -117,9 +122,7 @@ In the *add-one/src/lib.rs* file, let’s add an `add_one` function: Filename: add-one/src/lib.rs ```rust -pub fn add_one(x: i32) -> i32 { - x + 1 -} +{{#rustdoc_include ../listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/add-one/src/lib.rs}} ``` Now that we have a library crate in the workspace, we can have the binary crate @@ -129,9 +132,7 @@ dependency on `add-one` to *adder/Cargo.toml*. Filename: adder/Cargo.toml ```toml -[dependencies] - -add-one = { path = "../add-one" } +{{#include ../listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/Cargo.toml:7:9}} ``` Cargo doesn’t assume that crates in a workspace will depend on each other, so @@ -145,12 +146,7 @@ function to call the `add_one` function, as in Listing 14-7. Filename: adder/src/main.rs ```rust,ignore -use add_one; - -fn main() { - let num = 10; - println!("Hello, world! {} plus one is {}!", num, add_one::add_one(num)); -} +{{#rustdoc_include ../listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs}} ``` Listing 14-7: Using the `add-one` library crate from the @@ -159,20 +155,32 @@ fn main() { Let’s build the workspace by running `cargo build` in the top-level *add* directory! + + ```text $ cargo build Compiling add-one v0.1.0 (file:///projects/add/add-one) Compiling adder v0.1.0 (file:///projects/add/adder) - Finished dev [unoptimized + debuginfo] target(s) in 0.68 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.68s ``` To run the binary crate from the *add* directory, we need to specify which package in the workspace we want to use by using the `-p` argument and the package name with `cargo run`: + + ```text $ cargo run -p adder - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.0s Running `target/debug/adder` Hello, world! 10 plus one is 11! ``` @@ -201,14 +209,20 @@ crate: Filename: add-one/Cargo.toml ```toml -[dependencies] -rand = "0.5.5" +{{#include ../listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/add-one/Cargo.toml:7:8}} ``` We can now add `use rand;` to the *add-one/src/lib.rs* file, and building the whole workspace by running `cargo build` in the *add* directory will bring in and compile the `rand` crate: + + + ```text $ cargo build Updating crates.io index @@ -217,7 +231,7 @@ $ cargo build Compiling rand v0.5.5 Compiling add-one v0.1.0 (file:///projects/add/add-one) Compiling adder v0.1.0 (file:///projects/add/adder) - Finished dev [unoptimized + debuginfo] target(s) in 10.18 secs + Finished dev [unoptimized + debuginfo] target(s) in 10.18s ``` The top-level *Cargo.lock* now contains information about the dependency of @@ -226,14 +240,20 @@ workspace, we can’t use it in other crates in the workspace unless we add `rand` to their *Cargo.toml* files as well. For example, if we add `use rand;` to the *adder/src/main.rs* file for the `adder` crate, we’ll get an error: + + ```text $ cargo build Compiling adder v0.1.0 (file:///projects/add/adder) -error: use of unstable library feature 'rand': use `rand` from crates.io (see -issue #27703) - --> adder/src/main.rs:1:1 +error[E0432]: unresolved import `rand` + --> adder/src/main.rs:1:5 | 1 | use rand; + | ^^^^ no `rand` external crate ``` To fix this, edit the *Cargo.toml* file for the `adder` crate and indicate that @@ -253,28 +273,22 @@ within the `add_one` crate: Filename: add-one/src/lib.rs ```rust -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)); - } -} +{{#rustdoc_include ../listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add-one/src/lib.rs}} ``` Now run `cargo test` in the top-level *add* directory: + + ```text $ cargo test Compiling add-one v0.1.0 (file:///projects/add/add-one) Compiling adder v0.1.0 (file:///projects/add/adder) - Finished dev [unoptimized + debuginfo] target(s) in 0.27 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.27s Running target/debug/deps/add_one-f0253159197f7841 running 1 test @@ -305,9 +319,15 @@ We can also run tests for one particular crate in a workspace from the top-level directory by using the `-p` flag and specifying the name of the crate we want to test: + + ```text $ cargo test -p add-one - Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.00s Running target/debug/deps/add_one-b3235fea9a156f74 running 1 test diff --git a/src/ch14-04-installing-binaries.md b/src/ch14-04-installing-binaries.md index a654a371..5f9b43ed 100644 --- a/src/ch14-04-installing-binaries.md +++ b/src/ch14-04-installing-binaries.md @@ -21,17 +21,25 @@ For example, in Chapter 12 we mentioned that there’s a Rust implementation of the `grep` tool called `ripgrep` for searching files. If we want to install `ripgrep`, we can run the following: + + ```text $ cargo install ripgrep -Updating registry `https://github.com/rust-lang/crates.io-index` - Downloading ripgrep v0.3.2 - --snip-- - Compiling ripgrep v0.3.2 - Finished release [optimized + debuginfo] target(s) in 97.91 secs + Updating crates.io index + Downloaded ripgrep v11.0.2 + Downloaded 1 crate (243.3 KB) in 0.88s + Installing ripgrep v11.0.2 +--snip-- + Compiling ripgrep v11.0.2 + Finished release [optimized + debuginfo] target(s) in 3m 10s Installing ~/.cargo/bin/rg + Installed package `ripgrep v11.0.2` (executable `rg`) ``` -The last line of the output shows the location and the name of the installed -binary, which in the case of `ripgrep` is `rg`. As long as the installation -directory is in your `$PATH`, as mentioned previously, you can then run `rg ---help` and start using a faster, rustier tool for searching files! +The second-to-last line of the output shows the location and the name of the +installed binary, which in the case of `ripgrep` is `rg`. As long as the +installation directory is in your `$PATH`, as mentioned previously, you can +then run `rg --help` and start using a faster, rustier tool for searching files! diff --git a/src/ch15-01-box.md b/src/ch15-01-box.md index 2b9a51b3..1605928d 100644 --- a/src/ch15-01-box.md +++ b/src/ch15-01-box.md @@ -38,10 +38,7 @@ Listing 15-1 shows how to use a box to store an `i32` value on the heap: Filename: src/main.rs ```rust -fn main() { - let b = Box::new(5); - println!("b = {}", b); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-01/src/main.rs}} ``` Listing 15-1: Storing an `i32` value on the heap using a @@ -109,10 +106,7 @@ we’ll demonstrate. Filename: src/main.rs ```rust,ignore,does_not_compile -enum List { - Cons(i32, List), - Nil, -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-02/src/main.rs:here}} ``` Listing 15-2: The first attempt at defining an enum to @@ -129,11 +123,7 @@ Listing 15-3: Filename: src/main.rs ```rust,ignore,does_not_compile -use crate::List::{Cons, Nil}; - -fn main() { - let list = Cons(1, Cons(2, Cons(3, Nil))); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-03/src/main.rs:here}} ``` Listing 15-3: Using the `List` enum to store the list `1, @@ -148,16 +138,7 @@ If we try to compile the code in Listing 15-3, we get the error shown in Listing 15-4: ```text -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 indirection (e.g., a `Box`, `Rc`, or `&`) at some point to - make `List` representable +{{#include ../listings/ch15-smart-pointers/listing-15-03/output.txt}} ``` Listing 15-4: The error we get when attempting to define @@ -176,12 +157,7 @@ Recall the `Message` enum we defined in Listing 6-2 when we discussed enum definitions in Chapter 6: ```rust -enum Message { - Quit, - Move { x: i32, y: i32 }, - Write(String), - ChangeColor(i32, i32, i32), -} +{{#rustdoc_include ../listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs:here}} ``` To determine how much space to allocate for a `Message` value, Rust goes @@ -211,9 +187,12 @@ Rust can’t figure out how much space to allocate for recursively defined types so the compiler gives the error in Listing 15-4. But the error does include this helpful suggestion: + + ```text - = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to - make `List` representable + = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable ``` In this suggestion, “indirection” means that instead of storing a value @@ -235,19 +214,7 @@ of the `List` in Listing 15-3 to the code in Listing 15-5, which will compile: Filename: src/main.rs ```rust -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)))))); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-05/src/main.rs}} ``` Listing 15-5: Definition of `List` that uses `Box` in diff --git a/src/ch15-02-deref.md b/src/ch15-02-deref.md index e0fae5b1..63477c28 100644 --- a/src/ch15-02-deref.md +++ b/src/ch15-02-deref.md @@ -29,13 +29,7 @@ reference to the data: Filename: src/main.rs ```rust -fn main() { - let x = 5; - let y = &x; - - assert_eq!(5, x); - assert_eq!(5, *y); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-06/src/main.rs}} ``` Listing 15-6: Using the dereference operator to follow a @@ -52,14 +46,7 @@ If we tried to write `assert_eq!(5, y);` instead, we would get this compilation error: ```text -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 `std::cmp::PartialEq<&{integer}>` is not implemented for - `{integer}` +{{#include ../listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt}} ``` Comparing a number and a reference to a number isn’t allowed because they’re @@ -74,13 +61,7 @@ reference; the dereference operator will work as shown in Listing 15-7: Filename: src/main.rs ```rust -fn main() { - let x = 5; - let y = Box::new(x); - - assert_eq!(5, x); - assert_eq!(5, *y); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-07/src/main.rs}} ``` Listing 15-7: Using the dereference operator on a @@ -107,13 +88,7 @@ Listing 15-8 defines a `MyBox` type in the same way. We’ll also define a Filename: src/main.rs ```rust -struct MyBox(T); - -impl MyBox { - fn new(x: T) -> MyBox { - MyBox(x) - } -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-08/src/main.rs:here}} ``` Listing 15-8: Defining a `MyBox` type @@ -131,13 +106,7 @@ code in Listing 15-9 won’t compile because Rust doesn’t know how to derefere Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let x = 5; - let y = MyBox::new(x); - - assert_eq!(5, x); - assert_eq!(5, *y); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-09/src/main.rs:here}} ``` Listing 15-9: Attempting to use `MyBox` in the same @@ -146,11 +115,7 @@ way we used references and `Box` Here’s the resulting compilation error: ```text -error[E0614]: type `MyBox<{integer}>` cannot be dereferenced - --> src/main.rs:14:19 - | -14 | assert_eq!(5, *y); - | ^^ +{{#include ../listings/ch15-smart-pointers/listing-15-09/output.txt}} ``` Our `MyBox` type can’t be dereferenced because we haven’t implemented that @@ -168,16 +133,7 @@ contains an implementation of `Deref` to add to the definition of `MyBox`: Filename: src/main.rs ```rust -use std::ops::Deref; - -# struct MyBox(T); -impl Deref for MyBox { - type Target = T; - - fn deref(&self) -> &T { - &self.0 - } -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-10/src/main.rs:here}} ``` Listing 15-10: Implementing `Deref` on `MyBox` @@ -247,9 +203,7 @@ parameter: Filename: src/main.rs ```rust -fn hello(name: &str) { - println!("Hello, {}!", name); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-11/src/main.rs:here}} ``` Listing 15-11: A `hello` function that has the parameter @@ -262,32 +216,7 @@ with a reference to a value of type `MyBox`, as shown in Listing 15-12: Filename: src/main.rs ```rust -# use std::ops::Deref; -# -# struct MyBox(T); -# -# impl MyBox { -# fn new(x: T) -> MyBox { -# MyBox(x) -# } -# } -# -# impl Deref for MyBox { -# type Target = T; -# -# fn deref(&self) -> &T { -# &self.0 -# } -# } -# -# fn hello(name: &str) { -# println!("Hello, {}!", name); -# } -# -fn main() { - let m = MyBox::new(String::from("Rust")); - hello(&m); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-12/src/main.rs:here}} ``` Listing 15-12: Calling `hello` with a reference to a @@ -308,32 +237,7 @@ of type `&MyBox`. Filename: src/main.rs ```rust -# use std::ops::Deref; -# -# struct MyBox(T); -# -# impl MyBox { -# fn new(x: T) -> MyBox { -# MyBox(x) -# } -# } -# -# impl Deref for MyBox { -# type Target = T; -# -# fn deref(&self) -> &T { -# &self.0 -# } -# } -# -# fn hello(name: &str) { -# println!("Hello, {}!", name); -# } -# -fn main() { - let m = MyBox::new(String::from("Rust")); - hello(&(*m)[..]); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-13/src/main.rs:here}} ``` Listing 15-13: The code we would have to write if Rust diff --git a/src/ch15-03-drop.md b/src/ch15-03-drop.md index 333e4e2c..8566f030 100644 --- a/src/ch15-03-drop.md +++ b/src/ch15-03-drop.md @@ -30,21 +30,7 @@ function. Filename: src/main.rs ```rust -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."); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-14/src/main.rs}} ``` Listing 15-14: A `CustomSmartPointer` struct that @@ -66,9 +52,7 @@ call the `drop` method explicitly. When we run this program, we’ll see the following output: ```text -CustomSmartPointers created. -Dropping CustomSmartPointer with data `other stuff`! -Dropping CustomSmartPointer with data `my stuff`! +{{#include ../listings/ch15-smart-pointers/listing-15-14/output.txt}} ``` Rust automatically called `drop` for us when our instances went out of scope, @@ -96,12 +80,7 @@ compiler error: Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let c = CustomSmartPointer { data: String::from("some data") }; - println!("CustomSmartPointer created."); - c.drop(); - println!("CustomSmartPointer dropped before the end of main."); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-15/src/main.rs:here}} ``` Listing 15-15: Attempting to call the `drop` method from @@ -110,11 +89,7 @@ the `Drop` trait manually to clean up early When we try to compile this code, we’ll get this error: ```text -error[E0040]: explicit use of destructor method - --> src/main.rs:14:7 - | -14 | c.drop(); - | ^^^^ explicit destructor calls not allowed +{{#include ../listings/ch15-smart-pointers/listing-15-15/output.txt}} ``` This error message states that we’re not allowed to explicitly call `drop`. The @@ -140,22 +115,7 @@ an argument. The function is in the prelude, so we can modify `main` in Listing Filename: src/main.rs ```rust -# 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("some data") }; - println!("CustomSmartPointer created."); - drop(c); - println!("CustomSmartPointer dropped before the end of main."); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-16/src/main.rs:here}} ``` Listing 15-16: Calling `std::mem::drop` to explicitly @@ -164,9 +124,7 @@ drop a value before it goes out of scope Running this code will print the following: ```text -CustomSmartPointer created. -Dropping CustomSmartPointer with data `some data`! -CustomSmartPointer dropped before the end of main. +{{#include ../listings/ch15-smart-pointers/listing-15-16/output.txt}} ``` The text ```Dropping CustomSmartPointer with data `some data`!``` is printed diff --git a/src/ch15-04-rc.md b/src/ch15-04-rc.md index 7ac901ba..8990ca04 100644 --- a/src/ch15-04-rc.md +++ b/src/ch15-04-rc.md @@ -51,20 +51,7 @@ won’t work, as shown in Listing 15-17: Filename: src/main.rs ```rust,ignore,does_not_compile -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)); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-17/src/main.rs}} ``` Listing 15-17: Demonstrating we’re not allowed to have @@ -73,16 +60,7 @@ two lists using `Box` that try to share ownership of a third list When we compile this code, we get this error: ```text -error[E0382]: use of moved value: `a` - --> src/main.rs:13:30 - | -12 | let b = Cons(3, Box::new(a)); - | - value moved here -13 | let c = Cons(4, Box::new(a)); - | ^ value used here after move - | - = note: move occurs because `a` has type `List`, which does not implement - the `Copy` trait +{{#include ../listings/ch15-smart-pointers/listing-15-17/output.txt}} ``` The `Cons` variants own the data they hold, so when we create the `b` list, `a` @@ -110,19 +88,7 @@ it. Filename: src/main.rs ```rust -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)); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-18/src/main.rs}} ``` Listing 15-18: A definition of `List` that uses @@ -156,25 +122,7 @@ then we can see how the reference count changes when `c` goes out of scope. Filename: src/main.rs ```rust -# 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))))); - 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)); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-19/src/main.rs:here}} ``` Listing 15-19: Printing the reference count @@ -189,10 +137,7 @@ type also has a `weak_count`; we’ll see what `weak_count` is used for in the This code prints the following: ```text -count after creating a = 1 -count after creating b = 2 -count after creating c = 3 -count after c goes out of scope = 2 +{{#include ../listings/ch15-smart-pointers/listing-15-19/output.txt}} ``` We can see that the `Rc` in `a` has an initial reference count of 1; then diff --git a/src/ch15-05-interior-mutability.md b/src/ch15-05-interior-mutability.md index 34c002b2..959d3eb7 100644 --- a/src/ch15-05-interior-mutability.md +++ b/src/ch15-05-interior-mutability.md @@ -76,22 +76,13 @@ A consequence of the borrowing rules is that when you have an immutable value, you can’t borrow it mutably. For example, this code won’t compile: ```rust,ignore,does_not_compile -fn main() { - let x = 5; - let y = &mut x; -} +{{#rustdoc_include ../listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/src/main.rs}} ``` If you tried to compile this code, you’d get the following error: ```text -error[E0596]: cannot borrow immutable local variable `x` as mutable - --> src/main.rs:3:18 - | -2 | let x = 5; - | - consider changing this to `mut x` -3 | let y = &mut x; - | ^ cannot borrow mutably +{{#include ../listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt}} ``` However, there are situations in which it would be useful for a value to mutate @@ -134,40 +125,7 @@ called `Messenger`. Listing 15-20 shows the library code: Filename: src/lib.rs ```rust -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!"); - } - } -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-20/src/lib.rs}} ``` Listing 15-20: A library to keep track of how close a @@ -194,36 +152,7 @@ implement a mock object to do just that, but the borrow checker won’t allow it Filename: src/lib.rs ```rust,ignore,does_not_compile -#[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); - } -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-21/src/lib.rs:here}} ``` Listing 15-21: An attempt to implement a `MockMessenger` @@ -250,13 +179,7 @@ of should now have one message in it. However, there’s one problem with this test, as shown here: ```text -error[E0596]: cannot borrow immutable field `self.sent_messages` as mutable - --> src/lib.rs:52:13 - | -51 | fn send(&self, message: &str) { - | ----- use `&mut self` here to make mutable -52 | self.sent_messages.push(String::from(message)); - | ^^^^^^^^^^^^^^^^^^ cannot mutably borrow immutable field +{{#include ../listings/ch15-smart-pointers/listing-15-21/output.txt}} ``` We can’t modify the `MockMessenger` to keep track of the messages, because the @@ -273,73 +196,7 @@ shows what that looks like: Filename: src/lib.rs ```rust -# 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![]) } - } - } - - 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-- -# let mock_messenger = MockMessenger::new(); -# let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); -# limit_tracker.set_value(75); - - assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); - } -} -# fn main() {} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-22/src/lib.rs:here}} ``` Listing 15-22: Using `RefCell` to mutate an inner @@ -388,15 +245,7 @@ at runtime. Filename: src/lib.rs ```rust,ignore,panics -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)); - } -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-23/src/lib.rs:here}} ``` Listing 15-23: Creating two mutable references in the @@ -409,10 +258,7 @@ which isn’t allowed. When we run the tests for our library, the code in Listin 15-23 will compile without any errors, but the test will fail: ```text ----- tests::it_sends_an_over_75_percent_warning_message stdout ---- - thread 'tests::it_sends_an_over_75_percent_warning_message' panicked at -'already borrowed: BorrowMutError', src/libcore/result.rs:906:4 -note: Run with `RUST_BACKTRACE=1` for a backtrace. +{{#include ../listings/ch15-smart-pointers/listing-15-23/output.txt}} ``` Notice that the code panicked with the message `already borrowed: @@ -447,30 +293,7 @@ the lists: Filename: src/main.rs ```rust -#[derive(Debug)] -enum List { - Cons(Rc>, Rc), - Nil, -} - -use crate::List::{Cons, Nil}; -use std::rc::Rc; -use std::cell::RefCell; - -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(6)), Rc::clone(&a)); - let c = Cons(Rc::new(RefCell::new(10)), Rc::clone(&a)); - - *value.borrow_mut() += 10; - - println!("a after = {:?}", a); - println!("b after = {:?}", b); - println!("c after = {:?}", c); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-24/src/main.rs}} ``` Listing 15-24: Using `Rc>` to create a @@ -498,9 +321,7 @@ When we print `a`, `b`, and `c`, we can see that they all have the modified value of 15 rather than 5: ```text -a after = Cons(RefCell { value: 15 }, Nil) -b after = Cons(RefCell { value: 6 }, Cons(RefCell { value: 15 }, Nil)) -c after = Cons(RefCell { value: 10 }, Cons(RefCell { value: 15 }, Nil)) +{{#include ../listings/ch15-smart-pointers/listing-15-24/output.txt}} ``` This technique is pretty neat! By using `RefCell`, we have an outwardly diff --git a/src/ch15-06-reference-cycles.md b/src/ch15-06-reference-cycles.md index 1a919e3a..8b59ec02 100644 --- a/src/ch15-06-reference-cycles.md +++ b/src/ch15-06-reference-cycles.md @@ -17,29 +17,8 @@ starting with the definition of the `List` enum and a `tail` method in Listing Filename: src/main.rs - - ```rust -# fn main() {} -use std::rc::Rc; -use std::cell::RefCell; -use crate::List::{Cons, Nil}; - -#[derive(Debug)] -enum List { - Cons(i32, RefCell>), - Nil, -} - -impl List { - fn tail(&self) -> Option<&RefCell>> { - match self { - Cons(_, item) => Some(item), - Nil => None, - } - } -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-25/src/main.rs}} ``` Listing 15-25: A cons list definition that holds a @@ -61,47 +40,7 @@ reference counts are at various points in this process. Filename: src/main.rs ```rust -# use crate::List::{Cons, Nil}; -# use std::rc::Rc; -# use std::cell::RefCell; -# #[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() { - 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()); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-26/src/main.rs:here}} ``` Listing 15-26: Creating a reference cycle of two `List` @@ -122,13 +61,7 @@ When we run this code, keeping the last `println!` commented out for the moment, we’ll get this output: ```text -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 +{{#include ../listings/ch15-smart-pointers/listing-15-26/output.txt}} ``` The reference count of the `Rc` instances in both `a` and `b` are 2 @@ -215,14 +148,7 @@ references to its children `Node` values: Filename: src/main.rs ```rust -use std::rc::Rc; -use std::cell::RefCell; - -#[derive(Debug)] -struct Node { - value: i32, - children: RefCell>>, -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-27/src/main.rs:here}} ``` We want a `Node` to own its children, and we want to share that ownership with @@ -238,26 +164,7 @@ with the value 5 and `leaf` as one of its children, as shown in Listing 15-27: Filename: src/main.rs ```rust -# use std::rc::Rc; -# use std::cell::RefCell; -# -# #[derive(Debug)] -# struct Node { -# value: i32, -# children: RefCell>>, -# } -# -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)]), - }); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-27/src/main.rs:there}} ``` Listing 15-27: Creating a `leaf` node with no children @@ -291,15 +198,7 @@ like this: Filename: src/main.rs ```rust -use std::rc::{Rc, Weak}; -use std::cell::RefCell; - -#[derive(Debug)] -struct Node { - value: i32, - parent: RefCell>, - children: RefCell>>, -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-28/src/main.rs:here}} ``` A node will be able to refer to its parent node but doesn’t own its parent. @@ -309,35 +208,7 @@ node will have a way to refer to its parent, `branch`: Filename: src/main.rs ```rust -# use std::rc::{Rc, Weak}; -# use std::cell::RefCell; -# -# #[derive(Debug)] -# struct Node { -# value: i32, -# parent: RefCell>, -# children: RefCell>>, -# } -# -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()); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-28/src/main.rs:there}} ``` Listing 15-28: A `leaf` node with a weak reference to its @@ -390,58 +261,7 @@ in Listing 15-29: Filename: src/main.rs ```rust -# use std::rc::{Rc, Weak}; -# use std::cell::RefCell; -# -# #[derive(Debug)] -# struct Node { -# value: i32, -# parent: RefCell>, -# children: RefCell>>, -# } -# -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), - ); -} +{{#rustdoc_include ../listings/ch15-smart-pointers/listing-15-29/src/main.rs:here}} ``` Listing 15-29: Creating `branch` in an inner scope and diff --git a/src/ch16-01-threads.md b/src/ch16-01-threads.md index 5f6eb41a..6cec741d 100644 --- a/src/ch16-01-threads.md +++ b/src/ch16-01-threads.md @@ -71,22 +71,7 @@ thread and other text from a new thread: Filename: src/main.rs ```rust -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)); - } -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-01/src/main.rs}} ``` Listing 16-1: Creating a new thread to print one thing @@ -97,6 +82,10 @@ thread ends, whether or not it has finished running. The output from this program might be a little different every time, but it will look similar to the following: + + ```text hi number 1 from the main thread! hi number 1 from the spawned thread! @@ -139,24 +128,7 @@ in Listing 16-1 and call `join` to make sure the spawned thread finishes before Filename: src/main.rs ```rust -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(); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-02/src/main.rs}} ``` Listing 16-2: Saving a `JoinHandle` from `thread::spawn` @@ -168,6 +140,10 @@ thread is prevented from performing work or exiting. Because we’ve put the cal to `join` after the main thread’s `for` loop, running Listing 16-2 should produce output similar to this: + + ```text hi number 1 from the main thread! hi number 2 from the main thread! @@ -193,29 +169,16 @@ But let’s see what happens when we instead move `handle.join()` before the Filename: src/main.rs ```rust -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)); - } -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs}} ``` The main thread will wait for the spawned thread to finish and then run its `for` loop, so the output won’t be interleaved anymore, as shown here: + + ```text hi number 1 from the spawned thread! hi number 2 from the spawned thread! @@ -255,17 +218,7 @@ thread. However, this won’t yet work, as you’ll see in a moment. Filename: src/main.rs ```rust,ignore,does_not_compile -use std::thread; - -fn main() { - let v = vec![1, 2, 3]; - - let handle = thread::spawn(|| { - println!("Here's a vector: {:?}", v); - }); - - handle.join().unwrap(); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-03/src/main.rs}} ``` Listing 16-3: Attempting to use a vector created by the @@ -277,20 +230,7 @@ should be able to access `v` inside that new thread. But when we compile this example, we get the following error: ```text -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 - | -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 || { - | ^^^^^^^ +{{#include ../listings/ch16-fearless-concurrency/listing-16-03/output.txt}} ``` Rust *infers* how to capture `v`, and because `println!` only needs a reference @@ -304,19 +244,7 @@ that won’t be valid: Filename: src/main.rs ```rust,ignore,does_not_compile -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(); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-04/src/main.rs}} ``` Listing 16-4: A thread with a closure that attempts to @@ -332,9 +260,12 @@ is also invalid. Oh no! To fix the compiler error in Listing 16-3, we can use the error message’s advice: + + ```text -help: to force the closure to take ownership of `v` (and any other referenced -variables), use the `move` keyword +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 || { | ^^^^^^^ @@ -348,17 +279,7 @@ should borrow the values. The modification to Listing 16-3 shown in Listing Filename: src/main.rs ```rust -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(); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-05/src/main.rs}} ``` Listing 16-5: Using the `move` keyword to force a closure @@ -372,17 +293,7 @@ would move `v` into the closure’s environment, and we could no longer call `drop` on it in the main thread. We would get this compiler error instead: ```text -error[E0382]: use of moved value: `v` - --> src/main.rs:10:10 - | -6 | let handle = thread::spawn(move || { - | ------- value moved (into closure) here -... -10 | drop(v); // oh no! - | ^ value used here after move - | - = note: move occurs because `v` has type `std::vec::Vec`, which does - not implement the `Copy` trait +{{#include ../listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt}} ``` Rust’s ownership rules have saved us again! We got an error from the code in diff --git a/src/ch16-02-message-passing.md b/src/ch16-02-message-passing.md index 6b5c23f8..7fdbccc6 100644 --- a/src/ch16-02-message-passing.md +++ b/src/ch16-02-message-passing.md @@ -36,11 +36,7 @@ want to send over the channel. Filename: src/main.rs ```rust,ignore,does_not_compile -use std::sync::mpsc; - -fn main() { - let (tx, rx) = mpsc::channel(); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-06/src/main.rs}} ``` Listing 16-6: Creating a channel and assigning the two @@ -72,17 +68,7 @@ sending a chat message from one thread to another. Filename: src/main.rs ```rust -use std::thread; -use std::sync::mpsc; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let val = String::from("hi"); - tx.send(val).unwrap(); - }); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-07/src/main.rs}} ``` Listing 16-7: Moving `tx` to a spawned thread and sending @@ -107,20 +93,7 @@ end of the river or like getting a chat message. Filename: src/main.rs ```rust -use std::thread; -use std::sync::mpsc; - -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); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-08/src/main.rs}} ``` Listing 16-8: Receiving the value “hi” in the main thread @@ -148,6 +121,10 @@ thread is appropriate. When we run the code in Listing 16-8, we’ll see the value printed from the main thread: + + ```text Got: hi ``` @@ -167,21 +144,7 @@ this code isn’t allowed: Filename: src/main.rs ```rust,ignore,does_not_compile -use std::thread; -use std::sync::mpsc; - -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); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-09/src/main.rs}} ``` Listing 16-9: Attempting to use `val` after we’ve sent it @@ -195,16 +158,7 @@ unexpected results due to inconsistent or nonexistent data. However, Rust gives us an error if we try to compile the code in Listing 16-9: ```text -error[E0382]: use of moved value: `val` - --> src/main.rs:10:31 - | -9 | tx.send(val).unwrap(); - | --- value moved here -10 | println!("val is {}", val); - | ^^^ value used here after move - | - = note: move occurs because `val` has type `std::string::String`, which does -not implement the `Copy` trait +{{#include ../listings/ch16-fearless-concurrency/listing-16-09/output.txt}} ``` Our concurrency mistake has caused a compile time error. The `send` function @@ -223,31 +177,7 @@ pause for a second between each message. Filename: src/main.rs ```rust -use std::thread; -use std::sync::mpsc; -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); - } -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-10/src/main.rs}} ``` Listing 16-10: Sending multiple messages and pausing @@ -265,6 +195,10 @@ printing it. When the channel is closed, iteration will end. When running the code in Listing 16-10, you should see the following output with a 1-second pause in between each line: + + ```text Got: hi Got: from @@ -286,50 +220,7 @@ so by cloning the transmitting half of the channel, as shown in Listing 16-11: Filename: src/main.rs ```rust -# use std::thread; -# use std::sync::mpsc; -# use std::time::Duration; -# -# fn main() { -// --snip-- - -let (tx, rx) = mpsc::channel(); - -let tx1 = mpsc::Sender::clone(&tx); -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-- -# } +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-11/src/main.rs:here}} ``` Listing 16-11: Sending multiple messages from multiple @@ -343,6 +234,10 @@ messages to the receiving end of the channel. When you run the code, your output should look something like this: + + ```text Got: hi Got: more diff --git a/src/ch16-03-shared-state.md b/src/ch16-03-shared-state.md index c39d302b..50ce56cc 100644 --- a/src/ch16-03-shared-state.md +++ b/src/ch16-03-shared-state.md @@ -54,18 +54,7 @@ single-threaded context, as shown in Listing 16-12: Filename: src/main.rs ```rust -use std::sync::Mutex; - -fn main() { - let m = Mutex::new(5); - - { - let mut num = m.lock().unwrap(); - *num = 6; - } - - println!("m = {:?}", m); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-12/src/main.rs}} ``` Listing 16-12: Exploring the API of `Mutex` in a @@ -110,28 +99,7 @@ a compiler error, and we’ll use that error to learn more about using Filename: src/main.rs ```rust,ignore,does_not_compile -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()); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-13/src/main.rs}} ``` Listing 16-13: Ten threads each increment a counter @@ -153,17 +121,7 @@ program. We hinted that this example wouldn’t compile. Now let’s find out why! ```text -error[E0382]: use of moved value: `counter` - --> src/main.rs:9:36 - | -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 - | - = note: move occurs because `counter` has type `std::sync::Mutex`, -which does not implement the `Copy` trait +{{#include ../listings/ch16-fearless-concurrency/listing-16-13/output.txt}} ``` The error message states that the `counter` value was moved in the previous @@ -183,30 +141,7 @@ errors, we’ll also switch back to using the `for` loop, and we’ll keep the Filename: src/main.rs ```rust,ignore,does_not_compile -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()); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-14/src/main.rs}} ``` Listing 16-14: Attempting to use `Rc` to allow @@ -216,19 +151,7 @@ Once again, we compile and get... different errors! The compiler is teaching us a lot. ```text -error[E0277]: `std::rc::Rc>` cannot be sent between threads safely - --> src/main.rs:11:22 - | -11 | let handle = thread::spawn(move || { - | ^^^^^^^^^^^^^ `std::rc::Rc>` -cannot be sent between threads safely - | - = help: within `[closure@src/main.rs:11:36: 14:10 -counter:std::rc::Rc>]`, the trait `std::marker::Send` -is not implemented for `std::rc::Rc>` - = note: required because it appears within the type -`[closure@src/main.rs:11:36: 14:10 counter:std::rc::Rc>]` - = note: required by `std::thread::spawn` +{{#include ../listings/ch16-fearless-concurrency/listing-16-14/output.txt}} ``` Wow, that error message is very wordy! Here’s the important part to focus @@ -271,29 +194,7 @@ our program by changing the `use` line, the call to `new`, and the call to Filename: src/main.rs ```rust -use std::sync::{Mutex, Arc}; -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()); -} +{{#rustdoc_include ../listings/ch16-fearless-concurrency/listing-16-15/src/main.rs}} ``` Listing 16-15: Using an `Arc` to wrap the `Mutex` @@ -301,6 +202,10 @@ to be able to share ownership across multiple threads This code will print the following: + + ```text Result: 10 ``` diff --git a/src/ch17-01-what-is-oo.md b/src/ch17-01-what-is-oo.md index 15eae18e..e197cbfa 100644 --- a/src/ch17-01-what-is-oo.md +++ b/src/ch17-01-what-is-oo.md @@ -47,10 +47,7 @@ cache the calculated average for us. Listing 17-1 has the definition of the Filename: src/lib.rs ```rust -pub struct AveragedCollection { - list: Vec, - average: f64, -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-01/src/lib.rs}} ``` Listing 17-1: An `AveragedCollection` struct that @@ -66,36 +63,7 @@ on the struct, as shown in Listing 17-2: Filename: src/lib.rs ```rust -# pub struct AveragedCollection { -# list: Vec, -# average: f64, -# } -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; - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-02/src/lib.rs:here}} ``` Listing 17-2: Implementations of the public methods diff --git a/src/ch17-02-trait-objects.md b/src/ch17-02-trait-objects.md index d7369bff..b4f7e428 100644 --- a/src/ch17-02-trait-objects.md +++ b/src/ch17-02-trait-objects.md @@ -69,9 +69,7 @@ Listing 17-3 shows how to define a trait named `Draw` with one method named Filename: src/lib.rs ```rust -pub trait Draw { - fn draw(&self); -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-03/src/lib.rs}} ``` Listing 17-3: Definition of the `Draw` trait @@ -85,13 +83,7 @@ a `Box` that implements the `Draw` trait. Filename: src/lib.rs ```rust -# pub trait Draw { -# fn draw(&self); -# } -# -pub struct Screen { - pub components: Vec>, -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-04/src/lib.rs:here}} ``` Listing 17-4: Definition of the `Screen` struct with a @@ -104,21 +96,7 @@ On the `Screen` struct, we’ll define a method named `run` that will call the Filename: src/lib.rs ```rust -# 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(); - } - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-05/src/lib.rs:here}} ``` Listing 17-5: A `run` method on `Screen` that calls the @@ -134,22 +112,7 @@ as in Listing 17-6: Filename: src/lib.rs ```rust -# pub trait Draw { -# fn draw(&self); -# } -# -pub struct Screen { - pub components: Vec, -} - -impl Screen - where T: Draw { - pub fn run(&self) { - for component in self.components.iter() { - component.draw(); - } - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-06/src/lib.rs:here}} ``` Listing 17-6: An alternate implementation of the `Screen` @@ -176,21 +139,7 @@ might have fields for `width`, `height`, and `label`, as shown in Listing 17-7: Filename: src/lib.rs ```rust -# pub trait Draw { -# fn draw(&self); -# } -# -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 - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-07/src/lib.rs:here}} ``` Listing 17-7: A `Button` struct that implements the @@ -213,19 +162,7 @@ If someone using our library decides to implement a `SelectBox` struct that has Filename: src/main.rs ```rust,ignore -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 - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-08/src/main.rs:here}} ``` Listing 17-8: Another crate using `gui` and implementing @@ -240,30 +177,7 @@ components. Listing 17-9 shows this implementation: Filename: src/main.rs ```rust,ignore -use gui::{Screen, Button}; - -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(); -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-09/src/main.rs:here}} ``` Listing 17-9: Using trait objects to store values of @@ -297,17 +211,7 @@ with a `String` as a component: Filename: src/main.rs ```rust,ignore,does_not_compile -use gui::Screen; - -fn main() { - let screen = Screen { - components: vec![ - Box::new(String::from("Hi")), - ], - }; - - screen.run(); -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-10/src/main.rs}} ``` Listing 17-10: Attempting to use a type that doesn’t @@ -316,14 +220,7 @@ implement the trait object’s trait We’ll get this error because `String` doesn’t implement the `Draw` trait: ```text -error[E0277]: the trait bound `std::string::String: gui::Draw` is not satisfied - --> src/main.rs:7:13 - | - 7 | Box::new(String::from("Hi")), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait gui::Draw is not - implemented for `std::string::String` - | - = note: required for the cast to the object type `gui::Draw` +{{#include ../listings/ch17-oop/listing-17-10/output.txt}} ``` This error lets us know that either we’re passing something to `Screen` we @@ -398,22 +295,13 @@ tried to implement the `Screen` struct in Listing 17-4 to hold types that implement the `Clone` trait instead of the `Draw` trait, like this: ```rust,ignore,does_not_compile -pub struct Screen { - pub components: Vec>, -} +{{#rustdoc_include ../listings/ch17-oop/no-listing-01-trait-object-of-clone/src/lib.rs}} ``` We would get this error: ```text -error[E0038]: the trait `std::clone::Clone` cannot be made into an object - --> src/lib.rs:2:5 - | -2 | pub components: Vec>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` - cannot be made into an object - | - = note: the trait cannot require that `Self : Sized` +{{#include ../listings/ch17-oop/no-listing-01-trait-object-of-clone/output.txt}} ``` This error means you can’t use this trait as a trait object in this way. If diff --git a/src/ch17-03-oo-design-patterns.md b/src/ch17-03-oo-design-patterns.md index 4ffb3a01..b395da9c 100644 --- a/src/ch17-03-oo-design-patterns.md +++ b/src/ch17-03-oo-design-patterns.md @@ -35,20 +35,7 @@ because we haven’t implemented the `blog` crate yet. Filename: src/main.rs ```rust,ignore -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()); -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-11/src/main.rs:all}} ``` Listing 17-11: Code that demonstrates the desired @@ -89,25 +76,7 @@ inside an `Option` in a private field named `state`. You’ll see why the Filename: src/lib.rs ```rust -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 {} +{{#rustdoc_include ../listings/ch17-oop/listing-17-12/src/lib.rs}} ``` Listing 17-12: Definition of a `Post` struct and a `new` @@ -139,16 +108,7 @@ Post` block: Filename: src/lib.rs ```rust -# pub struct Post { -# content: String, -# } -# -impl Post { - // --snip-- - pub fn add_text(&mut self, text: &str) { - self.content.push_str(text); - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-13/src/lib.rs:here}} ``` Listing 17-13: Implementing the `add_text` method to add @@ -176,16 +136,7 @@ be empty. Listing 17-14 shows this placeholder implementation: Filename: src/lib.rs ```rust -# pub struct Post { -# content: String, -# } -# -impl Post { - // --snip-- - pub fn content(&self) -> &str { - "" - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-14/src/lib.rs:here}} ``` Listing 17-14: Adding a placeholder implementation for @@ -202,39 +153,7 @@ change its state from `Draft` to `PendingReview`. Listing 17-15 shows this code: Filename: src/lib.rs ```rust -# pub struct Post { -# state: Option>, -# content: String, -# } -# -impl Post { - // --snip-- - 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 - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-15/src/lib.rs:here}} ``` Listing 17-15: Implementing `request_review` methods on @@ -291,62 +210,7 @@ state is approved, as shown in Listing 17-16: Filename: src/lib.rs ```rust -# pub struct Post { -# state: Option>, -# content: String, -# } -# -impl Post { - // --snip-- - 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 { -# fn request_review(self: Box) -> Box { -# Box::new(PendingReview {}) -# } -# - // --snip-- - fn approve(self: Box) -> Box { - self - } -} - -struct PendingReview {} - -impl State for PendingReview { -# fn request_review(self: Box) -> Box { -# self -# } -# - // --snip-- - 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 - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-16/src/lib.rs:here}} ``` Listing 17-16: Implementing the `approve` method on @@ -368,22 +232,8 @@ otherwise, we want to return an empty string slice, as shown in Listing 17-17: Filename: src/lib.rs -```rust -# trait State { -# fn content<'a>(&self, post: &'a Post) -> &'a str; -# } -# pub struct Post { -# state: Option>, -# content: String, -# } -# -impl Post { - // --snip-- - pub fn content(&self) -> &str { - self.state.as_ref().unwrap().content(self) - } - // --snip-- -} +```rust,ignore,does_not_compile +{{#rustdoc_include ../listings/ch17-oop/listing-17-17/src/lib.rs:here}} ``` Listing 17-17: Updating the `content` method on `Post` to @@ -418,25 +268,7 @@ Listing 17-18: Filename: src/lib.rs ```rust -# pub struct Post { -# content: String -# } -trait State { - // --snip-- - fn content<'a>(&self, post: &'a Post) -> &'a str { - "" - } -} - -// --snip-- -struct Published {} - -impl State for Published { - // --snip-- - fn content<'a>(&self, post: &'a Post) -> &'a str { - &post.content - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-18/src/lib.rs:here}} ``` Listing 17-18: Adding the `content` method to the `State` @@ -528,14 +360,7 @@ Let’s consider the first part of `main` in Listing 17-11: Filename: src/main.rs ```rust,ignore -# use blog::Post; - -fn main() { - let mut post = Post::new(); - - post.add_text("I ate a salad for lunch today"); - assert_eq!("", post.content()); -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-11/src/main.rs:here}} ``` We still enable the creation of new posts in the draft state using `Post::new` @@ -551,31 +376,7 @@ as well as methods on each: Filename: src/lib.rs ```rust -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); - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-19/src/lib.rs}} ``` Listing 17-19: A `Post` with a `content` method and a @@ -611,35 +412,7 @@ shown in Listing 17-20: Filename: src/lib.rs ```rust -# pub struct Post { -# content: String, -# } -# -# pub struct DraftPost { -# content: String, -# } -# -impl DraftPost { - // --snip-- - - 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, - } - } -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-20/src/lib.rs:here}} ``` Listing 17-20: A `PendingReviewPost` that gets created by @@ -669,19 +442,7 @@ The updated code in `main` is shown in Listing 17-21: Filename: src/main.rs ```rust,ignore -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()); -} +{{#rustdoc_include ../listings/ch17-oop/listing-17-21/src/main.rs}} ``` Listing 17-21: Modifications to `main` to use the new diff --git a/src/ch18-01-all-the-places-for-patterns.md b/src/ch18-01-all-the-places-for-patterns.md index d838532f..ec0389a8 100644 --- a/src/ch18-01-all-the-places-for-patterns.md +++ b/src/ch18-01-all-the-places-for-patterns.md @@ -53,25 +53,7 @@ input. Filename: src/main.rs ```rust -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"); - } -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-01/src/main.rs}} ``` Listing 18-1: Mixing `if let`, `else if`, `else if let`, @@ -108,15 +90,7 @@ Listing 18-2 shows a `while let` loop that uses a vector as a stack and prints the values in the vector in the opposite order in which they were pushed. ```rust -let mut stack = Vec::new(); - -stack.push(1); -stack.push(2); -stack.push(3); - -while let Some(top) = stack.pop() { - println!("{}", top); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-02/src/main.rs:here}} ``` Listing 18-2: Using a `while let` loop to print values @@ -139,11 +113,7 @@ Listing 18-3 demonstrates how to use a pattern in a `for` loop to destructure, or break apart, a tuple as part of the `for` loop. ```rust -let v = vec!['a', 'b', 'c']; - -for (index, value) in v.iter().enumerate() { - println!("{} is at index {}", value, index); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-03/src/main.rs:here}} ``` Listing 18-3: Using a pattern in a `for` loop to @@ -152,9 +122,7 @@ destructure a tuple The code in Listing 18-3 will print the following: ```text -a is at index 0 -b is at index 1 -c is at index 2 +{{#include ../listings/ch18-patterns-and-matching/listing-18-03/output.txt}} ``` We use the `enumerate` method to adapt an iterator to produce a value and that @@ -193,7 +161,7 @@ To see the pattern matching aspect of `let` more clearly, consider Listing 18-4, which uses a pattern with `let` to destructure a tuple. ```rust -let (x, y, z) = (1, 2, 3); +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-04/src/main.rs:here}} ``` Listing 18-4: Using a pattern to destructure a tuple and @@ -210,7 +178,7 @@ example, Listing 18-5 shows an attempt to destructure a tuple with three elements into two variables, which won’t work. ```rust,ignore,does_not_compile -let (x, y) = (1, 2, 3); +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-05/src/main.rs:here}} ``` Listing 18-5: Incorrectly constructing a pattern whose @@ -219,14 +187,7 @@ variables don’t match the number of elements in the tuple Attempting to compile this code results in this type error: ```text -error[E0308]: mismatched types - --> src/main.rs:2:9 - | -2 | let (x, y) = (1, 2, 3); - | ^^^^^^ expected a tuple with 3 elements, found one with 2 elements - | - = note: expected type `({integer}, {integer}, {integer})` - found type `(_, _)` +{{#include ../listings/ch18-patterns-and-matching/listing-18-05/output.txt}} ``` If we wanted to ignore one or more of the values in the tuple, we could use `_` @@ -243,9 +204,7 @@ declares a function named `foo` that takes one parameter named `x` of type `i32`, should by now look familiar. ```rust -fn foo(x: i32) { - // code goes here -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-06/src/main.rs:here}} ``` Listing 18-6: A function signature uses patterns in the @@ -258,14 +217,7 @@ as we pass it to a function. Filename: src/main.rs ```rust -fn print_coordinates(&(x, y): &(i32, i32)) { - println!("Current location: ({}, {})", x, y); -} - -fn main() { - let point = (3, 5); - print_coordinates(&point); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-07/src/main.rs}} ``` Listing 18-7: A function with parameters that destructure diff --git a/src/ch18-02-refutability.md b/src/ch18-02-refutability.md index 36fa17d4..029547f4 100644 --- a/src/ch18-02-refutability.md +++ b/src/ch18-02-refutability.md @@ -28,7 +28,7 @@ where Rust requires an irrefutable pattern and vice versa. Listing 18-8 shows a pattern. As you might expect, this code will not compile. ```rust,ignore,does_not_compile -let Some(x) = some_option_value; +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-08/src/main.rs:here}} ``` Listing 18-8: Attempting to use a refutable pattern with @@ -41,11 +41,7 @@ do with a `None` value. At compile time, Rust will complain that we’ve tried t use a refutable pattern where an irrefutable pattern is required: ```text -error[E0005]: refutable pattern in local binding: `None` not covered - --> - | -3 | let Some(x) = some_option_value; - | ^^^^^^^ pattern `None` not covered +{{#include ../listings/ch18-patterns-and-matching/listing-18-08/output.txt}} ``` Because we didn’t cover (and couldn’t cover!) every valid value with the @@ -58,10 +54,7 @@ will just skip the code in the curly brackets, giving it a way to continue validly. Listing 18-9 shows how to fix the code in Listing 18-8. ```rust -# let some_option_value: Option = None; -if let Some(x) = some_option_value { - println!("{}", x); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-09/src/main.rs:here}} ``` Listing 18-9: Using `if let` and a block with refutable @@ -72,10 +65,8 @@ cannot use an irrefutable pattern without receiving an error. If we give `if let` a pattern that will always match, such as `x`, as shown in Listing 18-10, the compiler will give a warning. -```rust,ignore -if let x = 5 { - println!("{}", x); -}; +```rust +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-10/src/main.rs:here}} ``` Listing 18-10: Attempting to use an irrefutable pattern @@ -85,15 +76,7 @@ Rust complains that it doesn’t make sense to use `if let` with an irrefutable pattern: ```text -warning: irrefutable if-let pattern - --> :2:5 - | -2 | / if let x = 5 { -3 | | println!("{}", x); -4 | | }; - | |_^ - | - = note: #[warn(irrefutable_let_patterns)] on by default +{{#include ../listings/ch18-patterns-and-matching/listing-18-10/output.txt}} ``` For this reason, match arms must use refutable patterns, except for the last diff --git a/src/ch18-03-pattern-syntax.md b/src/ch18-03-pattern-syntax.md index ccbcbd9a..d0b28184 100644 --- a/src/ch18-03-pattern-syntax.md +++ b/src/ch18-03-pattern-syntax.md @@ -10,14 +10,7 @@ As you saw in Chapter 6, you can match patterns against literals directly. The following code gives some examples: ```rust -let x = 1; - -match x { - 1 => println!("one"), - 2 => println!("two"), - 3 => println!("three"), - _ => println!("anything"), -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-01-literals/src/main.rs:here}} ``` This code prints `one` because the value in `x` is 1. This syntax is useful @@ -40,18 +33,7 @@ running this code or reading further. Filename: src/main.rs ```rust -fn main() { - 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); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-11/src/main.rs:here}} ``` Listing 18-11: A `match` expression with an arm that @@ -94,13 +76,7 @@ value of `x` matches either of the values in that arm, that arm’s code will run: ```rust -let x = 1; - -match x { - 1 | 2 => println!("one or two"), - 3 => println!("three"), - _ => println!("anything"), -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/src/main.rs:here}} ``` This code prints `one or two`. @@ -112,12 +88,7 @@ following code, when a pattern matches any of the values within the range, that arm will execute: ```rust -let x = 5; - -match x { - 1..=5 => println!("one through five"), - _ => println!("something else"), -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs:here}} ``` If `x` is 1, 2, 3, 4, or 5, the first arm will match. This syntax is more @@ -133,13 +104,7 @@ which Rust can tell if a range is empty or not are `char` and numeric values. Here is an example using ranges of `char` values: ```rust -let x = 'c'; - -match x { - 'a'..='j' => println!("early ASCII letter"), - 'k'..='z' => println!("late ASCII letter"), - _ => println!("something else"), -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/src/main.rs:here}} ``` Rust can tell that `c` is within the first pattern’s range and prints `early @@ -158,18 +123,7 @@ break apart using a pattern with a `let` statement. Filename: src/main.rs ```rust -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); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-12/src/main.rs}} ``` Listing 18-12: Destructuring a struct’s fields into @@ -192,18 +146,7 @@ in Listing 18-12, but the variables created in the `let` pattern are `x` and Filename: src/main.rs ```rust -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); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-13/src/main.rs}} ``` Listing 18-13: Destructuring struct fields using struct @@ -225,20 +168,7 @@ three cases: points that lie directly on the `x` axis (which is true when `y = Filename: src/main.rs ```rust -# struct Point { -# x: i32, -# y: i32, -# } -# -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), - } -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-14/src/main.rs:here}} ``` Listing 18-14: Destructuring and matching literal values @@ -268,38 +198,7 @@ a `match` with patterns that will destructure each inner value. Filename: src/main.rs ```rust -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 - ) - } - } -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-15/src/main.rs}} ``` Listing 18-15: Destructuring enum variants that hold @@ -333,41 +232,7 @@ For example, we can refactor the code in Listing 18-15 to support RGB and HSV colors in the `ChangeColor` message, as shown in Listing 18-16. ```rust -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 - ) - } - _ => () - } -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-16/src/main.rs}} ``` Listing 18-16: Matching on nested enums @@ -386,12 +251,7 @@ The following example shows a complicated destructure where we nest structs and tuples inside a tuple and destructure all the primitive values out: ```rust -# struct Point { -# x: i32, -# y: i32, -# } -# -let ((feet, inches), Point {x, y}) = ((3, 10), Point { x: 3, y: -10 }); +{{#rustdoc_include ../listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/src/main.rs:here}} ``` This code lets us break complex types into their component parts so we can use @@ -420,13 +280,7 @@ including function parameters, as shown in Listing 18-17. Filename: src/main.rs ```rust -fn foo(_: i32, y: i32) { - println!("This code only uses the y parameter: {}", y); -} - -fn main() { - foo(3, 4); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-17/src/main.rs}} ``` Listing 18-17: Using `_` in a function signature @@ -452,19 +306,7 @@ the user should not be allowed to overwrite an existing customization of a setting but can unset the setting and give it a value if it is currently unset. ```rust -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); +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-18/src/main.rs:here}} ``` Listing 18-18: Using an underscore within patterns that @@ -487,13 +329,7 @@ particular values. Listing 18-19 shows an example of ignoring the second and fourth values in a tuple of five items. ```rust -let numbers = (2, 4, 8, 16, 32); - -match numbers { - (first, _, third, _, fifth) => { - println!("Some numbers: {}, {}, {}", first, third, fifth) - }, -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-19/src/main.rs:here}} ``` Listing 18-19: Ignoring multiple parts of a tuple @@ -514,10 +350,7 @@ only get a warning about one of them. Filename: src/main.rs ```rust -fn main() { - let _x = 5; - let y = 10; -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-20/src/main.rs}} ``` Listing 18-20: Starting a variable name with an @@ -532,13 +365,7 @@ variable, whereas `_` doesn’t bind at all. To show a case where this distinction matters, Listing 18-21 will provide us with an error. ```rust,ignore,does_not_compile -let s = Some(String::from("Hello!")); - -if let Some(_s) = s { - println!("found a string"); -} - -println!("{:?}", s); +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-21/src/main.rs:here}} ``` Listing 18-21: An unused variable starting with an @@ -550,13 +377,7 @@ doesn’t ever bind to the value. Listing 18-22 will compile without any errors because `s` doesn’t get moved into `_`. ```rust -let s = Some(String::from("Hello!")); - -if let Some(_) = s { - println!("found a string"); -} - -println!("{:?}", s); +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-22/src/main.rs:here}} ``` Listing 18-22: Using an underscore does not bind the @@ -575,17 +396,7 @@ explicitly matched in the rest of the pattern. In Listing 18-23, we have a the values in the `y` and `z` fields. ```rust -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), -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-23/src/main.rs:here}} ``` Listing 18-23: Ignoring all fields of a `Point` except @@ -602,15 +413,7 @@ shows how to use `..` with a tuple. Filename: src/main.rs ```rust -fn main() { - let numbers = (2, 4, 8, 16, 32); - - match numbers { - (first, .., last) => { - println!("Some numbers: {}, {}", first, last); - }, - } -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-24/src/main.rs}} ``` Listing 18-24: Matching only the first and last values in @@ -627,15 +430,7 @@ compile. Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - let numbers = (2, 4, 8, 16, 32); - - match numbers { - (.., second, ..) => { - println!("Some numbers: {}", second) - }, - } -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-25/src/main.rs}} ``` Listing 18-25: An attempt to use `..` in an ambiguous @@ -644,11 +439,7 @@ way When we compile this example, we get this error: ```text -error: `..` can only be used once per tuple or tuple struct pattern - --> src/main.rs:5:22 - | -5 | (.., second, ..) => { - | ^^ +{{#include ../listings/ch18-patterns-and-matching/listing-18-25/output.txt}} ``` It’s impossible for Rust to determine how many values in the tuple to ignore @@ -671,13 +462,7 @@ The condition can use variables created in the pattern. Listing 18-26 shows a guard of `if x < 5`. ```rust -let num = Some(4); - -match num { - Some(x) if x < 5 => println!("less than five: {}", x), - Some(x) => println!("{}", x), - None => (), -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-26/src/main.rs:here}} ``` Listing 18-26: Adding a match guard to a pattern @@ -705,18 +490,7 @@ problem. Filename: src/main.rs ```rust -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); -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-27/src/main.rs}} ``` Listing 18-27: Using a match guard to test for equality @@ -742,13 +516,7 @@ to `4`, `5`, *and* `6`, even though it might look like `if y` only applies to `6`. ```rust -let x = 4; -let y = false; - -match x { - 4 | 5 | 6 if y => println!("yes"), - _ => println!("no"), -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-28/src/main.rs:here}} ``` Listing 18-28: Combining multiple patterns with a match @@ -789,23 +557,7 @@ name this variable `id`, the same as the field, but for this example we’ll use a different name. ```rust -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) - }, -} +{{#rustdoc_include ../listings/ch18-patterns-and-matching/listing-18-29/src/main.rs:here}} ``` Listing 18-29: Using `@` to bind to a value in a pattern diff --git a/src/ch19-01-unsafe-rust.md b/src/ch19-01-unsafe-rust.md index c7956e86..7f6d2521 100644 --- a/src/ch19-01-unsafe-rust.md +++ b/src/ch19-01-unsafe-rust.md @@ -91,10 +91,7 @@ Listing 19-1 shows how to create an immutable and a mutable raw pointer from references. ```rust -let mut num = 5; - -let r1 = &num as *const i32; -let r2 = &mut num as *mut i32; +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-01/src/main.rs:here}} ``` Listing 19-1: Creating raw pointers from references @@ -117,8 +114,7 @@ is no memory access, or the program might error with a segmentation fault. Usually, there is no good reason to write code like this, but it is possible. ```rust -let address = 0x012345usize; -let r = address as *const i32; +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-02/src/main.rs:here}} ``` Listing 19-2: Creating a raw pointer to an arbitrary @@ -129,15 +125,7 @@ raw pointers and read the data being pointed to. In Listing 19-3, we use the dereference operator `*` on a raw pointer that requires an `unsafe` block. ```rust,unsafe -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); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-03/src/main.rs:here}} ``` Listing 19-3: Dereferencing raw pointers within an @@ -178,22 +166,14 @@ Here is an unsafe function named `dangerous` that doesn’t do anything in its body: ```rust,unsafe -unsafe fn dangerous() {} - -unsafe { - dangerous(); -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-01-unsafe-fn/src/main.rs:here}} ``` We must call the `dangerous` function within a separate `unsafe` block. If we try to call `dangerous` without the `unsafe` block, we’ll get an error: ```text -error[E0133]: call to unsafe function requires unsafe function or block - --> - | -4 | dangerous(); - | ^^^^^^^^^^^ call to unsafe function +{{#include ../listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt}} ``` By inserting the `unsafe` block around our call to `dangerous`, we’re asserting @@ -216,14 +196,7 @@ slice and makes it two by splitting the slice at the index given as an argument. Listing 19-4 shows how to use `split_at_mut`. ```rust -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]); +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-04/src/main.rs:here}} ``` Listing 19-4: Using the safe `split_at_mut` @@ -235,14 +208,7 @@ implement `split_at_mut` as a function rather than a method and only for slices of `i32` values rather than for a generic type `T`. ```rust,ignore,does_not_compile -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..]) -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-05/src/main.rs:here}} ``` Listing 19-5: An attempted implementation of @@ -261,15 +227,7 @@ slice. When we try to compile the code in Listing 19-5, we’ll get an error. ```text -error[E0499]: cannot borrow `*slice` as mutable more than once at a time - --> - | -6 | (&mut slice[..mid], - | ----- first mutable borrow occurs here -7 | &mut slice[mid..]) - | ^^^^^ second mutable borrow occurs here -8 | } - | - first borrow ends here +{{#include ../listings/ch19-advanced-features/listing-19-05/output.txt}} ``` Rust’s borrow checker can’t understand that we’re borrowing different parts of @@ -282,19 +240,7 @@ Listing 19-6 shows how to use an `unsafe` block, a raw pointer, and some calls to unsafe functions to make the implementation of `split_at_mut` work. ```rust,unsafe -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.offset(mid as isize), len - mid)) - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-06/src/main.rs:here}} ``` Listing 19-6: Using unsafe code in the implementation of @@ -336,14 +282,7 @@ likely crash when the slice is used. This code takes an arbitrary memory location and creates a slice 10,000 items long. ```rust,unsafe -use std::slice; - -let address = 0x01234usize; -let r = address as *mut i32; - -let slice: &[i32] = unsafe { - slice::from_raw_parts_mut(r, 10000) -}; +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-07/src/main.rs:here}} ``` Listing 19-7: Creating a slice from an arbitrary memory @@ -370,15 +309,7 @@ responsibility falls on the programmer to ensure safety. Filename: src/main.rs ```rust,unsafe -extern "C" { - fn abs(input: i32) -> i32; -} - -fn main() { - unsafe { - println!("Absolute value of -3 according to C: {}", abs(-3)); - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-08/src/main.rs}} ``` Listing 19-8: Declaring and calling an `extern` function @@ -428,11 +359,7 @@ value. Filename: src/main.rs ```rust -static HELLO_WORLD: &str = "Hello, world!"; - -fn main() { - println!("name is: {}", HELLO_WORLD); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-09/src/main.rs}} ``` Listing 19-9: Defining and using an immutable static @@ -461,21 +388,7 @@ static variable named `COUNTER`. Filename: src/main.rs ```rust,unsafe -static mut COUNTER: u32 = 0; - -fn add_to_count(inc: u32) { - unsafe { - COUNTER += inc; - } -} - -fn main() { - add_to_count(3); - - unsafe { - println!("COUNTER: {}", COUNTER); - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-10/src/main.rs}} ``` Listing 19-10: Reading from or writing to a mutable @@ -502,13 +415,7 @@ compiler can’t verify. We can declare that a trait is `unsafe` by adding the `unsafe` too, as shown in Listing 19-11. ```rust,unsafe -unsafe trait Foo { - // methods go here -} - -unsafe impl Foo for i32 { - // method implementations go here -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-11/src/main.rs}} ``` Listing 19-11: Defining and implementing an unsafe diff --git a/src/ch19-03-advanced-traits.md b/src/ch19-03-advanced-traits.md index c959f231..9c334286 100644 --- a/src/ch19-03-advanced-traits.md +++ b/src/ch19-03-advanced-traits.md @@ -28,11 +28,7 @@ Chapter 13, we mentioned that the definition of the `Iterator` trait is as shown in Listing 19-12. ```rust -pub trait Iterator { - type Item; - - fn next(&mut self) -> Option; -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-12/src/lib.rs}} ``` Listing 19-12: The definition of the `Iterator` trait @@ -54,20 +50,14 @@ Listing 13-21, we specified that the `Item` type was `u32`: Filename: src/lib.rs ```rust,ignore -impl Iterator for Counter { - type Item = u32; - - fn next(&mut self) -> Option { - // --snip-- +{{#rustdoc_include ../listings/ch19-advanced-features/listing-13-21-reproduced/src/lib.rs:ch19}} ``` This syntax seems comparable to that of generics. So why not just define the `Iterator` trait with generics, as shown in Listing 19-13? ```rust -pub trait Iterator { - fn next(&mut self) -> Option; -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-13/src/lib.rs}} ``` Listing 19-13: A hypothetical definition of the @@ -111,29 +101,7 @@ struct: Filename: src/main.rs ```rust -use std::ops::Add; - -#[derive(Debug, 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 }); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-14/src/main.rs}} ``` Listing 19-14: Implementing the `Add` trait to overload @@ -176,18 +144,7 @@ implementation of `Add` do the conversion correctly. We can implement `Add` for Filename: src/lib.rs ```rust -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)) - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-15/src/lib.rs}} ``` Listing 19-15: Implementing the `Add` trait on @@ -229,33 +186,7 @@ on it. Each `fly` method does something different. Filename: src/main.rs ```rust -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*"); - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-16/src/main.rs:here}} ``` Listing 19-16: Two traits are defined to have a `fly` @@ -268,38 +199,7 @@ the method that is directly implemented on the type, as shown in Listing 19-17. Filename: src/main.rs ```rust -# 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*"); -# } -# } -# -fn main() { - let person = Human; - person.fly(); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-17/src/main.rs:here}} ``` Listing 19-17: Calling `fly` on an instance of @@ -315,40 +215,7 @@ Listing 19-18 demonstrates this syntax. Filename: src/main.rs ```rust -# 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*"); -# } -# } -# -fn main() { - let person = Human; - Pilot::fly(&person); - Wizard::fly(&person); - person.fly(); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-18/src/main.rs:here}} ``` Listing 19-18: Specifying which trait’s `fly` method we @@ -363,9 +230,7 @@ disambiguate. Running this code prints the following: ```text -This is your captain speaking. -Up! -*waving arms furiously* +{{#include ../listings/ch19-advanced-features/listing-19-18/output.txt}} ``` Because the `fly` method takes a `self` parameter, if we had two *types* that @@ -382,27 +247,7 @@ associated function `baby_name` defined on `Dog` directly. Filename: src/main.rs ```rust -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()); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-19/src/main.rs}} ``` Listing 19-19: A trait with an associated function and a @@ -420,7 +265,7 @@ In `main`, we call the `Dog::baby_name` function, which calls the associated function defined on `Dog` directly. This code prints the following: ```text -A baby dog is called a Spot +{{#include ../listings/ch19-advanced-features/listing-19-19/output.txt}} ``` This output isn’t what we wanted. We want to call the `baby_name` function that @@ -432,9 +277,7 @@ Listing 19-20, we’ll get a compilation error. Filename: src/main.rs ```rust,ignore,does_not_compile -fn main() { - println!("A baby dog is called a {}", Animal::baby_name()); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-20/src/main.rs:here}} ``` Listing 19-20: Attempting to call the `baby_name` @@ -446,13 +289,7 @@ thus doesn’t have a `self` parameter, Rust can’t figure out which implementation of `Animal::baby_name` we want. We’ll get this compiler error: ```text -error[E0283]: type annotations required: cannot resolve `_: Animal` - --> src/main.rs:20:43 - | -20 | println!("A baby dog is called a {}", Animal::baby_name()); - | ^^^^^^^^^^^^^^^^^ - | - = note: required by `Animal::baby_name` +{{#include ../listings/ch19-advanced-features/listing-19-20/output.txt}} ``` To disambiguate and tell Rust that we want to use the implementation of @@ -462,27 +299,7 @@ demonstrates how to use fully qualified syntax. Filename: src/main.rs ```rust -# 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 {}", ::baby_name()); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-21/src/main.rs:here}} ``` Listing 19-21: Using fully qualified syntax to specify @@ -495,7 +312,7 @@ implemented on `Dog` by saying that we want to treat the `Dog` type as an `Animal` for this function call. This code will now print what we want: ```text -A baby dog is called a puppy +{{#include ../listings/ch19-advanced-features/listing-19-21/output.txt}} ``` In general, fully qualified syntax is defined as follows: @@ -542,19 +359,7 @@ the trait. Listing 19-22 shows an implementation of the `OutlinePrint` trait. Filename: src/main.rs ```rust -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)); - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-22/src/main.rs:here}} ``` Listing 19-22: Implementing the `OutlinePrint` trait that @@ -572,27 +377,14 @@ doesn’t implement `Display`, such as the `Point` struct: Filename: src/main.rs -```rust -# trait OutlinePrint {} -struct Point { - x: i32, - y: i32, -} - -impl OutlinePrint for Point {} +```rust,ignore,does_not_compile +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs:here}} ``` We get an error saying that `Display` is required but not implemented: ```text -error[E0277]: the trait bound `Point: std::fmt::Display` is not satisfied - --> src/main.rs:20:6 - | -20 | impl OutlinePrint for Point {} - | ^^^^^^^^^^^^ `Point` cannot be formatted with the default formatter; -try using `:?` instead if you are using a format string - | - = help: the trait `std::fmt::Display` is not implemented for `Point` +{{#include ../listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt}} ``` To fix this, we implement `Display` on `Point` and satisfy the constraint that @@ -601,18 +393,7 @@ To fix this, we implement `Display` on `Point` and satisfy the constraint that Filename: src/main.rs ```rust -# struct Point { -# x: i32, -# y: i32, -# } -# -use std::fmt; - -impl fmt::Display for Point { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "({}, {})", self.x, self.y) - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs:here}} ``` Then implementing the `OutlinePrint` trait on `Point` will compile @@ -644,20 +425,7 @@ that holds an instance of `Vec`; then we can implement `Display` on Filename: src/main.rs ```rust -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); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-23/src/main.rs}} ``` Listing 19-23: Creating a `Wrapper` type around diff --git a/src/ch19-04-advanced-types.md b/src/ch19-04-advanced-types.md index e1e46b1e..f20d6b4d 100644 --- a/src/ch19-04-advanced-types.md +++ b/src/ch19-04-advanced-types.md @@ -43,7 +43,7 @@ alias* to give an existing type another name. For this we use the `type` keyword. For example, we can create the alias `Kilometers` to `i32` like so: ```rust -type Kilometers = i32; +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-04-kilometers-alias/src/main.rs:here}} ``` Now, the alias `Kilometers` is a *synonym* for `i32`; unlike the `Millimeters` @@ -52,12 +52,7 @@ new type. Values that have the type `Kilometers` will be treated the same as values of type `i32`: ```rust -type Kilometers = i32; - -let x: i32 = 5; -let y: Kilometers = 5; - -println!("x + y = {}", x + y); +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-04-kilometers-alias/src/main.rs:there}} ``` Because `Kilometers` and `i32` are the same type, we can add values of both @@ -77,16 +72,7 @@ over the code can be tiresome and error prone. Imagine having a project full of code like that in Listing 19-24. ```rust -let f: Box = Box::new(|| println!("hi")); - -fn takes_long_type(f: Box) { - // --snip-- -} - -fn returns_long_type() -> Box { - // --snip-- -# Box::new(|| ()) -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-24/src/main.rs:here}} ``` Listing 19-24: Using a long type in many places @@ -96,18 +82,7 @@ Listing 19-25, we’ve introduced an alias named `Thunk` for the verbose type an can replace all uses of the type with the shorter alias `Thunk`. ```rust -type Thunk = Box; - -let f: Thunk = Box::new(|| println!("hi")); - -fn takes_long_type(f: Thunk) { - // --snip-- -} - -fn returns_long_type() -> Thunk { - // --snip-- -# Box::new(|| ()) -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-25/src/main.rs:here}} ``` Listing 19-25: Introducing a type alias `Thunk` to reduce @@ -127,23 +102,14 @@ possible I/O errors. Many of the functions in `std::io` will be returning the `Write` trait: ```rust -use std::io::Error; -use std::fmt; - -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>; -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-05-write-trait/src/lib.rs}} ``` The `Result<..., Error>` is repeated a lot. As such, `std::io` has this type of alias declaration: ```rust -type Result = std::result::Result; +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-06-result-alias/src/lib.rs:here}} ``` Because this declaration is in the `std::io` module, we can use the fully @@ -151,14 +117,8 @@ qualified alias `std::io::Result`—that is, a `Result` with the `E` filled in as `std::io::Error`. The `Write` trait function signatures end up looking like this: -```rust,ignore -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: Arguments) -> Result<()>; -} +```rust +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-06-result-alias/src/lib.rs:there}} ``` The type alias helps in two ways: it makes code easier to write *and* it gives @@ -173,10 +133,8 @@ Rust has a special type named `!` that’s known in type theory lingo as the because it stands in the place of the return type when a function will never return. Here is an example: -```rust,ignore -fn bar() -> ! { - // --snip-- -} +```rust +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-07-never-type/src/lib.rs:here}} ``` This code is read as “the function `bar` returns never.” Functions that return @@ -186,15 +144,8 @@ so `bar` can never possibly return. But what use is a type you can never create values for? Recall the code from Listing 2-5; we’ve reproduced part of it here in Listing 19-26. -```rust -# let guess = "3"; -# loop { -let guess: u32 = match guess.trim().parse() { - Ok(num) => num, - Err(_) => continue, -}; -# break; -# } +```rust,ignore +{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs:ch19}} ``` Listing 19-26: A `match` with an arm that ends in @@ -206,10 +157,7 @@ At the time, we skipped over some details in this code. In Chapter 6 in [“The for example, the following code doesn’t work: ```rust,ignore,does_not_compile -let guess = match guess.trim().parse() { - Ok(_) => 5, - Err(_) => "hello", -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs:here}} ``` The type of `guess` in this code would have to be an integer *and* a string, @@ -233,14 +181,7 @@ function that we call on `Option` values to produce a value or panic? Here is its definition: ```rust,ignore -impl Option { - pub fn unwrap(self) -> T { - match self { - Some(val) => val, - None => panic!("called `Option::unwrap()` on a `None` value"), - } - } -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs:here}} ``` In this code, the same thing happens as in the `match` in Listing 19-26: Rust @@ -252,11 +193,7 @@ returning a value from `unwrap`, so this code is valid. One final expression that has the type `!` is a `loop`: ```rust,ignore -print!("forever "); - -loop { - print!("and ever "); -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-10-loop-returns-never/src/main.rs:here}} ``` Here, the loop never ends, so `!` is the value of the expression. However, this @@ -278,8 +215,7 @@ we can’t create a variable of type `str`, nor can we take an argument of type `str`. Consider the following code, which does not work: ```rust,ignore,does_not_compile -let s1: str = "Hello there!"; -let s2: str = "How's it going?"; +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs:here}} ``` Rust needs to know how much memory to allocate for any value of a particular @@ -321,17 +257,13 @@ In addition, Rust implicitly adds a bound on `Sized` to every generic function. That is, a generic function definition like this: ```rust,ignore -fn generic(t: T) { - // --snip-- -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-12-generic-fn-definition/src/lib.rs}} ``` is actually treated as though we had written this: ```rust,ignore -fn generic(t: T) { - // --snip-- -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/src/lib.rs}} ``` By default, generic functions will work only on types that have a known size at @@ -339,9 +271,7 @@ compile time. However, you can use the following special syntax to relax this restriction: ```rust,ignore -fn generic(t: &T) { - // --snip-- -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/src/lib.rs}} ``` A trait bound on `?Sized` is the opposite of a trait bound on `Sized`: we would diff --git a/src/ch19-05-advanced-functions-and-closures.md b/src/ch19-05-advanced-functions-and-closures.md index 2955114a..ac452265 100644 --- a/src/ch19-05-advanced-functions-and-closures.md +++ b/src/ch19-05-advanced-functions-and-closures.md @@ -17,19 +17,7 @@ similar to that of closures, as shown in Listing 19-27. Filename: src/main.rs ```rust -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); -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-27/src/main.rs}} ``` Listing 19-27: Using the `fn` type to accept a function @@ -59,22 +47,14 @@ function, let’s look at a use of `map`. To use the `map` function to turn a vector of numbers into a vector of strings, we could use a closure, like this: ```rust -let list_of_numbers = vec![1, 2, 3]; -let list_of_strings: Vec = list_of_numbers - .iter() - .map(|i| i.to_string()) - .collect(); +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-15-map-closure/src/main.rs:here}} ``` Or we could name a function as the argument to `map` instead of the closure, like this: ```rust -let list_of_numbers = vec![1, 2, 3]; -let list_of_strings: Vec = list_of_numbers - .iter() - .map(ToString::to_string) - .collect(); +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-16-map-function/src/main.rs:here}} ``` Note that we must use the fully qualified syntax that we talked about earlier @@ -92,15 +72,7 @@ implement the closure traits, which means we can specify the initializer functions as arguments for methods that take closures, like so: ```rust -enum Status { - Value(u32), - Stop, -} - -let list_of_statuses: Vec = - (0u32..20) - .map(Status::Value) - .collect(); +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs:here}} ``` Here we create `Status::Value` instances using each `u32` value in the range @@ -120,25 +92,13 @@ pointer `fn` as a return type, for example. The following code tries to return a closure directly, but it won’t compile: ```rust,ignore,does_not_compile -fn returns_closure() -> Fn(i32) -> i32 { - |x| x + 1 -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs}} ``` The compiler error is as follows: ```text -error[E0277]: the trait bound `std::ops::Fn(i32) -> i32 + 'static: -std::marker::Sized` is not satisfied - --> - | -1 | fn returns_closure() -> Fn(i32) -> i32 { - | ^^^^^^^^^^^^^^ `std::ops::Fn(i32) -> i32 + 'static` - does not have a constant size known at compile-time - | - = help: the trait `std::marker::Sized` is not implemented for - `std::ops::Fn(i32) -> i32 + 'static` - = note: the return type of a function must have a statically known size +{{#include ../listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt}} ``` The error references the `Sized` trait again! Rust doesn’t know how much space @@ -146,9 +106,7 @@ it will need to store the closure. We saw a solution to this problem earlier. We can use a trait object: ```rust -fn returns_closure() -> Box i32> { - Box::new(|x| x + 1) -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/src/lib.rs}} ``` This code will compile just fine. For more about trait objects, refer to the diff --git a/src/ch19-06-macros.md b/src/ch19-06-macros.md index fbb22469..7c4661c5 100644 --- a/src/ch19-06-macros.md +++ b/src/ch19-06-macros.md @@ -78,18 +78,7 @@ Listing 19-28 shows a slightly simplified definition of the `vec!` macro. Filename: src/lib.rs ```rust -#[macro_export] -macro_rules! vec { - ( $( $x:expr ),* ) => { - { - let mut temp_vec = Vec::new(); - $( - temp_vec.push($x); - )* - temp_vec - } - }; -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-28/src/lib.rs}} ``` Listing 19-28: A simplified version of the `vec!` macro @@ -221,16 +210,8 @@ programmer to write code like Listing 19-30 using our crate. Filename: src/main.rs -```rust,ignore -use hello_macro::HelloMacro; -use hello_macro_derive::HelloMacro; - -#[derive(HelloMacro)] -struct Pancakes; - -fn main() { - Pancakes::hello_macro(); -} +```rust,ignore,does_not_compile +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-30/src/main.rs}} ``` Listing 19-30: The code a user of our crate will be able @@ -248,28 +229,14 @@ Next, we’ll define the `HelloMacro` trait and its associated function: Filename: src/lib.rs ```rust -pub trait HelloMacro { - fn hello_macro(); -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs}} ``` We have a trait and its function. At this point, our crate user could implement the trait to achieve the desired functionality, like so: ```rust,ignore -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(); -} +{{#rustdoc_include ../listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs}} ``` However, they would need to write the implementation block for each type they @@ -311,12 +278,7 @@ in a moment, so we need to add them as dependencies. Add the following to the Filename: hello_macro_derive/Cargo.toml ```toml -[lib] -proc-macro = true - -[dependencies] -syn = "0.14.4" -quote = "0.6.3" +{{#include ../listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/Cargo.toml:7:12}} ``` To start defining the procedural macro, place the code in Listing 19-31 into @@ -332,22 +294,8 @@ https://github.com/rust-lang/rust/pull/54658 https://github.com/rust-lang/rust/issues/55599 --> -```rust,ignore -extern crate proc_macro; - -use crate::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) -} +```rust,ignore,does_not_compile +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs}} ``` Listing 19-31: Code that most procedural macro crates @@ -441,17 +389,7 @@ into a `DeriveInput` instance, let’s generate the code that implements the Filename: hello_macro_derive/src/lib.rs ```rust,ignore -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() -} +{{#rustdoc_include ../listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs:here}} ``` Listing 19-33: Implementing the `HelloMacro` trait using @@ -502,9 +440,7 @@ crate’s *Cargo.toml*. If you’re publishing your versions of `hello_macro` an dependencies; if not, you can specify them as `path` dependencies as follows: ```toml -[dependencies] -hello_macro = { path = "../hello_macro" } -hello_macro_derive = { path = "../hello_macro/hello_macro_derive" } +{{#include ../listings/ch19-advanced-features/no-listing-21-pancakes/pancakes/Cargo.toml:7:9}} ``` Put the code in Listing 19-30 into *src/main.rs*, and run `cargo run`: it diff --git a/src/ch20-01-single-threaded.md b/src/ch20-01-single-threaded.md index a2617c00..b46d39f6 100644 --- a/src/ch20-01-single-threaded.md +++ b/src/ch20-01-single-threaded.md @@ -38,17 +38,7 @@ an incoming stream, it will print `Connection established!`. Filename: src/main.rs ```rust,no_run -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!"); - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-01/src/main.rs}} ``` Listing 20-1: Listening for incoming streams and printing @@ -140,27 +130,7 @@ look like Listing 20-2. Filename: src/main.rs ```rust,no_run -use std::io::prelude::*; -use std::net::TcpStream; -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(); - - handle_connection(stream); - } -} - -fn handle_connection(mut stream: TcpStream) { - let mut buffer = [0; 512]; - - stream.read(&mut buffer).unwrap(); - - println!("Request: {}", String::from_utf8_lossy(&buffer[..])); -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-02/src/main.rs}} ``` Listing 20-2: Reading from the `TcpStream` and printing @@ -200,7 +170,7 @@ program’s output in the terminal will now look similar to this: ```text $ cargo run Compiling hello v0.1.0 (file:///projects/hello) - Finished dev [unoptimized + debuginfo] target(s) in 0.42 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.42s Running `target/debug/hello` Request: GET / HTTP/1.1 Host: 127.0.0.1:7878 @@ -295,19 +265,8 @@ Listing 20-3. Filename: src/main.rs -```rust -# use std::io::prelude::*; -# use std::net::TcpStream; -fn handle_connection(mut stream: TcpStream) { - let mut buffer = [0; 512]; - - 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(); -} +```rust,no_run +{{#rustdoc_include ../listings/ch20-web-server/listing-20-03/src/main.rs:here}} ``` Listing 20-3: Writing a tiny successful HTTP response to @@ -340,17 +299,7 @@ possibility. Filename: hello.html ```html - - - - - Hello! - - -

Hello!

-

Hi from Rust

- - +{{#include ../listings/ch20-web-server/listing-20-04/hello.html}} ``` Listing 20-4: A sample HTML file to return in a @@ -363,23 +312,8 @@ and send it. Filename: src/main.rs -```rust -# use std::io::prelude::*; -# use std::net::TcpStream; -use std::fs; -// --snip-- - -fn handle_connection(mut stream: TcpStream) { - let mut buffer = [0; 512]; - stream.read(&mut buffer).unwrap(); - - let contents = fs::read_to_string("hello.html").unwrap(); - - let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents); - - stream.write(response.as_bytes()).unwrap(); - stream.flush().unwrap(); -} +```rust,no_run +{{#rustdoc_include ../listings/ch20-web-server/listing-20-05/src/main.rs:here}} ``` Listing 20-5: Sending the contents of *hello.html* as the @@ -415,29 +349,8 @@ received against what we know a request for */* looks like and adds `if` and Filename: src/main.rs -```rust -# use std::io::prelude::*; -# use std::net::TcpStream; -# use std::fs; -// --snip-- - -fn handle_connection(mut stream: TcpStream) { - let mut buffer = [0; 512]; - 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\n\r\n{}", contents); - - stream.write(response.as_bytes()).unwrap(); - stream.flush().unwrap(); - } else { - // some other request - } -} +```rust,no_run +{{#rustdoc_include ../listings/ch20-web-server/listing-20-06/src/main.rs:here}} ``` Listing 20-6: Matching the request and handling requests @@ -467,24 +380,8 @@ indicating the response to the end user. Filename: src/main.rs -```rust -# use std::io::prelude::*; -# use std::net::TcpStream; -# use std::fs; -# fn handle_connection(mut stream: TcpStream) { -# if true { -// --snip-- - -} else { - let status_line = "HTTP/1.1 404 NOT FOUND\r\n\r\n"; - let contents = fs::read_to_string("404.html").unwrap(); - - let response = format!("{}{}", status_line, contents); - - stream.write(response.as_bytes()).unwrap(); - stream.flush().unwrap(); -} -# } +```rust,no_run +{{#rustdoc_include ../listings/ch20-web-server/listing-20-07/src/main.rs:here}} ``` Listing 20-7: Responding with status code 404 and an @@ -499,17 +396,7 @@ any HTML you want or use the example HTML in Listing 20-8. Filename: 404.html ```html - - - - - Hello! - - -

Oops!

-

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

- - +{{#include ../listings/ch20-web-server/listing-20-08/404.html}} ``` Listing 20-8: Sample content for the page to send back @@ -532,32 +419,8 @@ the large `if` and `else` blocks. Filename: src/main.rs -```rust -# use std::io::prelude::*; -# use std::net::TcpStream; -# use std::fs; -// --snip-- - -fn handle_connection(mut stream: TcpStream) { -# let mut buffer = [0; 512]; -# stream.read(&mut buffer).unwrap(); -# -# let get = b"GET / HTTP/1.1\r\n"; - // --snip-- - - let (status_line, filename) = if buffer.starts_with(get) { - ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") - } else { - ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") - }; - - let contents = fs::read_to_string(filename).unwrap(); - - let response = format!("{}{}", status_line, contents); - - stream.write(response.as_bytes()).unwrap(); - stream.flush().unwrap(); -} +```rust,no_run +{{#rustdoc_include ../listings/ch20-web-server/listing-20-09/src/main.rs:here}} ``` Listing 20-9: Refactoring the `if` and `else` blocks to diff --git a/src/ch20-02-multithreaded.md b/src/ch20-02-multithreaded.md index 40d3a172..89182bff 100644 --- a/src/ch20-02-multithreaded.md +++ b/src/ch20-02-multithreaded.md @@ -17,33 +17,8 @@ for 5 seconds before responding. Filename: src/main.rs -```rust -use std::thread; -use std::time::Duration; -# use std::io::prelude::*; -# use std::net::TcpStream; -# use std::fs::File; -// --snip-- - -fn handle_connection(mut stream: TcpStream) { -# let mut buffer = [0; 512]; -# stream.read(&mut buffer).unwrap(); - // --snip-- - - 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\r\n\r\n", "hello.html") - } else if buffer.starts_with(sleep) { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") - } else { - ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") - }; - - // --snip-- -} +```rust,no_run +{{#rustdoc_include ../listings/ch20-web-server/listing-20-10/src/main.rs:here}} ``` Listing 20-10: Simulating a slow request by recognizing @@ -124,23 +99,7 @@ new thread to handle each stream within the `for` loop. Filename: src/main.rs ```rust,no_run -# use std::thread; -# 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(); - - thread::spawn(|| { - handle_connection(stream); - }); - } -} -# fn handle_connection(mut stream: TcpStream) {} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-11/src/main.rs:here}} ``` Listing 20-11: Spawning a new thread for each @@ -162,31 +121,8 @@ struct we want to use instead of `thread::spawn`. Filename: src/main.rs -```rust,no_run -# use std::thread; -# use std::io::prelude::*; -# use std::net::TcpListener; -# use std::net::TcpStream; -# struct ThreadPool; -# impl ThreadPool { -# fn new(size: u32) -> ThreadPool { ThreadPool } -# fn execute(&self, f: F) -# where F: FnOnce() + Send + 'static {} -# } -# -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) {} +```rust,ignore,does_not_compile +{{#rustdoc_include ../listings/ch20-web-server/listing-20-12/src/main.rs:here}} ``` Listing 20-12: Our ideal `ThreadPool` interface @@ -205,16 +141,7 @@ compiler errors from `cargo check` to drive our development. Here is the first error we get: ```text -$ cargo check - Compiling hello v0.1.0 (file:///projects/hello) -error[E0433]: failed to resolve. Use of undeclared type or module `ThreadPool` - --> src\main.rs:10:16 - | -10 | let pool = ThreadPool::new(4); - | ^^^^^^^^^^^^^^^ Use of undeclared type or module - `ThreadPool` - -error: aborting due to previous error +{{#include ../listings/ch20-web-server/listing-20-12/output.txt}} ``` Great! This error tells us we need a `ThreadPool` type or module, so we’ll @@ -231,7 +158,7 @@ definition of a `ThreadPool` struct that we can have for now: Filename: src/lib.rs ```rust -pub struct ThreadPool; +{{#rustdoc_include ../listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/lib.rs}} ``` Then create a new directory, *src/bin*, and move the binary crate rooted in @@ -244,22 +171,14 @@ following code to the top of *src/bin/main.rs*: Filename: src/bin/main.rs ```rust,ignore -use hello::ThreadPool; +{{#rustdoc_include ../listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/bin/main.rs:here}} ``` This code still won’t work, but let’s check it again to get the next error that we need to address: ```text -$ cargo check - Compiling hello v0.1.0 (file:///projects/hello) -error[E0599]: no function or associated item named `new` found for type -`hello::ThreadPool` in the current scope - --> src/bin/main.rs:13:16 - | -13 | let pool = ThreadPool::new(4); - | ^^^^^^^^^^^^^^^ function or associated item not found in - `hello::ThreadPool` +{{#include ../listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt}} ``` This error indicates that next we need to create an associated function named @@ -271,13 +190,7 @@ characteristics: Filename: src/lib.rs ```rust -pub struct ThreadPool; - -impl ThreadPool { - pub fn new(size: usize) -> ThreadPool { - ThreadPool - } -} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs:here}} ``` We chose `usize` as the type of the `size` parameter, because we know that a @@ -289,27 +202,11 @@ ignore --> section of Chapter 3. Let’s check the code again: ```text -$ cargo check - Compiling hello v0.1.0 (file:///projects/hello) -warning: unused variable: `size` - --> src/lib.rs:4:16 - | -4 | pub fn new(size: usize) -> ThreadPool { - | ^^^^ - | - = note: #[warn(unused_variables)] on by default - = note: to avoid this warning, consider using `_size` instead - -error[E0599]: no method named `execute` found for type `hello::ThreadPool` in the current scope - --> src/bin/main.rs:18:14 - | -18 | pool.execute(|| { - | ^^^^^^^ +{{#include ../listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt}} ``` -Now we get a warning and an error. Ignoring the warning for a moment, the error -occurs because we don’t have an `execute` method on `ThreadPool`. Recall from -the [“Creating a Similar Interface for a Finite Number of +Now the error occurs because we don’t have an `execute` method on `ThreadPool`. +Recall from the [“Creating a Similar Interface for a Finite Number of Threads”](#creating-a-similar-interface-for-a-finite-number-of-threads) section that we decided our thread pool should have an interface similar to `thread::spawn`. In addition, we’ll implement the `execute` function @@ -350,17 +247,7 @@ the thread will take to execute. Let’s create an `execute` method on Filename: src/lib.rs ```rust -# pub struct ThreadPool; -impl ThreadPool { - // --snip-- - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static - { - - } -} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs:here}} ``` We still use the `()` after `FnOnce` because this `FnOnce` represents a closure @@ -372,30 +259,13 @@ Again, this is the simplest implementation of the `execute` method: it does nothing, but we’re trying only to make our code compile. Let’s check it again: ```text -$ cargo check - Compiling hello v0.1.0 (file:///projects/hello) -warning: unused variable: `size` - --> src/lib.rs:4:16 - | -4 | pub fn new(size: usize) -> ThreadPool { - | ^^^^ - | - = note: #[warn(unused_variables)] on by default - = note: to avoid this warning, consider using `_size` instead - -warning: unused variable: `f` - --> src/lib.rs:8:30 - | -8 | pub fn execute(&self, f: F) - | ^ - | - = note: to avoid this warning, consider using `_f` instead +{{#include ../listings/ch20-web-server/no-listing-03-define-execute/output.txt}} ``` -We’re receiving only warnings now, which means it compiles! But note that if -you try `cargo run` and make a request in the browser, you’ll see the errors in -the browser that we saw at the beginning of the chapter. Our library isn’t -actually calling the closure passed to `execute` yet! +It compiles! But note that if you try `cargo run` and make a request in the +browser, you’ll see the errors in the browser that we saw at the beginning of +the chapter. Our library isn’t actually calling the closure passed to `execute` +yet! > Note: A saying you might hear about languages with strict compilers, such as > Haskell and Rust, is “if the code compiles, it works.” But this saying is not @@ -406,36 +276,19 @@ actually calling the closure passed to `execute` yet! #### Validating the Number of Threads in `new` -We’ll continue to get warnings because we aren’t doing anything with the -parameters to `new` and `execute`. Let’s implement the bodies of these -functions with the behavior we want. To start, let’s think about `new`. Earlier -we chose an unsigned type for the `size` parameter, because a pool with a -negative number of threads makes no sense. However, a pool with zero threads -also makes no sense, yet zero is a perfectly valid `usize`. We’ll add code to -check that `size` is greater than zero before we return a `ThreadPool` instance -and have the program panic if it receives a zero by using the `assert!` macro, -as shown in Listing 20-13. +We aren’t doing anything with the parameters to `new` and `execute`. Let’s +implement the bodies of these functions with the behavior we want. To start, +let’s think about `new`. Earlier we chose an unsigned type for the `size` +parameter, because a pool with a negative number of threads makes no sense. +However, a pool with zero threads also makes no sense, yet zero is a perfectly +valid `usize`. We’ll add code to check that `size` is greater than zero before +we return a `ThreadPool` instance and have the program panic if it receives a +zero by using the `assert!` macro, as shown in Listing 20-13. Filename: src/lib.rs ```rust -# pub struct ThreadPool; -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-- -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-13/src/lib.rs:here}} ``` Listing 20-13: Implementing `ThreadPool::new` to panic if @@ -486,30 +339,7 @@ returned a `ThreadPool` instance containing them. Filename: src/lib.rs ```rust,ignore,not_desired_behavior -use std::thread; - -pub struct ThreadPool { - threads: Vec>, -} - -impl ThreadPool { - // --snip-- - 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-- -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-14/src/lib.rs:here}} ``` Listing 20-14: Creating a vector for `ThreadPool` to hold @@ -575,45 +405,7 @@ Ready? Here is Listing 20-15 with one way to make the preceding modifications. Filename: src/lib.rs ```rust -use std::thread; - -pub struct ThreadPool { - workers: Vec, -} - -impl ThreadPool { - // --snip-- - 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-- -} - -struct Worker { - id: usize, - thread: thread::JoinHandle<()>, -} - -impl Worker { - fn new(id: usize) -> Worker { - let thread = thread::spawn(|| {}); - - Worker { - id, - thread, - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-15/src/lib.rs:here}} ``` Listing 20-15: Modifying `ThreadPool` to hold `Worker` @@ -668,53 +460,7 @@ the channel. Filename: src/lib.rs ```rust -# use std::thread; -// --snip-- -use std::sync::mpsc; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -struct Job; - -impl ThreadPool { - // --snip-- - 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-- -} -# -# struct Worker { -# id: usize, -# thread: thread::JoinHandle<()>, -# } -# -# impl Worker { -# fn new(id: usize) -> Worker { -# let thread = thread::spawn(|| {}); -# -# Worker { -# id, -# thread, -# } -# } -# } +{{#rustdoc_include ../listings/ch20-web-server/listing-20-16/src/lib.rs:here}} ``` Listing 20-16: Modifying `ThreadPool` to store the @@ -731,41 +477,7 @@ the closure. The code in Listing 20-17 won’t quite compile yet. Filename: src/lib.rs ```rust,ignore,does_not_compile -impl ThreadPool { - // --snip-- - 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-- -} - -// --snip-- - -impl Worker { - fn new(id: usize, receiver: mpsc::Receiver) -> Worker { - let thread = thread::spawn(|| { - receiver; - }); - - Worker { - id, - thread, - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-17/src/lib.rs:here}} ``` Listing 20-17: Passing the receiving end of the channel @@ -777,17 +489,7 @@ the channel into `Worker::new`, and then we use it inside the closure. When we try to check this code, we get this error: ```text -$ cargo check - Compiling hello v0.1.0 (file:///projects/hello) -error[E0382]: use of moved value: `receiver` - --> src/lib.rs:27:42 - | -27 | workers.push(Worker::new(id, receiver)); - | ^^^^^^^^ value moved here in - previous iteration of loop - | - = note: move occurs because `receiver` has type - `std::sync::mpsc::Receiver`, which does not implement the `Copy` trait +{{#include ../listings/ch20-web-server/listing-20-17/output.txt}} ``` The code is trying to pass `receiver` to multiple `Worker` instances. This @@ -810,60 +512,7 @@ receiver at a time. Listing 20-18 shows the changes we need to make. Filename: src/lib.rs ```rust -# use std::thread; -# use std::sync::mpsc; -use std::sync::Arc; -use std::sync::Mutex; -// --snip-- - -# pub struct ThreadPool { -# workers: Vec, -# sender: mpsc::Sender, -# } -# struct Job; -# -impl ThreadPool { - // --snip-- - 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-- -} - -# struct Worker { -# id: usize, -# thread: thread::JoinHandle<()>, -# } -# -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - // --snip-- -# let thread = thread::spawn(|| { -# receiver; -# }); -# -# Worker { -# id, -# thread, -# } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-18/src/lib.rs:here}} ``` Listing 20-18: Sharing the receiving end of the channel @@ -887,30 +536,7 @@ at Listing 20-19. Filename: src/lib.rs ```rust -// --snip-- -# pub struct ThreadPool { -# workers: Vec, -# sender: mpsc::Sender, -# } -# use std::sync::mpsc; -# struct Worker {} - -type Job = Box; - -impl ThreadPool { - // --snip-- - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -// --snip-- +{{#rustdoc_include ../listings/ch20-web-server/listing-20-19/src/lib.rs:here}} ``` Listing 20-19: Creating a `Job` type alias for a `Box` @@ -933,27 +559,8 @@ shown in Listing 20-20 to `Worker::new`. Filename: src/lib.rs -```rust,ignore,does_not_compile -// --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, - } - } -} +```rust +{{#rustdoc_include ../listings/ch20-web-server/listing-20-20/src/lib.rs:here}} ``` Listing 20-20: Receiving and executing the jobs in the @@ -976,10 +583,16 @@ The call to `recv` blocks, so if there is no job yet, the current thread will wait until a job becomes available. The `Mutex` ensures that only one `Worker` thread at a time is trying to request a job. - With the implementation of this trick, our thread pool is in a working state! Give it a `cargo run` and make some requests: + + ```text $ cargo run Compiling hello v0.1.0 (file:///projects/hello) @@ -1007,7 +620,7 @@ warning: field is never used: `thread` | = note: #[warn(dead_code)] on by default - Finished dev [unoptimized + debuginfo] target(s) in 0.99 secs + Finished dev [unoptimized + debuginfo] target(s) in 0.99s Running `target/debug/hello` Worker 0 got a job; executing. Worker 2 got a job; executing. @@ -1038,24 +651,7 @@ why we didn’t write the worker thread code as shown in Listing 20-21. Filename: src/lib.rs ```rust,ignore,not_desired_behavior -// --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, - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-21/src/lib.rs:here}} ``` Listing 20-21: An alternative implementation of diff --git a/src/ch20-03-graceful-shutdown-and-cleanup.md b/src/ch20-03-graceful-shutdown-and-cleanup.md index 174378b9..fe80857d 100644 --- a/src/ch20-03-graceful-shutdown-and-cleanup.md +++ b/src/ch20-03-graceful-shutdown-and-cleanup.md @@ -24,15 +24,7 @@ quite work yet. Filename: src/lib.rs ```rust,ignore,does_not_compile -impl Drop for ThreadPool { - fn drop(&mut self) { - for worker in &mut self.workers { - println!("Shutting down worker {}", worker.id); - - worker.thread.join().unwrap(); - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-22/src/lib.rs:here}} ``` Listing 20-22: Joining each thread when the thread pool @@ -48,11 +40,7 @@ into an ungraceful shutdown. Here is the error we get when we compile this code: ```text -error[E0507]: cannot move out of borrowed content - --> src/lib.rs:65:13 - | -65 | worker.thread.join().unwrap(); - | ^^^^^^ cannot move out of borrowed content +{{#include ../listings/ch20-web-server/listing-20-22/output.txt}} ``` The error tells us we can’t call `join` because we only have a mutable borrow @@ -70,37 +58,15 @@ So we know we want to update the definition of `Worker` like this: Filename: src/lib.rs -```rust -# use std::thread; -struct Worker { - id: usize, - thread: Option>, -} +```rust,ignore,does_not_compile +{{#rustdoc_include ../listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs:here}} ``` Now let’s lean on the compiler to find the other places that need to change. Checking this code, we get two errors: ```text -error[E0599]: no method named `join` found for type -`std::option::Option>` in the current scope - --> src/lib.rs:65:27 - | -65 | worker.thread.join().unwrap(); - | ^^^^ - -error[E0308]: mismatched types - --> src/lib.rs:89:13 - | -89 | thread, - | ^^^^^^ - | | - | expected enum `std::option::Option`, found struct - `std::thread::JoinHandle` - | help: try using a variant of the expected type: `Some(thread)` - | - = note: expected type `std::option::Option>` - found type `std::thread::JoinHandle<_>` +{{#include ../listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt}} ``` Let’s address the second error, which points to the code at the end of @@ -110,16 +76,7 @@ new `Worker`. Make the following changes to fix this error: Filename: src/lib.rs ```rust,ignore -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - // --snip-- - - Worker { - id, - thread: Some(thread), - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs:here}} ``` The first error is in our `Drop` implementation. We mentioned earlier that we @@ -129,17 +86,7 @@ The following changes will do so: Filename: src/lib.rs ```rust,ignore -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(); - } - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs:here}} ``` As discussed in Chapter 17, the `take` method on `Option` takes the `Some` @@ -166,11 +113,7 @@ variants. Filename: src/lib.rs ```rust -# struct Job; -enum Message { - NewJob(Job), - Terminate, -} +{{#rustdoc_include ../listings/ch20-web-server/no-listing-07-define-message-enum/src/lib.rs:here}} ``` This `Message` enum will either be a `NewJob` variant that holds the `Job` the @@ -183,57 +126,7 @@ We need to adjust the channel to use values of type `Message` rather than type Filename: src/lib.rs ```rust,ignore -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -// --snip-- - -impl ThreadPool { - // --snip-- - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static - { - let job = Box::new(f); - - self.sender.send(Message::NewJob(job)).unwrap(); - } -} - -// --snip-- - -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), - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-23/src/lib.rs:here}} ``` Listing 20-23: Sending and receiving `Message` values and @@ -255,25 +148,7 @@ changing our `Drop` implementation to look like Listing 20-24. Filename: src/lib.rs ```rust,ignore -impl Drop for ThreadPool { - fn drop(&mut self) { - println!("Sending terminate message to all workers."); - - for _ in &mut 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(); - } - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-24/src/lib.rs:here}} ``` Listing 20-24: Sending `Message::Terminate` to the @@ -307,20 +182,7 @@ before gracefully shutting down the server, as shown in Listing 20-25. Filename: src/bin/main.rs ```rust,ignore -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."); -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-25/src/bin/main.rs:here}} ``` Listing 20-25: Shut down the server after serving two @@ -337,11 +199,19 @@ end of `main`, and the `drop` implementation will run. Start the server with `cargo run`, and make three requests. The third request should error, and in your terminal you should see output similar to this: + + ```text $ cargo run Compiling hello v0.1.0 (file:///projects/hello) - Finished dev [unoptimized + debuginfo] target(s) in 1.0 secs - Running `target/debug/hello` + Finished dev [unoptimized + debuginfo] target(s) in 1.0s + Running `target/debug/main` Worker 0 got a job; executing. Worker 3 got a job; executing. Shutting down. @@ -383,166 +253,13 @@ Here’s the full code for reference: Filename: src/bin/main.rs ```rust,ignore -use hello::ThreadPool; - -use std::io::prelude::*; -use std::net::TcpListener; -use std::net::TcpStream; -use std::fs; -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().take(2) { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } - - println!("Shutting down."); -} - -fn handle_connection(mut stream: TcpStream) { - let mut buffer = [0; 512]; - 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\r\n\r\n", "hello.html") - } else if buffer.starts_with(sleep) { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK\r\n\r\n", "hello.html") - } else { - ("HTTP/1.1 404 NOT FOUND\r\n\r\n", "404.html") - }; - - let contents = fs::read_to_string(filename).unwrap(); - - let response = format!("{}{}", status_line, contents); - - stream.write(response.as_bytes()).unwrap(); - stream.flush().unwrap(); -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-25/src/bin/main.rs:all}} ``` Filename: src/lib.rs ```rust -use std::thread; -use std::sync::mpsc; -use std::sync::Arc; -use std::sync::Mutex; - -enum Message { - NewJob(Job), - Terminate, -} - -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(Message::NewJob(job)).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - println!("Sending terminate message to all workers."); - - for _ in &mut 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), - } - } -} +{{#rustdoc_include ../listings/ch20-web-server/listing-20-25/src/lib.rs:here}} ``` We could do more here! If you want to continue enhancing this project, here are