diff --git a/.gitignore b/.gitignore index 56aa638d4..dbd55d346 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,260 @@ *.njsproj *.sln *.sw? + +rustbook-ru/cycles_3_5/Cargo.lock +rustbook-ru/cycles_3_5/Cargo.toml +rustbook-ru/cycles_3_5/src/main.rs +rustbook-ru/cycles_3_5/target/.rustc_info.json +rustbook-ru/cycles_3_5/target/CACHEDIR.TAG +rustbook-ru/cycles_3_5/target/debug/.cargo-lock +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-c253783af073fa6e/bin-cycles_3_5 +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-c253783af073fa6e/bin-cycles_3_5.json +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-c253783af073fa6e/dep-bin-cycles_3_5 +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-c253783af073fa6e/invoked.timestamp +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-dc176b0a8aa1d384/dep-test-bin-cycles_3_5 +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-dc176b0a8aa1d384/invoked.timestamp +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-dc176b0a8aa1d384/test-bin-cycles_3_5 +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-dc176b0a8aa1d384/test-bin-cycles_3_5.json +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-f14a7c93068820f1/bin-cycles_3_5 +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-f14a7c93068820f1/bin-cycles_3_5.json +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-f14a7c93068820f1/dep-bin-cycles_3_5 +rustbook-ru/cycles_3_5/target/debug/.fingerprint/cycles_3_5-f14a7c93068820f1/invoked.timestamp +rustbook-ru/cycles_3_5/target/debug/cycles_3_5.d +rustbook-ru/cycles_3_5/target/debug/cycles_3_5.exe +rustbook-ru/cycles_3_5/target/debug/cycles_3_5.pdb +rustbook-ru/cycles_3_5/target/debug/deps/cycles_3_5-c253783af073fa6e.d +rustbook-ru/cycles_3_5/target/debug/deps/cycles_3_5-dc176b0a8aa1d384.d +rustbook-ru/cycles_3_5/target/debug/deps/cycles_3_5.d +rustbook-ru/cycles_3_5/target/debug/deps/cycles_3_5.exe +rustbook-ru/cycles_3_5/target/debug/deps/cycles_3_5.pdb +rustbook-ru/cycles_3_5/target/debug/deps/libcycles_3_5-c253783af073fa6e.rmeta +rustbook-ru/cycles_3_5/target/debug/deps/libcycles_3_5-dc176b0a8aa1d384.rmeta +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfealghg-0vdxhwd-working/dep-graph.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfealghg-0vdxhwd-working/dep-graph.part.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfealghg-0vdxhwd-working/query-cache.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfealghg-0vdxhwd-working/work-products.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfealghg-0vdxhwd.lock +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfefwvxa-1kkkcxr-7onebx9jtyo3h5yr6swno5654/dep-graph.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfefwvxa-1kkkcxr-7onebx9jtyo3h5yr6swno5654/query-cache.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfefwvxa-1kkkcxr-7onebx9jtyo3h5yr6swno5654/work-products.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-0jbr1d9ga43gg/s-gzkfefwvxa-1kkkcxr.lock +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfealgg9-0pek6ib-working/dep-graph.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfealgg9-0pek6ib-working/dep-graph.part.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfealgg9-0pek6ib-working/query-cache.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfealgg9-0pek6ib-working/work-products.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfealgg9-0pek6ib.lock +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfefwvxi-0u18x8k-3qkehu52mqzefz5drpzv4iy0w/dep-graph.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfefwvxi-0u18x8k-3qkehu52mqzefz5drpzv4iy0w/query-cache.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfefwvxi-0u18x8k-3qkehu52mqzefz5drpzv4iy0w/work-products.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-1y6ujlyeevrve/s-gzkfefwvxi-0u18x8k.lock +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/0ro9b14ut7d6e8q9hcz6hdqxd.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/1mismad4ax139m8jpxm56u5ps.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/308zo3n0i8r6ea3rsbg2gj9m2.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/42ccgda5sgw8bfy30qpdmbbds.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/6y5sk2h6y545qxj0e81qcxsgc.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/8ou23t89gn4uk8bg5szlornpo.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/adjhbrkknkep5q8qzolf7f5su.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/b1rk05pjdh23ne0d9d3xr2kxs.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/cbu6httwlt0lyi8wfkxix1c7a.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/dep-graph.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/dep-graph.part.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/ecicg9dka1lknodd23z9hcacm.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/evpfw0bkf2ohhz2b5q7r2gw5p.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/query-cache.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6-working/work-products.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfeandqa-01njnq6.lock +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/0ro9b14ut7d6e8q9hcz6hdqxd.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/1mismad4ax139m8jpxm56u5ps.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/308zo3n0i8r6ea3rsbg2gj9m2.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/42ccgda5sgw8bfy30qpdmbbds.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/6y5sk2h6y545qxj0e81qcxsgc.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/8ou23t89gn4uk8bg5szlornpo.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/adjhbrkknkep5q8qzolf7f5su.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/b1rk05pjdh23ne0d9d3xr2kxs.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/cbu6httwlt0lyi8wfkxix1c7a.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/dep-graph.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/ecicg9dka1lknodd23z9hcacm.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/evpfw0bkf2ohhz2b5q7r2gw5p.o +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/query-cache.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki-8rpdpsrxhpenexr4rk04iuozc/work-products.bin +rustbook-ru/cycles_3_5/target/debug/incremental/cycles_3_5-37m9q3i4pavv1/s-gzkfefy8bb-1rihqki.lock +rustbook-ru/src/ch00-00-introduction.md.bak +.vs/book/FileContentIndex/2ca08269-4e51-443c-a77b-85f12e843257.vsidx +.vs/book/FileContentIndex/2f454a4b-0c2f-4cfc-9095-155eb0b0ccf4.vsidx +.vs/book/FileContentIndex/b86b8781-ac9a-4547-ba2a-089f8a95030c.vsidx +.vs/book/FileContentIndex/d0b97c63-b172-441f-9ffa-a95133024ebc.vsidx +.vs/book/FileContentIndex/e552bc62-c316-441c-8c45-a5815ab8a22d.vsidx +.vs/book/FileContentIndex/ff24b99c-24f9-479c-9475-81b161c44b02.vsidx +.vs/book/v17/.wsuo +.vs/book/v17/DocumentLayout.backup.json +.vs/book/v17/workspaceFileList.bin +.vs/slnx.sqlite +.vs/slnx.sqlite +.vs/book/v17/workspaceFileList.bin +.vs/book/v17/.wsuo +/rustbook-ru/target +/rustbook-ru/listings/ch16-fearless-concurrency/listing-16-02/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-01/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-01/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-01/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-02/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-03/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-03/target +/rustbook-ru/packages/mdbook-trpl-note/target +/rustbook-ru/packages/mdbook-trpl-listing/target +/rustbook-ru/packages/mdbook-trpl-listing/target +/rustbook-ru/packages/mdbook-trpl-listing/target +/rustbook-ru/packages/mdbook-trpl-listing +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-01/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-01/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-01/target +*.TAG +*.json +*.json +rustbook-ru/src/черновик +/.vs +/rustbook-ru/listings/ch12-an-io-project/listing-12-03/target +/rustbook-ru/listings/ch12-an-io-project/listing-12-04/target +/rustbook-ru/listings/ch12-an-io-project/listing-12-05/target +/rustbook-ru/listings/ch13-functional-features/listing-13-14/target +/rustbook-ru/listings/ch13-functional-features/listing-13-15/target +/rustbook-ru/listings/ch13-functional-features/listing-13-18/target +/rustbook-ru/listings/ch13-functional-features/listing-13-19/target +/rustbook-ru/listings/ch13-functional-features/listing-13-20/target +/.vs +/.vs +/.vs/book +/.vs/book/v17 +/.vs +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-06/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/no-listing-04-looping/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/target +/rustbook-ru/listings/ch03-common-programming-concepts/listing-03-03/target +/rustbook-ru/listings/ch03-common-programming-concepts/listing-03-04 +/rustbook-ru/listings/ch03-common-programming-concepts/listing-03-05/target +/rustbook-ru/listings/ch03-common-programming-concepts/listing-03-02/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-04-shadowing-can-change-types/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-06-floating-point/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-03-shadowing/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-09-char/target/debug +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-08-boolean/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-10-tuples/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-13-arrays/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-16-functions/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-27-if-false/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-26-if-true/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-30-else-if/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/target +/rustbook-ru/listings/ch21-web-server/listing-20-21/target +/rustbook-ru/listings/ch21-web-server/listing-20-22/target +/rustbook-ru/listings/ch21-web-server/listing-20-23/target +/rustbook-ru/listings/ch21-web-server/listing-20-24/target +/rustbook-ru/listings/ch21-web-server/listing-20-25/target +/rustbook-ru/listings/ch21-web-server/no-listing-01-define-threadpool-struct/target +/rustbook-ru/listings/ch21-web-server/no-listing-02-impl-threadpool-new/target +/rustbook-ru/listings/ch21-web-server/no-listing-03-define-execute/target +/rustbook-ru/listings/ch21-web-server/no-listing-04-update-worker-definition/target +/rustbook-ru/listings/ch21-web-server/no-listing-05-fix-worker-new/target +/rustbook-ru/listings/ch21-web-server/no-listing-06-fix-threadpool-drop/target +/rustbook-ru/listings/ch21-web-server/listing-20-20/target +/rustbook-ru/listings/ch21-web-server/no-listing-07-final-code/target +/rustbook-ru/listings/ch21-web-server/listing-20-18/target +/rustbook-ru/listings/ch21-web-server/listing-20-19/target +/rustbook-ru/listings/ch21-web-server/listing-20-17/target +/rustbook-ru/listings/ch21-web-server/listing-20-16/target +/rustbook-ru/listings/ch21-web-server/listing-20-15/target +/rustbook-ru/listings/ch21-web-server/listing-20-14/target +/rustbook-ru/listings/ch21-web-server/listing-20-13/target +/rustbook-ru/listings/ch21-web-server/listing-20-11/target +/rustbook-ru/listings/ch21-web-server/listing-20-10/target +/rustbook-ru/listings/ch21-web-server/listing-20-12/target +/rustbook-ru/listings/ch21-web-server/listing-20-07/target +/rustbook-ru/listings/ch21-web-server/listing-20-06/target +/rustbook-ru/listings/ch21-web-server/listing-20-05/target +/rustbook-ru/listings/ch21-web-server/listing-20-09/target +/rustbook-ru/listings/ch21-web-server/listing-20-02/target +/rustbook-ru/listings/ch21-web-server/listing-20-03/target +/rustbook-ru/listings/ch21-web-server/listing-20-01/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-22-iterator-on-counter/target +/rustbook-ru/listings/ch20-advanced-features/output-only-01-missing-unsafe/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-21-pancakes/pancakes/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-21-pancakes/hello_macro/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro +/rustbook-ru/listings/ch20-advanced-features/no-listing-19-returns-closure-trait-object/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-17-map-initializer/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-18-returns-closure/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-15-map-closure/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-16-map-function/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-13-generic-implicit-sized-bound/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-14-generic-maybe-sized/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-11-cant-create-str/target/debug +/rustbook-ru/listings/ch20-advanced-features/no-listing-10-loop-returns-never/target +/rustbook-ru/listings/ch20-advanced-features/no-listing-12-generic-fn-definition/target +/rustbook-ru/listings/ch20-advanced-features/listing-19-31/hello_macro/hello_macro_derive/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-04/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/listing-02-05/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/target +/rustbook-ru/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/target +/rustbook-ru/listings/ch03-common-programming-concepts/listing-03-01/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-32-loop/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/target +/rustbook-ru/listings/ch03-common-programming-concepts/no-listing-34-for-range/target +/rustbook-ru/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/target +/rustbook-ru/listings/ch04-understanding-ownership/listing-04-01/target +/rustbook-ru/listings/ch04-understanding-ownership/listing-04-03/target +/rustbook-ru/listings/ch04-understanding-ownership/listing-04-02/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-03-string-move/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-06-copy/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-05-clone/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-07-reference/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/target +/rustbook-ru/listings/ch04-understanding-ownership/no-listing-16-no-dangle/target +*.timestamp +/rustbook-ru/listings/ch05-using-structs-to-structure-related-data/listing-05-15/target +*.cargo-lock +*lib-restaurant +*bin-collections +*test-bin-error-handling +*bin-error-handling +*bin-chapter10 +*lib-adder +*lib-greeter +**/target/ +*/target +*\target +*.lock +/logs +rustbook-ru/listings/ch20-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock +/rustbook-ru/logs +rustbook-ru/Cargo.lock diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 000000000..f8b488856 --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": null +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 000000000..6b6114114 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/book/v17/.wsuo b/.vs/book/v17/.wsuo new file mode 100644 index 000000000..d8d8fc44f Binary files /dev/null and b/.vs/book/v17/.wsuo differ diff --git a/.vs/book/v17/DocumentLayout.json b/.vs/book/v17/DocumentLayout.json new file mode 100644 index 000000000..5a0dcb99c --- /dev/null +++ b/.vs/book/v17/DocumentLayout.json @@ -0,0 +1,12 @@ +{ + "Version": 1, + "WorkspaceRootPath": "E:\\Rust\\\u043A\u043D\u0438\u0433\u0438\\book\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [] + } + ] +} \ No newline at end of file diff --git a/.vs/book/v17/workspaceFileList.bin b/.vs/book/v17/workspaceFileList.bin new file mode 100644 index 000000000..f48971fef Binary files /dev/null and b/.vs/book/v17/workspaceFileList.bin differ diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 000000000..353f82238 Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08f450d28..d8f8ff2bb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,16 +4,16 @@ ## Как устроен процесс перевода -Перевод происходит исключительно в системе GitLocalize. Для регистрации в системе нужно авторизоваться через аккаунт на Github. Для каждого перевода создан отдельный проект. -Список проектов можно найти [тут][books-projects]. +Перевод происходит исключительно в системе GitLocalize. Для регистрации в системе нужно авторизоваться через аккаунт на Github. Для каждого перевода создан отдельный дело. +Список дел можно найти [тут][books-projects]. Процесс перевода происходит в следующих этапах: 1. Перевод файла 2. После полного перевода файла появляется кнопка "Create Review Request" для отправки на ревью -3. В течение недели корректор вычитывает перевод, правит ошибки, приводит книгу к одному стилю -4. После этого корректор отправляет Pull Request на Github -5. Модераторы перевода исправляют помарки, опечатки и технические ошибки, вызванные багами GitLocalize, и мержат перевод. После этого перевод синхронизируется с GitLocalize и появляется в системе +3. В течение недели изменитель вычитывает перевод, правит ошибки, приводит книгу к одному стилю +4. После этого изменитель отправляет Pull Request на Github +5. Писари перевода исправляют помарки, опечатки и технические ошибки, вызванные багами GitLocalize, и мержат перевод. После этого перевод синхронизируется с GitLocalize и появляется в системе ## Соглашения о процессе перевода @@ -26,7 +26,7 @@ - Перевод должен быть в единой стилистике, которая поддерживается редактором. В [чате переводов][translations-chat] можно задать вопросы по стилистике и принести предложения по ней. ## Ресурсы -- [Список проектов и переводов][books-projects] +- [Список дел и переводов][books-projects] - [Словарь терминов и переводов](https://github.com/rust-lang-ru/dictionary#readme) - [Словарь для проверки орфографии](https://github.com/rust-lang-ru/common-configs/blob/master/.yaspellerrc) - [Чат переводов][translations-chat] diff --git a/README.md b/README.md index f3736471c..29c9083ad 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,116 @@ -# Язык программирования Rust (The Rust Programming Language) +# The Rust Programming Language -В данном репозитории содержится перевод книги [The Rust Programming Language](https://github.com/rust-lang/book). +![Build Status](https://github.com/rust-lang/book/workflows/CI/badge.svg) -## Зачем ещё один репозиторий? +This repository contains the source of "The Rust Programming Language" book. -Этот репозиторий подключён к системе перевода и вся работа ведётся там. -Сама система перевода нужна для отслеживания изменений в оригинале книги и -за счёт этого становится более удобной поддержка перевода, так как не надо -самому переводчику искать что изменилось - система сама это показывает. +[The book is available in dead-tree form from No Starch Press][nostarch]. -## GitLocalize +[nostarch]: https://nostarch.com/rust-programming-language-2nd-edition -Проект на GitLocalize: https://gitlocalize.com/repo/4579 +You can also read the book for free online. Please see the book as shipped with +the latest [stable], [beta], or [nightly] Rust releases. Be aware that issues +in those versions may have been fixed in this repository already, as those +releases are updated less frequently. -## Правила участия в переводе +[stable]: https://doc.rust-lang.org/stable/book/ +[beta]: https://doc.rust-lang.org/beta/book/ +[nightly]: https://doc.rust-lang.org/nightly/book/ -Правила участия в переводе описаны в [этом документе](https://github.com/rust-lang-ru/book/blob/master/CONTRIBUTING.md). +See the [releases] to download just the code of all the code listings that appear in the book. + +[releases]: https://github.com/rust-lang/book/releases + +## Requirements + +Building the book requires [mdBook], ideally the same version that +rust-lang/rust uses in [this file][rust-mdbook]. To get it: + +[mdBook]: https://github.com/rust-lang/mdBook +[rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml + +```bash +$ cargo install mdbook --locked --version +``` + +The book also uses two mdbook plugins which are part of this repository. If you +do not install them, you will see warnings when building and the output will not +look right, but you _will_ still be able to build the book. To use the plugins, +you should run: + +```bash +$ cargo install --locked --path packages/mdbook-trpl --force +``` + +## Building + +To build the book, type: + +```bash +$ mdbook build +``` + +The output will be in the `book` subdirectory. To check it out, open it in +your web browser. + +_Firefox:_ + +```bash +$ firefox book/index.html # Linux +$ open -a "Firefox" book/index.html # OS X +$ Start-Process "firefox.exe" .\book\index.html # Windows (PowerShell) +$ start firefox.exe .\book\index.html # Windows (Cmd) +``` + +_Chrome:_ + +```bash +$ google-chrome book/index.html # Linux +$ open -a "Google Chrome" book/index.html # OS X +$ Start-Process "chrome.exe" .\book\index.html # Windows (PowerShell) +$ start chrome.exe .\book\index.html # Windows (Cmd) +``` + +To run the tests: + +```bash +$ cd packages/trpl +$ mdbook test --library-path packages/trpl/target/debug/deps +``` + +## Contributing + +We'd love your help! Please see [CONTRIBUTING.md][contrib] to learn about the +kinds of contributions we're looking for. + +[contrib]: https://github.com/rust-lang/book/blob/main/CONTRIBUTING.md + +Because the book is [printed][nostarch], and because we want +to keep the online version of the book close to the print version when +possible, it may take longer than you're used to for us to address your issue +or pull request. + +So far, we've been doing a larger revision to coincide with [Rust Editions](https://doc.rust-lang.org/edition-guide/). Between those larger +revisions, we will only be correcting errors. If your issue or pull request +isn't strictly fixing an error, it might sit until the next time that we're +working on a large revision: expect on the order of months or years. Thank you +for your patience! + +### Translations + +We'd love help translating the book! See the [Translations] label to join in +efforts that are currently in progress. Open a new issue to start working on +a new language! We're waiting on [mdbook support] for multiple languages +before we merge any in, but feel free to start! + +[Translations]: https://github.com/rust-lang/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations +[mdbook support]: https://github.com/rust-lang/mdBook/issues/5 + +## Spellchecking + +To scan source files for spelling errors, you can use the `spellcheck.sh` +script available in the `ci` directory. It needs a dictionary of valid words, +which is provided in `ci/dictionary.txt`. If the script produces a false +positive (say, you used the word `BTreeMap` which the script considers invalid), +you need to add this word to `ci/dictionary.txt` (keep the sorted order for +consistency). diff --git a/rustbook-en/.cargo/config.toml b/rustbook-en/.cargo/config.toml deleted file mode 100644 index 2de187130..000000000 --- a/rustbook-en/.cargo/config.toml +++ /dev/null @@ -1,3 +0,0 @@ -[cargo-new] -name = "Your Name" -email = "you@example.com" diff --git a/rustbook-en/.gitattributes b/rustbook-en/.gitattributes deleted file mode 100644 index 22f241249..000000000 --- a/rustbook-en/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -# Set the default behavior, in case people don't have core.autocrlf set. -* text=auto eol=lf -*.docx binary -*.odt binary -*.png binary - diff --git a/rustbook-en/.github/ISSUE_TEMPLATE/bug_report.md b/rustbook-en/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 2423c4cd4..000000000 --- a/rustbook-en/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve ---- - -- I have searched open and closed issues and pull requests for duplicates, using these search terms: - - - - - - -- I have checked the latest `main` branch to see if this has already been fixed, in this file: - - - -URL to the section(s) of the book with this problem: - -Description of the problem: - -Suggested fix: diff --git a/rustbook-en/.github/ISSUE_TEMPLATE/new_translation.md b/rustbook-en/.github/ISSUE_TEMPLATE/new_translation.md deleted file mode 100644 index c7bdc06ed..000000000 --- a/rustbook-en/.github/ISSUE_TEMPLATE/new_translation.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: New translation -about: Let us know of a new language translation you're working on ---- - -Language your translation is for: -URL to the repo where you're working: diff --git a/rustbook-en/.github/workflows/main.yml b/rustbook-en/.github/workflows/main.yml deleted file mode 100644 index 1737bce00..000000000 --- a/rustbook-en/.github/workflows/main.yml +++ /dev/null @@ -1,99 +0,0 @@ -name: CI -on: [push, pull_request] - -jobs: - test: - name: Run tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Update rustup - run: rustup self update - - name: Install Rust - run: | - rustup set profile minimal - rustup toolchain install 1.79 -c rust-docs - rustup default 1.79 - - name: Install mdbook - run: | - mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin - echo "$(pwd)/bin" >> "${GITHUB_PATH}" - - name: Report versions - run: | - rustup --version - rustc -Vv - mdbook --version - - name: Run tests - run: mdbook test - package_tests: - name: Run package tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Update rustup - run: rustup self update - - name: Install Rust - run: | - rustup set profile minimal - rustup toolchain install 1.79 -c rust-docs - rustup default 1.79 - - name: Run `tools` package tests - run: | - cargo test - - name: Run `mdbook-trpl-note` package tests - working-directory: packages/mdbook-trpl-note - run: | - cargo test - - name: Run `mdbook-trpl-listing` package tests - working-directory: packages/mdbook-trpl-listing - run: | - cargo test - lint: - name: Run lints - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Update rustup - run: rustup self update - - name: Install Rust - run: | - rustup set profile minimal - rustup toolchain install nightly -c rust-docs - rustup override set nightly - - name: Install mdbook - run: | - mkdir bin - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.21/mdbook-v0.4.21-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=bin - echo "$(pwd)/bin" >> "${GITHUB_PATH}" - - name: Install mdbook-trpl-note - run: cargo install --path packages/mdbook-trpl-note - - name: Install mdbook-trpl-listing - run: cargo install --path packages/mdbook-trpl-listing - - name: Install aspell - run: sudo apt-get install aspell - - name: Install shellcheck - run: sudo apt-get install shellcheck - - name: Report versions - run: | - rustup --version - rustc -Vv - mdbook --version - aspell --version - shellcheck --version - - name: Shellcheck - run: find . -name '*.sh' -print0 | xargs -0 shellcheck - - name: Spellcheck - run: bash ci/spellcheck.sh list - - name: Lint for local file paths - run: | - mdbook build - cargo run --bin lfp src - - name: Validate references - run: bash ci/validate.sh - - name: Check for broken links - run: | - curl -sSLo linkcheck.sh \ - https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh - # Cannot use --all here because of the generated redirect pages aren't available. - sh linkcheck.sh book diff --git a/rustbook-en/.gitignore b/rustbook-en/.gitignore deleted file mode 100644 index 17127d114..000000000 --- a/rustbook-en/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -book/ -*~ -.idea -.DS_Store -target -tmp - -.nova diff --git a/rustbook-en/2018-edition/book.toml b/rustbook-en/2018-edition/book.toml deleted file mode 100644 index 03b59090b..000000000 --- a/rustbook-en/2018-edition/book.toml +++ /dev/null @@ -1,7 +0,0 @@ -[book] -title = "The Rust Programming Language" -author = "Steve Klabnik and Carol Nichols, with Contributions from the Rust Community" - -[output.html] -additional-css = ["ferris.css"] -additional-js = ["ferris.js"] diff --git a/rustbook-en/2018-edition/ferris.css b/rustbook-en/2018-edition/ferris.css deleted file mode 100644 index 371207924..000000000 --- a/rustbook-en/2018-edition/ferris.css +++ /dev/null @@ -1,33 +0,0 @@ -body.light .does_not_compile, -body.light .panics, -body.light .not_desired_behavior, -body.rust .does_not_compile, -body.rust .panics, -body.rust .not_desired_behavior { - background: #fff1f1; -} - -body.coal .does_not_compile, -body.coal .panics, -body.coal .not_desired_behavior, -body.navy .does_not_compile, -body.navy .panics, -body.navy .not_desired_behavior, -body.ayu .does_not_compile, -body.ayu .panics, -body.ayu .not_desired_behavior { - background: #501f21; -} - -.ferris { - position: absolute; - z-index: 99; - right: 5px; - top: 30px; - width: 10%; - height: auto; -} - -.ferris-explain { - width: 100px; -} diff --git a/rustbook-en/2018-edition/ferris.js b/rustbook-en/2018-edition/ferris.js deleted file mode 100644 index 5e79b3c71..000000000 --- a/rustbook-en/2018-edition/ferris.js +++ /dev/null @@ -1,51 +0,0 @@ -var ferrisTypes = [ - { - attr: 'does_not_compile', - title: 'This code does not compile!' - }, - { - attr: 'panics', - title: 'This code panics!' - }, - { - attr: 'unsafe', - title: 'This code block contains unsafe code.' - }, - { - attr: 'not_desired_behavior', - title: 'This code does not produce the desired behavior.' - } -] - -document.addEventListener('DOMContentLoaded', () => { - for (var ferrisType of ferrisTypes) { - attachFerrises(ferrisType) - } -}) - -function attachFerrises (type) { - var elements = document.getElementsByClassName(type.attr) - - for (var codeBlock of elements) { - var lines = codeBlock.textContent.split(/\r|\r\n|\n/).length - 1; - - if (lines >= 4) { - attachFerris(codeBlock, type) - } - } -} - -function attachFerris (element, type) { - var a = document.createElement('a') - a.setAttribute('href', 'ch00-00-introduction.html#ferris') - a.setAttribute('target', '_blank') - - var img = document.createElement('img') - img.setAttribute('src', 'img/ferris/' + type.attr + '.svg') - img.setAttribute('title', type.title) - img.className = 'ferris' - - a.appendChild(img) - - element.parentElement.insertBefore(a, element) -} diff --git a/rustbook-en/2018-edition/src/SUMMARY.md b/rustbook-en/2018-edition/src/SUMMARY.md deleted file mode 100644 index db8991c00..000000000 --- a/rustbook-en/2018-edition/src/SUMMARY.md +++ /dev/null @@ -1,132 +0,0 @@ -# The Rust Programming Language - -[Foreword](foreword.md) -[Introduction](ch00-00-introduction.md) - -## Getting started - -- [Getting Started](ch01-00-getting-started.md) - - [Installation](ch01-01-installation.md) - - [Hello, World!](ch01-02-hello-world.md) - - [Hello, Cargo!](ch01-03-hello-cargo.md) - -- [Programming a Guessing Game](ch02-00-guessing-game-tutorial.md) - -- [Common Programming Concepts](ch03-00-common-programming-concepts.md) - - [Variables and Mutability](ch03-01-variables-and-mutability.md) - - [Data Types](ch03-02-data-types.md) - - [How Functions Work](ch03-03-how-functions-work.md) - - [Comments](ch03-04-comments.md) - - [Control Flow](ch03-05-control-flow.md) - -- [Understanding Ownership](ch04-00-understanding-ownership.md) - - [What is Ownership?](ch04-01-what-is-ownership.md) - - [References & Borrowing](ch04-02-references-and-borrowing.md) - - [Slices](ch04-03-slices.md) - -- [Using Structs to Structure Related Data](ch05-00-structs.md) - - [Defining and Instantiating Structs](ch05-01-defining-structs.md) - - [An Example Program Using Structs](ch05-02-example-structs.md) - - [Method Syntax](ch05-03-method-syntax.md) - -- [Enums and Pattern Matching](ch06-00-enums.md) - - [Defining an Enum](ch06-01-defining-an-enum.md) - - [The `match` Control Flow Operator](ch06-02-match.md) - - [Concise Control Flow with `if let`](ch06-03-if-let.md) - -## Basic Rust Literacy - -- [Packages, Crates, and Modules](ch07-00-packages-crates-and-modules.md) - - [Packages and crates for making libraries and executables](ch07-01-packages-and-crates-for-making-libraries-and-executables.md) - - [Modules and `use` to control scope and privacy](ch07-02-modules-and-use-to-control-scope-and-privacy.md) - -- [Common Collections](ch08-00-common-collections.md) - - [Vectors](ch08-01-vectors.md) - - [Strings](ch08-02-strings.md) - - [Hash Maps](ch08-03-hash-maps.md) - -- [Error Handling](ch09-00-error-handling.md) - - [Unrecoverable Errors with `panic!`](ch09-01-unrecoverable-errors-with-panic.md) - - [Recoverable Errors with `Result`](ch09-02-recoverable-errors-with-result.md) - - [To `panic!` or Not to `panic!`](ch09-03-to-panic-or-not-to-panic.md) - -- [Generic Types, Traits, and Lifetimes](ch10-00-generics.md) - - [Generic Data Types](ch10-01-syntax.md) - - [Traits: Defining Shared Behavior](ch10-02-traits.md) - - [Validating References with Lifetimes](ch10-03-lifetime-syntax.md) - -- [Testing](ch11-00-testing.md) - - [Writing tests](ch11-01-writing-tests.md) - - [Running tests](ch11-02-running-tests.md) - - [Test Organization](ch11-03-test-organization.md) - -- [An I/O Project: Building a Command Line Program](ch12-00-an-io-project.md) - - [Accepting Command Line Arguments](ch12-01-accepting-command-line-arguments.md) - - [Reading a File](ch12-02-reading-a-file.md) - - [Refactoring to Improve Modularity and Error Handling](ch12-03-improving-error-handling-and-modularity.md) - - [Developing the Library’s Functionality with Test Driven Development](ch12-04-testing-the-librarys-functionality.md) - - [Working with Environment Variables](ch12-05-working-with-environment-variables.md) - - [Writing Error Messages to Standard Error Instead of Standard Output](ch12-06-writing-to-stderr-instead-of-stdout.md) - -## Thinking in Rust - -- [Functional Language Features: Iterators and Closures](ch13-00-functional-features.md) - - [Closures: Anonymous Functions that Can Capture Their Environment](ch13-01-closures.md) - - [Processing a Series of Items with Iterators](ch13-02-iterators.md) - - [Improving Our I/O Project](ch13-03-improving-our-io-project.md) - - [Comparing Performance: Loops vs. Iterators](ch13-04-performance.md) - -- [More about Cargo and Crates.io](ch14-00-more-about-cargo.md) - - [Customizing Builds with Release Profiles](ch14-01-release-profiles.md) - - [Publishing a Crate to Crates.io](ch14-02-publishing-to-crates-io.md) - - [Cargo Workspaces](ch14-03-cargo-workspaces.md) - - [Installing Binaries from Crates.io with `cargo install`](ch14-04-installing-binaries.md) - - [Extending Cargo with Custom Commands](ch14-05-extending-cargo.md) - -- [Smart Pointers](ch15-00-smart-pointers.md) - - [`Box` Points to Data on the Heap and Has a Known Size](ch15-01-box.md) - - [The `Deref` Trait Allows Access to the Data Through a Reference](ch15-02-deref.md) - - [The `Drop` Trait Runs Code on Cleanup](ch15-03-drop.md) - - [`Rc`, the Reference Counted Smart Pointer](ch15-04-rc.md) - - [`RefCell` and the Interior Mutability Pattern](ch15-05-interior-mutability.md) - - [Creating Reference Cycles and Leaking Memory is Safe](ch15-06-reference-cycles.md) - -- [Fearless Concurrency](ch16-00-concurrency.md) - - [Threads](ch16-01-threads.md) - - [Message Passing](ch16-02-message-passing.md) - - [Shared State](ch16-03-shared-state.md) - - [Extensible Concurrency: `Sync` and `Send`](ch16-04-extensible-concurrency-sync-and-send.md) - -- [Object Oriented Programming Features of Rust](ch17-00-oop.md) - - [Characteristics of Object-Oriented Languages](ch17-01-what-is-oo.md) - - [Using Trait Objects that Allow for Values of Different Types](ch17-02-trait-objects.md) - - [Implementing an Object-Oriented Design Pattern](ch17-03-oo-design-patterns.md) - -## Advanced Topics - -- [Patterns Match the Structure of Values](ch18-00-patterns.md) - - [All the Places Patterns May be Used](ch18-01-all-the-places-for-patterns.md) - - [Refutability: Whether a Pattern Might Fail to Match](ch18-02-refutability.md) - - [All the Pattern Syntax](ch18-03-pattern-syntax.md) - -- [Advanced Features](ch19-00-advanced-features.md) - - [Unsafe Rust](ch19-01-unsafe-rust.md) - - [Advanced Lifetimes](ch19-02-advanced-lifetimes.md) - - [Advanced Traits](ch19-03-advanced-traits.md) - - [Advanced Types](ch19-04-advanced-types.md) - - [Advanced Functions & Closures](ch19-05-advanced-functions-and-closures.md) - - [Macros](ch19-06-macros.md) - -- [Final Project: Building a Multithreaded Web Server](ch20-00-final-project-a-web-server.md) - - [A Single Threaded Web Server](ch20-01-single-threaded.md) - - [Turning our Single Threaded Server into a Multithreaded Server](ch20-02-multithreaded.md) - - [Graceful Shutdown and Cleanup](ch20-03-graceful-shutdown-and-cleanup.md) - -- [Appendix](appendix-00.md) - - [A - Keywords](appendix-01-keywords.md) - - [B - Operators and Symbols](appendix-02-operators.md) - - [C - Derivable Traits](appendix-03-derivable-traits.md) - - [D - Useful Development Tools](appendix-04-useful-development-tools.md) - - [E - Editions](appendix-05-editions.md) - - [F - Translations](appendix-06-translation.md) - - [G - How Rust is Made and “Nightly Rust”](appendix-07-nightly-rust.md) diff --git a/rustbook-en/2018-edition/src/appendix-00.md b/rustbook-en/2018-edition/src/appendix-00.md deleted file mode 100644 index c4145d6d8..000000000 --- a/rustbook-en/2018-edition/src/appendix-00.md +++ /dev/null @@ -1,10 +0,0 @@ -# Appendix - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-00.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-00.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/appendix-01-keywords.md b/rustbook-en/2018-edition/src/appendix-01-keywords.md deleted file mode 100644 index dde1ac6ce..000000000 --- a/rustbook-en/2018-edition/src/appendix-01-keywords.md +++ /dev/null @@ -1,10 +0,0 @@ -## Appendix A: Keywords - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-01-keywords.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-01-keywords.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/appendix-02-operators.md b/rustbook-en/2018-edition/src/appendix-02-operators.md deleted file mode 100644 index 4bca5b78f..000000000 --- a/rustbook-en/2018-edition/src/appendix-02-operators.md +++ /dev/null @@ -1,10 +0,0 @@ -## Appendix B: Operators and Symbols - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-02-operators.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-02-operators.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/appendix-03-derivable-traits.md b/rustbook-en/2018-edition/src/appendix-03-derivable-traits.md deleted file mode 100644 index effe9c22a..000000000 --- a/rustbook-en/2018-edition/src/appendix-03-derivable-traits.md +++ /dev/null @@ -1,10 +0,0 @@ -## Appendix C: Derivable Traits - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-03-derivable-traits.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-03-derivable-traits.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/appendix-04-useful-development-tools.md b/rustbook-en/2018-edition/src/appendix-04-useful-development-tools.md deleted file mode 100644 index 9757c17ab..000000000 --- a/rustbook-en/2018-edition/src/appendix-04-useful-development-tools.md +++ /dev/null @@ -1,10 +0,0 @@ -# Appendix D - Useful Development Tools - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-04-useful-development-tools.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-04-useful-development-tools.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/appendix-05-editions.md b/rustbook-en/2018-edition/src/appendix-05-editions.md deleted file mode 100644 index fe2254362..000000000 --- a/rustbook-en/2018-edition/src/appendix-05-editions.md +++ /dev/null @@ -1,10 +0,0 @@ -# Appendix E - Editions - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-05-editions.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-05-editions.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/appendix-06-translation.md b/rustbook-en/2018-edition/src/appendix-06-translation.md deleted file mode 100644 index ef6345533..000000000 --- a/rustbook-en/2018-edition/src/appendix-06-translation.md +++ /dev/null @@ -1,10 +0,0 @@ -## Appendix F: Translations of the Book - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-06-translation.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-06-translation.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/appendix-07-nightly-rust.md b/rustbook-en/2018-edition/src/appendix-07-nightly-rust.md deleted file mode 100644 index d5ee3806d..000000000 --- a/rustbook-en/2018-edition/src/appendix-07-nightly-rust.md +++ /dev/null @@ -1,10 +0,0 @@ -# Appendix G - How Rust is Made and “Nightly Rust” - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../appendix-07-nightly-rust.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/appendix-07-nightly-rust.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch00-00-introduction.md b/rustbook-en/2018-edition/src/ch00-00-introduction.md deleted file mode 100644 index 2645d6f54..000000000 --- a/rustbook-en/2018-edition/src/ch00-00-introduction.md +++ /dev/null @@ -1,10 +0,0 @@ -# Introduction - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch00-00-introduction.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch00-00-introduction.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch01-00-getting-started.md b/rustbook-en/2018-edition/src/ch01-00-getting-started.md deleted file mode 100644 index 18db71409..000000000 --- a/rustbook-en/2018-edition/src/ch01-00-getting-started.md +++ /dev/null @@ -1,10 +0,0 @@ -# Getting Started - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch01-00-getting-started.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch10-00-getting-started.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch01-01-installation.md b/rustbook-en/2018-edition/src/ch01-01-installation.md deleted file mode 100644 index 29ec038de..000000000 --- a/rustbook-en/2018-edition/src/ch01-01-installation.md +++ /dev/null @@ -1,10 +0,0 @@ -## Installation - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch01-01-installation.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch01-01-installation.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch01-02-hello-world.md b/rustbook-en/2018-edition/src/ch01-02-hello-world.md deleted file mode 100644 index f56f59291..000000000 --- a/rustbook-en/2018-edition/src/ch01-02-hello-world.md +++ /dev/null @@ -1,10 +0,0 @@ -## Hello, World! - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch01-02-hello-world.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch01-02-hello-world.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch01-03-hello-cargo.md b/rustbook-en/2018-edition/src/ch01-03-hello-cargo.md deleted file mode 100644 index 464955150..000000000 --- a/rustbook-en/2018-edition/src/ch01-03-hello-cargo.md +++ /dev/null @@ -1,10 +0,0 @@ -## Hello, Cargo! - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch01-03-hello-cargo.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch01-03-hello-cargo.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch02-00-guessing-game-tutorial.md b/rustbook-en/2018-edition/src/ch02-00-guessing-game-tutorial.md deleted file mode 100644 index 40a593691..000000000 --- a/rustbook-en/2018-edition/src/ch02-00-guessing-game-tutorial.md +++ /dev/null @@ -1,10 +0,0 @@ -# Programming a Guessing Game - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch02-00-guessing-game-tutorial.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch02-00-guessing-game-tutorial.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch03-00-common-programming-concepts.md b/rustbook-en/2018-edition/src/ch03-00-common-programming-concepts.md deleted file mode 100644 index 52e38dedf..000000000 --- a/rustbook-en/2018-edition/src/ch03-00-common-programming-concepts.md +++ /dev/null @@ -1,10 +0,0 @@ -# Common Programming Concepts - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-00-common-programming-concepts.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch03-00-common-programming-concepts.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch03-01-variables-and-mutability.md b/rustbook-en/2018-edition/src/ch03-01-variables-and-mutability.md deleted file mode 100644 index 990602058..000000000 --- a/rustbook-en/2018-edition/src/ch03-01-variables-and-mutability.md +++ /dev/null @@ -1,10 +0,0 @@ -## Variables and Mutability - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-01-variables-and-mutability.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch03-01-variables-and-mutability.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch03-02-data-types.md b/rustbook-en/2018-edition/src/ch03-02-data-types.md deleted file mode 100644 index 7109be297..000000000 --- a/rustbook-en/2018-edition/src/ch03-02-data-types.md +++ /dev/null @@ -1,10 +0,0 @@ -## Data Types - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-02-data-types.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch03-02-data-types.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch03-03-how-functions-work.md b/rustbook-en/2018-edition/src/ch03-03-how-functions-work.md deleted file mode 100644 index 60213ba9a..000000000 --- a/rustbook-en/2018-edition/src/ch03-03-how-functions-work.md +++ /dev/null @@ -1,10 +0,0 @@ -## Functions - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-03-how-functions-work.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch03-03-how-functions-work.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch03-04-comments.md b/rustbook-en/2018-edition/src/ch03-04-comments.md deleted file mode 100644 index 679c7ee21..000000000 --- a/rustbook-en/2018-edition/src/ch03-04-comments.md +++ /dev/null @@ -1,10 +0,0 @@ -## Comments - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-04-comments.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch03-04-comments.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch03-05-control-flow.md b/rustbook-en/2018-edition/src/ch03-05-control-flow.md deleted file mode 100644 index de3f331be..000000000 --- a/rustbook-en/2018-edition/src/ch03-05-control-flow.md +++ /dev/null @@ -1,10 +0,0 @@ -## Control Flow - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-05-control-flow.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch03-05-control-flow.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch04-00-understanding-ownership.md b/rustbook-en/2018-edition/src/ch04-00-understanding-ownership.md deleted file mode 100644 index d48cc711b..000000000 --- a/rustbook-en/2018-edition/src/ch04-00-understanding-ownership.md +++ /dev/null @@ -1,10 +0,0 @@ -# Understanding Ownership - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch04-00-understanding-ownership.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch04-00-understanding-ownership.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch04-01-what-is-ownership.md b/rustbook-en/2018-edition/src/ch04-01-what-is-ownership.md deleted file mode 100644 index f6a2e485e..000000000 --- a/rustbook-en/2018-edition/src/ch04-01-what-is-ownership.md +++ /dev/null @@ -1,10 +0,0 @@ -## What Is Ownership? - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch04-01-what-is-ownership.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch04-01-what-is-ownership.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch04-02-references-and-borrowing.md b/rustbook-en/2018-edition/src/ch04-02-references-and-borrowing.md deleted file mode 100644 index a6b9d5cba..000000000 --- a/rustbook-en/2018-edition/src/ch04-02-references-and-borrowing.md +++ /dev/null @@ -1,10 +0,0 @@ -## References and Borrowing - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch04-02-references-and-borrowing.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch04-02-references-and-borrowing.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch04-03-slices.md b/rustbook-en/2018-edition/src/ch04-03-slices.md deleted file mode 100644 index 8e1f8bcf9..000000000 --- a/rustbook-en/2018-edition/src/ch04-03-slices.md +++ /dev/null @@ -1,10 +0,0 @@ -## The Slice Type - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch04-03-slices.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch04-03-slices.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch05-00-structs.md b/rustbook-en/2018-edition/src/ch05-00-structs.md deleted file mode 100644 index 8957ae29d..000000000 --- a/rustbook-en/2018-edition/src/ch05-00-structs.md +++ /dev/null @@ -1,10 +0,0 @@ -# Using Structs to Structure Related Data - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch05-00-structs.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch05-00-structs.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch05-01-defining-structs.md b/rustbook-en/2018-edition/src/ch05-01-defining-structs.md deleted file mode 100644 index abd150f93..000000000 --- a/rustbook-en/2018-edition/src/ch05-01-defining-structs.md +++ /dev/null @@ -1,10 +0,0 @@ -## Defining and Instantiating Structs - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch05-01-defining-structs.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch05-01-defining-structs.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch05-02-example-structs.md b/rustbook-en/2018-edition/src/ch05-02-example-structs.md deleted file mode 100644 index ac6b43e19..000000000 --- a/rustbook-en/2018-edition/src/ch05-02-example-structs.md +++ /dev/null @@ -1,10 +0,0 @@ -## An Example Program Using Structs - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch05-02-example-structs.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch05-02-example-structs.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch05-03-method-syntax.md b/rustbook-en/2018-edition/src/ch05-03-method-syntax.md deleted file mode 100644 index a45b9f334..000000000 --- a/rustbook-en/2018-edition/src/ch05-03-method-syntax.md +++ /dev/null @@ -1,10 +0,0 @@ -## Method Syntax - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch05-03-method-syntax.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch05-03-method-syntax.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch06-00-enums.md b/rustbook-en/2018-edition/src/ch06-00-enums.md deleted file mode 100644 index 55d2cd162..000000000 --- a/rustbook-en/2018-edition/src/ch06-00-enums.md +++ /dev/null @@ -1,10 +0,0 @@ -# Enums and Pattern Matching - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch06-00-enums.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch06-00-enums.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch06-01-defining-an-enum.md b/rustbook-en/2018-edition/src/ch06-01-defining-an-enum.md deleted file mode 100644 index 81c2603dc..000000000 --- a/rustbook-en/2018-edition/src/ch06-01-defining-an-enum.md +++ /dev/null @@ -1,10 +0,0 @@ -## Defining an Enum - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch06-01-defining-an-enum.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch06-01-defining-an-enum.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch06-02-match.md b/rustbook-en/2018-edition/src/ch06-02-match.md deleted file mode 100644 index 5663fb82a..000000000 --- a/rustbook-en/2018-edition/src/ch06-02-match.md +++ /dev/null @@ -1,10 +0,0 @@ -## The `match` Control Flow Operator - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch06-02-match.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch06-02-match.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch06-03-if-let.md b/rustbook-en/2018-edition/src/ch06-03-if-let.md deleted file mode 100644 index 24b14c1d0..000000000 --- a/rustbook-en/2018-edition/src/ch06-03-if-let.md +++ /dev/null @@ -1,10 +0,0 @@ -## Concise Control Flow with `if let` - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch06-03-if-let.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch06-03-if-let.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch07-00-packages-crates-and-modules.md b/rustbook-en/2018-edition/src/ch07-00-packages-crates-and-modules.md deleted file mode 100644 index b4ea93377..000000000 --- a/rustbook-en/2018-edition/src/ch07-00-packages-crates-and-modules.md +++ /dev/null @@ -1,10 +0,0 @@ -# Packages, Crates, and Modules - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch07-00-packages-crates-and-modules.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch07-01-packages-and-crates-for-making-libraries-and-executables.md b/rustbook-en/2018-edition/src/ch07-01-packages-and-crates-for-making-libraries-and-executables.md deleted file mode 100644 index 605267733..000000000 --- a/rustbook-en/2018-edition/src/ch07-01-packages-and-crates-for-making-libraries-and-executables.md +++ /dev/null @@ -1,10 +0,0 @@ -## Packages and Crates for Making Libraries and Executables - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch07-01-packages-and-crates-for-making-libraries-and-executables.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch07-02-modules-and-use-to-control-scope-and-privacy.md b/rustbook-en/2018-edition/src/ch07-02-modules-and-use-to-control-scope-and-privacy.md deleted file mode 100644 index c137290e2..000000000 --- a/rustbook-en/2018-edition/src/ch07-02-modules-and-use-to-control-scope-and-privacy.md +++ /dev/null @@ -1,10 +0,0 @@ -## The Module System to Control Scope and Privacy - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch07-02-modules-and-use-to-control-scope-and-privacy.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch08-00-common-collections.md b/rustbook-en/2018-edition/src/ch08-00-common-collections.md deleted file mode 100644 index 079daccf3..000000000 --- a/rustbook-en/2018-edition/src/ch08-00-common-collections.md +++ /dev/null @@ -1,10 +0,0 @@ -# Common Collections - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch08-00-common-collections.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch08-00-common-collections.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch08-01-vectors.md b/rustbook-en/2018-edition/src/ch08-01-vectors.md deleted file mode 100644 index e13e45d52..000000000 --- a/rustbook-en/2018-edition/src/ch08-01-vectors.md +++ /dev/null @@ -1,10 +0,0 @@ -## Storing Lists of Values with Vectors - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch08-01-vectors.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch08-01-vectors.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch08-02-strings.md b/rustbook-en/2018-edition/src/ch08-02-strings.md deleted file mode 100644 index 2ca314b87..000000000 --- a/rustbook-en/2018-edition/src/ch08-02-strings.md +++ /dev/null @@ -1,10 +0,0 @@ -## Storing UTF-8 Encoded Text with Strings - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch08-02-strings.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch08-02-strings.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch08-03-hash-maps.md b/rustbook-en/2018-edition/src/ch08-03-hash-maps.md deleted file mode 100644 index 365ede452..000000000 --- a/rustbook-en/2018-edition/src/ch08-03-hash-maps.md +++ /dev/null @@ -1,10 +0,0 @@ -## Storing Keys with Associated Values in Hash Maps - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch08-03-hash-maps.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch08-03-hash-maps.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch09-00-error-handling.md b/rustbook-en/2018-edition/src/ch09-00-error-handling.md deleted file mode 100644 index d49907775..000000000 --- a/rustbook-en/2018-edition/src/ch09-00-error-handling.md +++ /dev/null @@ -1,10 +0,0 @@ -# Error Handling - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch09-00-error-handling.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch09-00-error-handling.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch09-01-unrecoverable-errors-with-panic.md b/rustbook-en/2018-edition/src/ch09-01-unrecoverable-errors-with-panic.md deleted file mode 100644 index 4850a3d00..000000000 --- a/rustbook-en/2018-edition/src/ch09-01-unrecoverable-errors-with-panic.md +++ /dev/null @@ -1,10 +0,0 @@ -## Unrecoverable Errors with `panic!` - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch09-01-unrecoverable-errors-with-panic.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch09-01-unrecoverable-errors-with-panic.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch09-02-recoverable-errors-with-result.md b/rustbook-en/2018-edition/src/ch09-02-recoverable-errors-with-result.md deleted file mode 100644 index 12c2158f9..000000000 --- a/rustbook-en/2018-edition/src/ch09-02-recoverable-errors-with-result.md +++ /dev/null @@ -1,10 +0,0 @@ -## Recoverable Errors with `Result` - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch09-02-recoverable-errors-with-result.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch09-02-recoverable-errors-with-result.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch09-03-to-panic-or-not-to-panic.md b/rustbook-en/2018-edition/src/ch09-03-to-panic-or-not-to-panic.md deleted file mode 100644 index 1d1d06e48..000000000 --- a/rustbook-en/2018-edition/src/ch09-03-to-panic-or-not-to-panic.md +++ /dev/null @@ -1,10 +0,0 @@ -## To `panic!` or Not to `panic!` - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch09-03-to-panic-or-not-to-panic.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch09-03-to-panic-or-not-to-panic.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch10-00-generics.md b/rustbook-en/2018-edition/src/ch10-00-generics.md deleted file mode 100644 index e29591247..000000000 --- a/rustbook-en/2018-edition/src/ch10-00-generics.md +++ /dev/null @@ -1,10 +0,0 @@ -# Generic Types, Traits, and Lifetimes - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch10-00-generics.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch10-00-generics.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch10-01-syntax.md b/rustbook-en/2018-edition/src/ch10-01-syntax.md deleted file mode 100644 index 0237c7694..000000000 --- a/rustbook-en/2018-edition/src/ch10-01-syntax.md +++ /dev/null @@ -1,10 +0,0 @@ -## Generic Data Types - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch10-01-syntax.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch10-01-syntax.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch10-02-traits.md b/rustbook-en/2018-edition/src/ch10-02-traits.md deleted file mode 100644 index 667383339..000000000 --- a/rustbook-en/2018-edition/src/ch10-02-traits.md +++ /dev/null @@ -1,10 +0,0 @@ -## Traits: Defining Shared Behavior - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch10-02-traits.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch10-02-traits.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch10-03-lifetime-syntax.md b/rustbook-en/2018-edition/src/ch10-03-lifetime-syntax.md deleted file mode 100644 index a3ccf0033..000000000 --- a/rustbook-en/2018-edition/src/ch10-03-lifetime-syntax.md +++ /dev/null @@ -1,10 +0,0 @@ -## Validating References with Lifetimes - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch10-03-lifetime-syntax.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch10-03-lifetime-syntax.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch11-00-testing.md b/rustbook-en/2018-edition/src/ch11-00-testing.md deleted file mode 100644 index 33f5d7eeb..000000000 --- a/rustbook-en/2018-edition/src/ch11-00-testing.md +++ /dev/null @@ -1,10 +0,0 @@ -# Writing Automated Tests - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch11-00-testing.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch11-00-testing.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch11-01-writing-tests.md b/rustbook-en/2018-edition/src/ch11-01-writing-tests.md deleted file mode 100644 index 17c608e61..000000000 --- a/rustbook-en/2018-edition/src/ch11-01-writing-tests.md +++ /dev/null @@ -1,10 +0,0 @@ -## How to Write Tests - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch11-01-writing-tests.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch11-01-writing-tests.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch11-02-running-tests.md b/rustbook-en/2018-edition/src/ch11-02-running-tests.md deleted file mode 100644 index 377407684..000000000 --- a/rustbook-en/2018-edition/src/ch11-02-running-tests.md +++ /dev/null @@ -1,10 +0,0 @@ -## Controlling How Tests Are Run - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch11-02-running-tests.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch11-02-running-tests.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch11-03-test-organization.md b/rustbook-en/2018-edition/src/ch11-03-test-organization.md deleted file mode 100644 index 92cca4c74..000000000 --- a/rustbook-en/2018-edition/src/ch11-03-test-organization.md +++ /dev/null @@ -1,10 +0,0 @@ -## Test Organization - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch11-03-test-organization.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch11-03-test-organization.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch12-00-an-io-project.md b/rustbook-en/2018-edition/src/ch12-00-an-io-project.md deleted file mode 100644 index 3e1fbac98..000000000 --- a/rustbook-en/2018-edition/src/ch12-00-an-io-project.md +++ /dev/null @@ -1,10 +0,0 @@ -# An I/O Project: Building a Command Line Program - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch12-00-an-io-project.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch12-00-an-io-project.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch12-01-accepting-command-line-arguments.md b/rustbook-en/2018-edition/src/ch12-01-accepting-command-line-arguments.md deleted file mode 100644 index a91b0cad1..000000000 --- a/rustbook-en/2018-edition/src/ch12-01-accepting-command-line-arguments.md +++ /dev/null @@ -1,10 +0,0 @@ -## Accepting Command Line Arguments - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch12-01-accepting-command-line-arguments.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch12-01-accepting-command-line-arguments.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch12-02-reading-a-file.md b/rustbook-en/2018-edition/src/ch12-02-reading-a-file.md deleted file mode 100644 index 6ef334939..000000000 --- a/rustbook-en/2018-edition/src/ch12-02-reading-a-file.md +++ /dev/null @@ -1,10 +0,0 @@ -## Reading a File - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch12-02-reading-a-file.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch12-02-reading-a-file.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch12-03-improving-error-handling-and-modularity.md b/rustbook-en/2018-edition/src/ch12-03-improving-error-handling-and-modularity.md deleted file mode 100644 index 5d52ab893..000000000 --- a/rustbook-en/2018-edition/src/ch12-03-improving-error-handling-and-modularity.md +++ /dev/null @@ -1,10 +0,0 @@ -## Refactoring to Improve Modularity and Error Handling - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch12-03-improving-error-handling-and-modularity.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch12-03-improving-error-handling-and-modularity.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch12-04-testing-the-librarys-functionality.md b/rustbook-en/2018-edition/src/ch12-04-testing-the-librarys-functionality.md deleted file mode 100644 index 12b0204d8..000000000 --- a/rustbook-en/2018-edition/src/ch12-04-testing-the-librarys-functionality.md +++ /dev/null @@ -1,10 +0,0 @@ -## Developing the Library’s Functionality with Test-Driven Development - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch12-04-testing-the-librarys-functionality.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch12-04-testing-the-librarys-functionality.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch12-05-working-with-environment-variables.md b/rustbook-en/2018-edition/src/ch12-05-working-with-environment-variables.md deleted file mode 100644 index d6316cb2d..000000000 --- a/rustbook-en/2018-edition/src/ch12-05-working-with-environment-variables.md +++ /dev/null @@ -1,10 +0,0 @@ -## Working with Environment Variables - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch12-05-working-with-environment-variables.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch12-05-working-with-environment-variables.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch12-06-writing-to-stderr-instead-of-stdout.md b/rustbook-en/2018-edition/src/ch12-06-writing-to-stderr-instead-of-stdout.md deleted file mode 100644 index 6114b4bb8..000000000 --- a/rustbook-en/2018-edition/src/ch12-06-writing-to-stderr-instead-of-stdout.md +++ /dev/null @@ -1,10 +0,0 @@ -## Writing Error Messages to Standard Error Instead of Standard Output - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch12-06-writing-to-stderr-instead-of-stdout.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch12-06-writing-to-stderr-instead-of-stdout.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch13-00-functional-features.md b/rustbook-en/2018-edition/src/ch13-00-functional-features.md deleted file mode 100644 index 466b49c6f..000000000 --- a/rustbook-en/2018-edition/src/ch13-00-functional-features.md +++ /dev/null @@ -1,10 +0,0 @@ -# Functional Language Features: Iterators and Closures - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch13-00-functional-features.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch13-00-functional-features.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch13-01-closures.md b/rustbook-en/2018-edition/src/ch13-01-closures.md deleted file mode 100644 index bc580304e..000000000 --- a/rustbook-en/2018-edition/src/ch13-01-closures.md +++ /dev/null @@ -1,10 +0,0 @@ -## Closures: Anonymous Functions that Can Capture Their Environment - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch13-01-closures.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch13-01-closures.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch13-02-iterators.md b/rustbook-en/2018-edition/src/ch13-02-iterators.md deleted file mode 100644 index 7f5e9cf86..000000000 --- a/rustbook-en/2018-edition/src/ch13-02-iterators.md +++ /dev/null @@ -1,10 +0,0 @@ -## Processing a Series of Items with Iterators - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch13-02-iterators.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch13-02-iterators.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch13-03-improving-our-io-project.md b/rustbook-en/2018-edition/src/ch13-03-improving-our-io-project.md deleted file mode 100644 index 5148fcf1b..000000000 --- a/rustbook-en/2018-edition/src/ch13-03-improving-our-io-project.md +++ /dev/null @@ -1,10 +0,0 @@ -## Improving Our I/O Project - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch13-03-improving-our-io-project.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch13-03-improving-our-io-project.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch13-04-performance.md b/rustbook-en/2018-edition/src/ch13-04-performance.md deleted file mode 100644 index 817a13844..000000000 --- a/rustbook-en/2018-edition/src/ch13-04-performance.md +++ /dev/null @@ -1,10 +0,0 @@ -## Comparing Performance: Loops vs. Iterators - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch13-04-performance.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch13-04-performance.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch14-00-more-about-cargo.md b/rustbook-en/2018-edition/src/ch14-00-more-about-cargo.md deleted file mode 100644 index dea00b8aa..000000000 --- a/rustbook-en/2018-edition/src/ch14-00-more-about-cargo.md +++ /dev/null @@ -1,10 +0,0 @@ -# More About Cargo and Crates.io - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch14-00-more-about-cargo.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch14-00-more-about-cargo.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch14-01-release-profiles.md b/rustbook-en/2018-edition/src/ch14-01-release-profiles.md deleted file mode 100644 index eb9946ac7..000000000 --- a/rustbook-en/2018-edition/src/ch14-01-release-profiles.md +++ /dev/null @@ -1,10 +0,0 @@ -## Customizing Builds with Release Profiles - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch14-01-release-profiles.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch14-01-release-profiles.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch14-02-publishing-to-crates-io.md b/rustbook-en/2018-edition/src/ch14-02-publishing-to-crates-io.md deleted file mode 100644 index a5707e5ac..000000000 --- a/rustbook-en/2018-edition/src/ch14-02-publishing-to-crates-io.md +++ /dev/null @@ -1,10 +0,0 @@ -## Publishing a Crate to Crates.io - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch14-02-publishing-to-crates-io.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch14-02-publishing-to-crates-io.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch14-03-cargo-workspaces.md b/rustbook-en/2018-edition/src/ch14-03-cargo-workspaces.md deleted file mode 100644 index 50691e654..000000000 --- a/rustbook-en/2018-edition/src/ch14-03-cargo-workspaces.md +++ /dev/null @@ -1,10 +0,0 @@ -## Cargo Workspaces - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch14-03-cargo-workspaces.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch14-03-cargo-workspaces.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch14-04-installing-binaries.md b/rustbook-en/2018-edition/src/ch14-04-installing-binaries.md deleted file mode 100644 index b6e196bb9..000000000 --- a/rustbook-en/2018-edition/src/ch14-04-installing-binaries.md +++ /dev/null @@ -1,10 +0,0 @@ -## Installing Binaries from Crates.io with `cargo install` - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch14-04-installing-binaries.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch14-04-installing-binaries.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch14-05-extending-cargo.md b/rustbook-en/2018-edition/src/ch14-05-extending-cargo.md deleted file mode 100644 index ed1235de6..000000000 --- a/rustbook-en/2018-edition/src/ch14-05-extending-cargo.md +++ /dev/null @@ -1,10 +0,0 @@ -## Extending Cargo with Custom Commands - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch14-05-extending-cargo.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch14-05-extending-cargo.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch15-00-smart-pointers.md b/rustbook-en/2018-edition/src/ch15-00-smart-pointers.md deleted file mode 100644 index de4c648df..000000000 --- a/rustbook-en/2018-edition/src/ch15-00-smart-pointers.md +++ /dev/null @@ -1,10 +0,0 @@ -# Smart Pointers - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-00-smart-pointers.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch15-00-smart-pointers.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch15-01-box.md b/rustbook-en/2018-edition/src/ch15-01-box.md deleted file mode 100644 index cbbc07bbf..000000000 --- a/rustbook-en/2018-edition/src/ch15-01-box.md +++ /dev/null @@ -1,10 +0,0 @@ -## Using `Box` to Point to Data on the Heap - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-01-box.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch15-01-box.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch15-02-deref.md b/rustbook-en/2018-edition/src/ch15-02-deref.md deleted file mode 100644 index b5f1f8612..000000000 --- a/rustbook-en/2018-edition/src/ch15-02-deref.md +++ /dev/null @@ -1,10 +0,0 @@ -## Treating Smart Pointers Like Regular References with the `Deref` Trait - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-02-deref.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch15-02-deref.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch15-03-drop.md b/rustbook-en/2018-edition/src/ch15-03-drop.md deleted file mode 100644 index 2ae0b436d..000000000 --- a/rustbook-en/2018-edition/src/ch15-03-drop.md +++ /dev/null @@ -1,10 +0,0 @@ -## Running Code on Cleanup with the `Drop` Trait - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-03-drop.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch15-03-drop.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch15-04-rc.md b/rustbook-en/2018-edition/src/ch15-04-rc.md deleted file mode 100644 index 2b4015e7e..000000000 --- a/rustbook-en/2018-edition/src/ch15-04-rc.md +++ /dev/null @@ -1,10 +0,0 @@ -## `Rc`, the Reference Counted Smart Pointer - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-04-rc.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch15-04-rc.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch15-05-interior-mutability.md b/rustbook-en/2018-edition/src/ch15-05-interior-mutability.md deleted file mode 100644 index fb1f96df7..000000000 --- a/rustbook-en/2018-edition/src/ch15-05-interior-mutability.md +++ /dev/null @@ -1,10 +0,0 @@ -## `RefCell` and the Interior Mutability Pattern - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-05-interior-mutability.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch15-05-interior-mutability.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch15-06-reference-cycles.md b/rustbook-en/2018-edition/src/ch15-06-reference-cycles.md deleted file mode 100644 index ac93fe3bb..000000000 --- a/rustbook-en/2018-edition/src/ch15-06-reference-cycles.md +++ /dev/null @@ -1,10 +0,0 @@ -## Reference Cycles Can Leak Memory - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-06-reference-cycles.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch15-06-reference-cycles.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch16-00-concurrency.md b/rustbook-en/2018-edition/src/ch16-00-concurrency.md deleted file mode 100644 index 1cf6b2f58..000000000 --- a/rustbook-en/2018-edition/src/ch16-00-concurrency.md +++ /dev/null @@ -1,10 +0,0 @@ -# Fearless Concurrency - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch16-00-concurrency.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch16-00-concurrency.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch16-01-threads.md b/rustbook-en/2018-edition/src/ch16-01-threads.md deleted file mode 100644 index 708e30be7..000000000 --- a/rustbook-en/2018-edition/src/ch16-01-threads.md +++ /dev/null @@ -1,10 +0,0 @@ -## Using Threads to Run Code Simultaneously - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch16-01-threads.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch16-01-threads.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch16-02-message-passing.md b/rustbook-en/2018-edition/src/ch16-02-message-passing.md deleted file mode 100644 index 4540efaac..000000000 --- a/rustbook-en/2018-edition/src/ch16-02-message-passing.md +++ /dev/null @@ -1,10 +0,0 @@ -## Using Message Passing to Transfer Data Between Threads - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch16-02-message-passing.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch16-02-message-passing.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch16-03-shared-state.md b/rustbook-en/2018-edition/src/ch16-03-shared-state.md deleted file mode 100644 index 043aa25cd..000000000 --- a/rustbook-en/2018-edition/src/ch16-03-shared-state.md +++ /dev/null @@ -1,10 +0,0 @@ -## Shared-State Concurrency - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch16-03-shared-state.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch16-03-shared-state.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch16-04-extensible-concurrency-sync-and-send.md b/rustbook-en/2018-edition/src/ch16-04-extensible-concurrency-sync-and-send.md deleted file mode 100644 index 44a4a0b19..000000000 --- a/rustbook-en/2018-edition/src/ch16-04-extensible-concurrency-sync-and-send.md +++ /dev/null @@ -1,10 +0,0 @@ -## Extensible Concurrency with the `Sync` and `Send` Traits - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch16-04-extensible-concurrency-sync-and-send.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch16-04-extensible-concurrency-sync-and-send.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch17-00-oop.md b/rustbook-en/2018-edition/src/ch17-00-oop.md deleted file mode 100644 index c731bbc95..000000000 --- a/rustbook-en/2018-edition/src/ch17-00-oop.md +++ /dev/null @@ -1,10 +0,0 @@ -# Object Oriented Programming Features of Rust - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch17-00-oop.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch17-00-oop.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch17-01-what-is-oo.md b/rustbook-en/2018-edition/src/ch17-01-what-is-oo.md deleted file mode 100644 index ed1ec4013..000000000 --- a/rustbook-en/2018-edition/src/ch17-01-what-is-oo.md +++ /dev/null @@ -1,10 +0,0 @@ -## Characteristics of Object-Oriented Languages - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch17-01-what-is-oo.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch17-01-what-is-oo.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch17-02-trait-objects.md b/rustbook-en/2018-edition/src/ch17-02-trait-objects.md deleted file mode 100644 index 1999647aa..000000000 --- a/rustbook-en/2018-edition/src/ch17-02-trait-objects.md +++ /dev/null @@ -1,10 +0,0 @@ -## Using Trait Objects that Allow for Values of Different Types - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch17-02-trait-objects.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch17-02-trait-objects.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch17-03-oo-design-patterns.md b/rustbook-en/2018-edition/src/ch17-03-oo-design-patterns.md deleted file mode 100644 index 1b74425fe..000000000 --- a/rustbook-en/2018-edition/src/ch17-03-oo-design-patterns.md +++ /dev/null @@ -1,10 +0,0 @@ -## Implementing an Object-Oriented Design Pattern - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch17-03-oo-design-patterns.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch17-03-oo-design-patterns.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch18-00-patterns.md b/rustbook-en/2018-edition/src/ch18-00-patterns.md deleted file mode 100644 index f3da1f40d..000000000 --- a/rustbook-en/2018-edition/src/ch18-00-patterns.md +++ /dev/null @@ -1,10 +0,0 @@ -# Patterns and Matching - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch18-00-patterns.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch18-00-patterns.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch18-01-all-the-places-for-patterns.md b/rustbook-en/2018-edition/src/ch18-01-all-the-places-for-patterns.md deleted file mode 100644 index ccf388406..000000000 --- a/rustbook-en/2018-edition/src/ch18-01-all-the-places-for-patterns.md +++ /dev/null @@ -1,10 +0,0 @@ -## All the Places Patterns Can Be Used - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch18-01-all-the-places-for-patterns.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch18-01-all-the-places-for-patterns.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch18-02-refutability.md b/rustbook-en/2018-edition/src/ch18-02-refutability.md deleted file mode 100644 index a3e2bcff7..000000000 --- a/rustbook-en/2018-edition/src/ch18-02-refutability.md +++ /dev/null @@ -1,10 +0,0 @@ -## Refutability: Whether a Pattern Might Fail to Match - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch18-02-refutability.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch18-02-refutability.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch18-03-pattern-syntax.md b/rustbook-en/2018-edition/src/ch18-03-pattern-syntax.md deleted file mode 100644 index 0e0929e7b..000000000 --- a/rustbook-en/2018-edition/src/ch18-03-pattern-syntax.md +++ /dev/null @@ -1,10 +0,0 @@ -## Pattern Syntax - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch18-03-pattern-syntax.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch18-03-pattern-syntax.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch19-00-advanced-features.md b/rustbook-en/2018-edition/src/ch19-00-advanced-features.md deleted file mode 100644 index b34d6b9b6..000000000 --- a/rustbook-en/2018-edition/src/ch19-00-advanced-features.md +++ /dev/null @@ -1,10 +0,0 @@ -# Advanced Features - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-00-advanced-features.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-00-advanced-features.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch19-01-unsafe-rust.md b/rustbook-en/2018-edition/src/ch19-01-unsafe-rust.md deleted file mode 100644 index 34b569fee..000000000 --- a/rustbook-en/2018-edition/src/ch19-01-unsafe-rust.md +++ /dev/null @@ -1,10 +0,0 @@ -## Unsafe Rust - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-01-unsafe-rust.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-01-unsafe-rust.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch19-02-advanced-lifetimes.md b/rustbook-en/2018-edition/src/ch19-02-advanced-lifetimes.md deleted file mode 100644 index dd84b4627..000000000 --- a/rustbook-en/2018-edition/src/ch19-02-advanced-lifetimes.md +++ /dev/null @@ -1,10 +0,0 @@ -## Advanced Lifetimes - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-02-advanced-lifetimes.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch19-03-advanced-traits.md b/rustbook-en/2018-edition/src/ch19-03-advanced-traits.md deleted file mode 100644 index 4219b208b..000000000 --- a/rustbook-en/2018-edition/src/ch19-03-advanced-traits.md +++ /dev/null @@ -1,10 +0,0 @@ -## Advanced Traits - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-03-advanced-traits.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-03-advanced-traits.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch19-04-advanced-types.md b/rustbook-en/2018-edition/src/ch19-04-advanced-types.md deleted file mode 100644 index fecbd52dc..000000000 --- a/rustbook-en/2018-edition/src/ch19-04-advanced-types.md +++ /dev/null @@ -1,10 +0,0 @@ -## Advanced Types - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-04-advanced-types.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-04-advanced-types.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch19-05-advanced-functions-and-closures.md b/rustbook-en/2018-edition/src/ch19-05-advanced-functions-and-closures.md deleted file mode 100644 index 1bf045090..000000000 --- a/rustbook-en/2018-edition/src/ch19-05-advanced-functions-and-closures.md +++ /dev/null @@ -1,10 +0,0 @@ -## Advanced Functions and Closures - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-05-advanced-functions-and-closures.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-05-advanced-functions-and-closures.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch19-06-macros.md b/rustbook-en/2018-edition/src/ch19-06-macros.md deleted file mode 100644 index bf019c5d6..000000000 --- a/rustbook-en/2018-edition/src/ch19-06-macros.md +++ /dev/null @@ -1,10 +0,0 @@ -## Macros - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-06-macros.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch19-06-macros.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch20-00-final-project-a-web-server.md b/rustbook-en/2018-edition/src/ch20-00-final-project-a-web-server.md deleted file mode 100644 index f9b9e5c2d..000000000 --- a/rustbook-en/2018-edition/src/ch20-00-final-project-a-web-server.md +++ /dev/null @@ -1,10 +0,0 @@ -# Final Project: Building a Multithreaded Web Server - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch20-00-final-project-a-web-server.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch20-00-final-project-a-web-server.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch20-01-single-threaded.md b/rustbook-en/2018-edition/src/ch20-01-single-threaded.md deleted file mode 100644 index 30d0884ad..000000000 --- a/rustbook-en/2018-edition/src/ch20-01-single-threaded.md +++ /dev/null @@ -1,10 +0,0 @@ -## Building a Single-Threaded Web Server - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch20-01-single-threaded.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch20-01-single-threaded.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch20-02-multithreaded.md b/rustbook-en/2018-edition/src/ch20-02-multithreaded.md deleted file mode 100644 index e8b592ad2..000000000 --- a/rustbook-en/2018-edition/src/ch20-02-multithreaded.md +++ /dev/null @@ -1,10 +0,0 @@ -## Turning Our Single-Threaded Server into a Multithreaded Server - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch20-02-multithreaded.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch20-02-multithreaded.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/ch20-03-graceful-shutdown-and-cleanup.md b/rustbook-en/2018-edition/src/ch20-03-graceful-shutdown-and-cleanup.md deleted file mode 100644 index 928d199be..000000000 --- a/rustbook-en/2018-edition/src/ch20-03-graceful-shutdown-and-cleanup.md +++ /dev/null @@ -1,10 +0,0 @@ -## Graceful Shutdown and Cleanup - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch20-03-graceful-shutdown-and-cleanup.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/ch20-03-graceful-shutdown-and-cleanup.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/foreword.md b/rustbook-en/2018-edition/src/foreword.md deleted file mode 100644 index 3af707e35..000000000 --- a/rustbook-en/2018-edition/src/foreword.md +++ /dev/null @@ -1,10 +0,0 @@ -# Foreword - -The 2018 edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../foreword.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/2018-edition/foreword.html). \ No newline at end of file diff --git a/rustbook-en/2018-edition/src/img/ferris/does_not_compile.svg b/rustbook-en/2018-edition/src/img/ferris/does_not_compile.svg deleted file mode 100644 index 5d345f14e..000000000 --- a/rustbook-en/2018-edition/src/img/ferris/does_not_compile.svg +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rustbook-en/2018-edition/src/img/ferris/not_desired_behavior.svg b/rustbook-en/2018-edition/src/img/ferris/not_desired_behavior.svg deleted file mode 100644 index 47f402455..000000000 --- a/rustbook-en/2018-edition/src/img/ferris/not_desired_behavior.svg +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rustbook-en/2018-edition/src/img/ferris/panics.svg b/rustbook-en/2018-edition/src/img/ferris/panics.svg deleted file mode 100644 index be55f5e09..000000000 --- a/rustbook-en/2018-edition/src/img/ferris/panics.svg +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rustbook-en/2018-edition/src/img/ferris/unsafe.svg b/rustbook-en/2018-edition/src/img/ferris/unsafe.svg deleted file mode 100644 index d4fdc08dd..000000000 --- a/rustbook-en/2018-edition/src/img/ferris/unsafe.svg +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl04-01.svg b/rustbook-en/2018-edition/src/img/trpl04-01.svg deleted file mode 100644 index 314f53ba1..000000000 --- a/rustbook-en/2018-edition/src/img/trpl04-01.svg +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - -%3 - - - -table0 - -s1 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table1 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - - - -table0:c->table1:pointee - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl04-02.svg b/rustbook-en/2018-edition/src/img/trpl04-02.svg deleted file mode 100644 index 70d490f0b..000000000 --- a/rustbook-en/2018-edition/src/img/trpl04-02.svg +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - -%3 - - - -table0 - -s1 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table1 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - - - -table0:c->table1:pointee - - - - - -table3 - -s2 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table3:c->table1:pointee - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl04-03.svg b/rustbook-en/2018-edition/src/img/trpl04-03.svg deleted file mode 100644 index 7c153e23a..000000000 --- a/rustbook-en/2018-edition/src/img/trpl04-03.svg +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - -%3 - - - -table0 - -s2 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table1 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - - - -table0:c->table1:pointee - - - - - -table3 - -s1 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table4 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - - - -table3:c->table4:pointee - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl04-04.svg b/rustbook-en/2018-edition/src/img/trpl04-04.svg deleted file mode 100644 index a0513abd9..000000000 --- a/rustbook-en/2018-edition/src/img/trpl04-04.svg +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - -%3 - - - -table0 - - -s1 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table1 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - - - -table0:c->table1:pointee - - - - - -table3 - -s2 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table3:c->table1:pointee - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl04-05.svg b/rustbook-en/2018-edition/src/img/trpl04-05.svg deleted file mode 100644 index b4bf2ebee..000000000 --- a/rustbook-en/2018-edition/src/img/trpl04-05.svg +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - -%3 - - - -table0 - -s - -name - -value - -ptr - - - - -table1 - -s1 - -name - -value - -ptr - - -len - -5 - -capacity - -5 - - - -table0:c->table1:borrowee - - - - - -table2 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - - - -table1:c->table2:pointee - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl04-06.svg b/rustbook-en/2018-edition/src/img/trpl04-06.svg deleted file mode 100644 index e64415fe4..000000000 --- a/rustbook-en/2018-edition/src/img/trpl04-06.svg +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - -%3 - - - -table0 - -world - -name - -value - -ptr - - -len - -5 - - - -table4 - -index - -value - -0 - -h - -1 - -e - -2 - -l - -3 - -l - -4 - -o - -5 - - - -6 - -w - -7 - -o - -8 - -r - -9 - -l - -10 - -d - - - -table0:c->table4:pointee2 - - - - - -table3 - -s - -name - -value - -ptr - - -len - -11 - -capacity - -11 - - - -table3:c->table4:pointee - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl14-01.png b/rustbook-en/2018-edition/src/img/trpl14-01.png deleted file mode 100644 index 5fc59898c..000000000 Binary files a/rustbook-en/2018-edition/src/img/trpl14-01.png and /dev/null differ diff --git a/rustbook-en/2018-edition/src/img/trpl14-02.png b/rustbook-en/2018-edition/src/img/trpl14-02.png deleted file mode 100644 index 78e7e7ba7..000000000 Binary files a/rustbook-en/2018-edition/src/img/trpl14-02.png and /dev/null differ diff --git a/rustbook-en/2018-edition/src/img/trpl14-03.png b/rustbook-en/2018-edition/src/img/trpl14-03.png deleted file mode 100644 index ef8414507..000000000 Binary files a/rustbook-en/2018-edition/src/img/trpl14-03.png and /dev/null differ diff --git a/rustbook-en/2018-edition/src/img/trpl14-04.png b/rustbook-en/2018-edition/src/img/trpl14-04.png deleted file mode 100644 index d0ed2ca18..000000000 Binary files a/rustbook-en/2018-edition/src/img/trpl14-04.png and /dev/null differ diff --git a/rustbook-en/2018-edition/src/img/trpl15-01.svg b/rustbook-en/2018-edition/src/img/trpl15-01.svg deleted file mode 100644 index bbeef968a..000000000 --- a/rustbook-en/2018-edition/src/img/trpl15-01.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - -%3 - - - -table0 - -Cons - -i32 - - -Cons - -i32 - - -Cons - -i32 - - -Cons - -i32 - - -Cons - -i32 - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl15-02.svg b/rustbook-en/2018-edition/src/img/trpl15-02.svg deleted file mode 100644 index 4454df8c3..000000000 --- a/rustbook-en/2018-edition/src/img/trpl15-02.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - -%3 - - - -table0 - -Cons - -i32 - - -Box - -usize - - - diff --git a/rustbook-en/2018-edition/src/img/trpl15-03.svg b/rustbook-en/2018-edition/src/img/trpl15-03.svg deleted file mode 100644 index dbc3b5cdb..000000000 --- a/rustbook-en/2018-edition/src/img/trpl15-03.svg +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - -%3 - - - -table4 -b - - - -table5 - -3 - -   - - - -table4:c->table5:pte4 - - - - - -table1 - -5 - -   - - - -table5:c->table1:pte0 - - - - - -table0 -a - - - -table0:c->table1:pte0 - - - - - -table2 - -10 - -   - - - -table1:c->table2:pte1 - - - - - -table3 - -Nil - - - -table2:c->table3:pte2 - - - - - -table6 -c - - - -table7 - -4 - -   - - - -table6:c->table7:pte6 - - - - - -table7:c->table1:pte0 - - - - - diff --git a/rustbook-en/2018-edition/src/img/trpl15-04.svg b/rustbook-en/2018-edition/src/img/trpl15-04.svg deleted file mode 100644 index 96ad98ca1..000000000 --- a/rustbook-en/2018-edition/src/img/trpl15-04.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - -%3 - - -table0 - -a - - -table1 - -5 - - - - -table2 - -b - - -table3 - -10 - - - - -table0:ref->table1:data - - - - -table1:ref->table2:data - - - - -table2:ref->table3:data - - - - -table3:ref->table0:data - - - - - diff --git a/rustbook-en/COPYRIGHT b/rustbook-en/COPYRIGHT deleted file mode 100644 index 0fc3ea43f..000000000 --- a/rustbook-en/COPYRIGHT +++ /dev/null @@ -1,3 +0,0 @@ -This repository is licensed under the Apache License, Version 2.0 - or the MIT -license , at your option. diff --git a/rustbook-en/Cargo.lock b/rustbook-en/Cargo.lock deleted file mode 100644 index d54e8284e..000000000 --- a/rustbook-en/Cargo.lock +++ /dev/null @@ -1,392 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "crc32fast" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "docopt" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f3f119846c823f9eafcf953a8f6ffb6ed69bf6240883261a7f13b634579a51f" -dependencies = [ - "lazy_static", - "regex", - "serde", - "strsim", -] - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "filetime" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "windows-sys", -] - -[[package]] -name = "flate2" -version = "1.0.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - -[[package]] -name = "memchr" -version = "2.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" - -[[package]] -name = "miniz_oxide" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" -dependencies = [ - "adler", -] - -[[package]] -name = "proc-macro2" -version = "1.0.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "regex" -version = "1.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" - -[[package]] -name = "rust-book-tools" -version = "0.0.1" -dependencies = [ - "docopt", - "flate2", - "lazy_static", - "regex", - "serde", - "tar", - "walkdir", -] - -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "serde" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "2.0.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tar" -version = "0.4.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "unicode-ident" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "xattr" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" -dependencies = [ - "libc", - "linux-raw-sys", - "rustix", -] diff --git a/rustbook-en/Cargo.toml b/rustbook-en/Cargo.toml deleted file mode 100644 index 2bddb66f9..000000000 --- a/rustbook-en/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[workspace] -members = ["packages/tools"] -default-members = ["packages/tools"] -resolver = "2" -exclude = [ - "linkchecker", # linkchecker is part of the CI workflow - "listings", # these are intentionally distinct from the workspace - "tmp", # listings are built here when updating output via tools/update-rustc.sh - - # These are used as path dependencies in `rust-lang/rust` (since we are not - # publishing them to crates.io), so they cannot be part of this workspace, - # because path dependencies do not get built as a crate within the hosting - # workspace. - "packages/mdbook-trpl-listing", - "packages/mdbook-trpl-note", -] - -[workspace.dependencies] -walkdir = "2.3.1" -docopt = "1.1.0" -serde = "1.0" -regex = "1.3.3" -lazy_static = "1.4.0" -flate2 = "1.0.13" -tar = "0.4.26" diff --git a/rustbook-en/README.md b/rustbook-en/README.md deleted file mode 100644 index 8befc1b31..000000000 --- a/rustbook-en/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# The Rust Programming Language - -![Build Status](https://github.com/rust-lang/book/workflows/CI/badge.svg) - -This repository contains the source of "The Rust Programming Language" book. - -[The book is available in dead-tree form from No Starch Press][nostarch]. - -[nostarch]: https://nostarch.com/rust-programming-language-2nd-edition - -You can also read the book for free online. Please see the book as shipped with -the latest [stable], [beta], or [nightly] Rust releases. Be aware that issues -in those versions may have been fixed in this repository already, as those -releases are updated less frequently. - -[stable]: https://doc.rust-lang.org/stable/book/ -[beta]: https://doc.rust-lang.org/beta/book/ -[nightly]: https://doc.rust-lang.org/nightly/book/ - -See the [releases] to download just the code of all the code listings that appear in the book. - -[releases]: https://github.com/rust-lang/book/releases - -## Requirements - -Building the book requires [mdBook], ideally the same version that -rust-lang/rust uses in [this file][rust-mdbook]. To get it: - -[mdBook]: https://github.com/rust-lang/mdBook -[rust-mdbook]: https://github.com/rust-lang/rust/blob/master/src/tools/rustbook/Cargo.toml - -```bash -$ cargo install mdbook --locked --version -``` - -## Building - -To build the book, type: - -```bash -$ mdbook build -``` - -The output will be in the `book` subdirectory. To check it out, open it in -your web browser. - -_Firefox:_ -```bash -$ firefox book/index.html # Linux -$ open -a "Firefox" book/index.html # OS X -$ Start-Process "firefox.exe" .\book\index.html # Windows (PowerShell) -$ start firefox.exe .\book\index.html # Windows (Cmd) -``` - -_Chrome:_ -```bash -$ google-chrome book/index.html # Linux -$ open -a "Google Chrome" book/index.html # OS X -$ Start-Process "chrome.exe" .\book\index.html # Windows (PowerShell) -$ start chrome.exe .\book\index.html # Windows (Cmd) -``` - -To run the tests: - -```bash -$ mdbook test -``` - -## Contributing - -We'd love your help! Please see [CONTRIBUTING.md][contrib] to learn about the -kinds of contributions we're looking for. - -[contrib]: https://github.com/rust-lang/book/blob/main/CONTRIBUTING.md - -Because the book is [printed][nostarch], and because we want -to keep the online version of the book close to the print version when -possible, it may take longer than you're used to for us to address your issue -or pull request. - -So far, we've been doing a larger revision to coincide with [Rust -Editions](https://doc.rust-lang.org/edition-guide/). Between those larger -revisions, we will only be correcting errors. If your issue or pull request -isn't strictly fixing an error, it might sit until the next time that we're -working on a large revision: expect on the order of months or years. Thank you -for your patience! - -### Translations - -We'd love help translating the book! See the [Translations] label to join in -efforts that are currently in progress. Open a new issue to start working on -a new language! We're waiting on [mdbook support] for multiple languages -before we merge any in, but feel free to start! - -[Translations]: https://github.com/rust-lang/book/issues?q=is%3Aopen+is%3Aissue+label%3ATranslations -[mdbook support]: https://github.com/rust-lang/mdBook/issues/5 - -## Spellchecking - -To scan source files for spelling errors, you can use the `spellcheck.sh` -script available in the `ci` directory. It needs a dictionary of valid words, -which is provided in `ci/dictionary.txt`. If the script produces a false -positive (say, you used the word `BTreeMap` which the script considers invalid), -you need to add this word to `ci/dictionary.txt` (keep the sorted order for -consistency). diff --git a/rustbook-en/book.toml b/rustbook-en/book.toml deleted file mode 100644 index 800adcf0f..000000000 --- a/rustbook-en/book.toml +++ /dev/null @@ -1,20 +0,0 @@ -# Sync any changes to this *other than where explicitly specified* with the copy -# in `nostarch/book.toml`! - -[book] -title = "The Rust Programming Language" -authors = ["Steve Klabnik", "Carol Nichols", "Contributions from the Rust Community"] - -[output.html] -additional-css = ["ferris.css", "theme/2018-edition.css", "theme/semantic-notes.css", "theme/listing.css"] -additional-js = ["ferris.js"] -git-repository-url = "https://github.com/rust-lang/book" - -# Do not sync this preprocessor; it is for the HTML renderer only. -[preprocessor.trpl-note] - -[preprocessor.trpl-listing] -output-mode = "default" - -[rust] -edition = "2021" diff --git a/rustbook-en/dot/trpl04-01.dot b/rustbook-en/dot/trpl04-01.dot deleted file mode 100644 index 331d59133..000000000 --- a/rustbook-en/dot/trpl04-01.dot +++ /dev/null @@ -1,26 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - - - - -
s1
namevalue
ptr
len5
capacity5
>]; - table1[label=< - - - - - - -
indexvalue
0h
1e
2l
3l
4o
>]; - - edge[tailclip="false"]; - table0:pointer:c -> table1:pointee; -} - diff --git a/rustbook-en/dot/trpl04-02.dot b/rustbook-en/dot/trpl04-02.dot deleted file mode 100644 index e46d2ed4a..000000000 --- a/rustbook-en/dot/trpl04-02.dot +++ /dev/null @@ -1,35 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - - - - -
s1
namevalue
ptr
len5
capacity5
>]; - table3[label=< - - - - - -
s2
namevalue
ptr
len5
capacity5
>]; - - table1[label=< - - - - - - -
indexvalue
0h
1e
2l
3l
4o
>]; - - edge[tailclip="false"]; - table0:pointer:c -> table1:pointee; - table3:pointer:c -> table1:pointee; -} - diff --git a/rustbook-en/dot/trpl04-03.dot b/rustbook-en/dot/trpl04-03.dot deleted file mode 100644 index 16c0b2860..000000000 --- a/rustbook-en/dot/trpl04-03.dot +++ /dev/null @@ -1,44 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - - - - -
s2
namevalue
ptr
len5
capacity5
>]; - table1[label=< - - - - - - -
indexvalue
0h
1e
2l
3l
4o
>]; - - table3[label=< - - - - - -
s1
namevalue
ptr
len5
capacity5
>]; - table4[label=< - - - - - - -
indexvalue
0h
1e
2l
3l
4o
>]; - - - edge[tailclip="false"]; - table0:pointer:c -> table1:pointee; - table3:pointer:c -> table4:pointee; -} - diff --git a/rustbook-en/dot/trpl04-04.dot b/rustbook-en/dot/trpl04-04.dot deleted file mode 100644 index 1c95c231c..000000000 --- a/rustbook-en/dot/trpl04-04.dot +++ /dev/null @@ -1,35 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - - - - -
s1
namevalue
ptr
len5
capacity5
>]; - table3[label=< - - - - - -
s2
namevalue
ptr
len5
capacity5
>]; - - table1[label=< - - - - - - -
indexvalue
0h
1e
2l
3l
4o
>]; - - edge[tailclip="false"]; - table0:pointer:c -> table1:pointee; - table3:pointer:c -> table1:pointee; -} - diff --git a/rustbook-en/dot/trpl04-05.dot b/rustbook-en/dot/trpl04-05.dot deleted file mode 100644 index ca1f7e06e..000000000 --- a/rustbook-en/dot/trpl04-05.dot +++ /dev/null @@ -1,32 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - - -
s
namevalue
ptr
>]; - table1[label=< - - - - - -
s1
namevalue
ptr
len5
capacity5
>]; - table2[label=< - - - - - - -
indexvalue
0h
1e
2l
3l
4o
>]; - - edge[tailclip="false"]; - table1:pointer:c -> table2:pointee; - table0:borrower:c -> table1:borrowee; -} - diff --git a/rustbook-en/dot/trpl04-06.dot b/rustbook-en/dot/trpl04-06.dot deleted file mode 100644 index a23f179a7..000000000 --- a/rustbook-en/dot/trpl04-06.dot +++ /dev/null @@ -1,41 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - - - -
world
namevalue
ptr
len5
>]; - - table3[label=< - - - - - -
s
namevalue
ptr
len11
capacity11
>]; - table4[label=< - - - - - - - - - - - - -
indexvalue
0h
1e
2l
3l
4o
5
6w
7o
8r
9l
10d
>]; - - - edge[tailclip="false"]; - table0:pointer2:c -> table4:pointee2; - table3:pointer:c -> table4:pointee; -} - diff --git a/rustbook-en/dot/trpl15-01.dot b/rustbook-en/dot/trpl15-01.dot deleted file mode 100644 index e8b95f9a3..000000000 --- a/rustbook-en/dot/trpl15-01.dot +++ /dev/null @@ -1,24 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - -
Cons
i32 - - -
Cons
i32 - - -
Cons
i32 - - -
Cons
i32 - - -
Cons
i32
>]; -} - diff --git a/rustbook-en/dot/trpl15-02.dot b/rustbook-en/dot/trpl15-02.dot deleted file mode 100644 index f7dfd22c9..000000000 --- a/rustbook-en/dot/trpl15-02.dot +++ /dev/null @@ -1,18 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table0[label=< - - - -
Cons
i32 - - - -
Box
usize
-
>]; -} - diff --git a/rustbook-en/dot/trpl15-03.dot b/rustbook-en/dot/trpl15-03.dot deleted file mode 100644 index 16f026814..000000000 --- a/rustbook-en/dot/trpl15-03.dot +++ /dev/null @@ -1,51 +0,0 @@ -digraph { - rankdir=LR; - overlap=false; - dpi=300.0; - node [shape="plaintext"]; - - table4[label=< - -
b
>]; - - table5[label=< - -
3
>]; - - - table0[label=< - -
a
>]; - - table1[label=< - -
5
>]; - - table2[label=< - -
10
>]; - - table3[label=< - -
Nil
>]; - - - table6[label=< - -
c
>]; - - table7[label=< - -
4
>]; - - - edge[tailclip="false"]; - table0:ptr0:c -> table1:pte0; - table1:ptr1:c -> table2:pte1; - table2:ptr2:c -> table3:pte2; - table4:ptr4:c -> table5:pte4; - table5:ptr5:c -> table1:pte0; - table6:ptr6:c -> table7:pte6; - table7:ptr7:c -> table1:pte0; -} - diff --git a/rustbook-en/ferris.css b/rustbook-en/ferris.css deleted file mode 100644 index fb4a553ff..000000000 --- a/rustbook-en/ferris.css +++ /dev/null @@ -1,45 +0,0 @@ -body.light .does_not_compile, -body.light .panics, -body.light .not_desired_behavior, -body.rust .does_not_compile, -body.rust .panics, -body.rust .not_desired_behavior { - background: #fff1f1; -} - -body.coal .does_not_compile, -body.coal .panics, -body.coal .not_desired_behavior, -body.navy .does_not_compile, -body.navy .panics, -body.navy .not_desired_behavior, -body.ayu .does_not_compile, -body.ayu .panics, -body.ayu .not_desired_behavior { - background: #501f21; -} - -.ferris-container { - position: absolute; - z-index: 99; - right: 5px; - top: 30px; -} - -.ferris { - vertical-align: top; - margin-left: 0.2em; - height: auto; -} - -.ferris-large { - width: 4.5em; -} - -.ferris-small { - width: 2.3em; -} - -.ferris-explain { - width: 100px; -} diff --git a/rustbook-en/ferris.js b/rustbook-en/ferris.js deleted file mode 100644 index 51e5b12a9..000000000 --- a/rustbook-en/ferris.js +++ /dev/null @@ -1,100 +0,0 @@ -// @ts-check - -/** - * @typedef {{ attr: string, title: string }} FerrisType - */ - -/** @type {Array} */ -const FERRIS_TYPES = [ - { - attr: 'does_not_compile', - title: 'This code does not compile!' - }, - { - attr: 'panics', - title: 'This code panics!' - }, - { - attr: 'not_desired_behavior', - title: 'This code does not produce the desired behavior.' - } -] - -document.addEventListener('DOMContentLoaded', () => { - for (let ferrisType of FERRIS_TYPES) { - attachFerrises(ferrisType) - } -}) - -/** - * @param {FerrisType} type - */ -function attachFerrises(type) { - let elements = document.getElementsByClassName(type.attr) - - for (let codeBlock of elements) { - // Skip SVG etc.: in principle, these should never be attached to those, but - // this means if someone happens to have a browser extension which *is* - // attaching them, it will not break the code. - if (!(codeBlock instanceof HTMLElement)) { - continue - } - - let lines = codeBlock.innerText.replace(/\n$/, '').split(/\n/).length - - /** @type {'small' | 'large'} */ - let size = lines < 4 ? 'small' : 'large' - - let container = prepareFerrisContainer(codeBlock, size == 'small') - if (!container) { - continue - } - - container.appendChild(createFerris(type, size)) - } -} - -/** - * @param {HTMLElement} element - Code block element to attach a Ferris to. - * @param {boolean} useButtons - Whether to attach to existing buttons. - * @returns {Element | null} - The container element to use. - */ -function prepareFerrisContainer(element, useButtons) { - let foundButtons = element.parentElement?.querySelector('.buttons') - if (useButtons && foundButtons) { - return foundButtons - } - - let div = document.createElement('div') - div.classList.add('ferris-container') - - if (!element.parentElement) { - console.error(`Could not install Ferris on ${element}, which is missing a parent`); - return null; - } - - element.parentElement.insertBefore(div, element) - - return div -} - -/** - * @param {FerrisType} type - * @param {'small' | 'large'} size - * @returns {HTMLAnchorElement} - The generated anchor element. - */ -function createFerris(type, size) { - let a = document.createElement('a') - a.setAttribute('href', 'ch00-00-introduction.html#ferris') - a.setAttribute('target', '_blank') - - let img = document.createElement('img') - img.setAttribute('src', 'img/ferris/' + type.attr + '.svg') - img.setAttribute('title', type.title) - img.classList.add('ferris') - img.classList.add('ferris-' + size) - - a.appendChild(img) - - return a -} diff --git a/rustbook-en/first-edition/book.toml b/rustbook-en/first-edition/book.toml deleted file mode 100644 index 3a3189c4d..000000000 --- a/rustbook-en/first-edition/book.toml +++ /dev/null @@ -1,3 +0,0 @@ -[book] -title = "The Rust Programming Language" -author = "The Rust Project Developers" diff --git a/rustbook-en/first-edition/src/README.md b/rustbook-en/first-edition/src/README.md deleted file mode 100644 index 31babb298..000000000 --- a/rustbook-en/first-edition/src/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# The Rust Programming Language - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/README.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/SUMMARY.md b/rustbook-en/first-edition/src/SUMMARY.md deleted file mode 100644 index c3763cdf9..000000000 --- a/rustbook-en/first-edition/src/SUMMARY.md +++ /dev/null @@ -1,60 +0,0 @@ -# Summary - -[Introduction](README.md) - -* [Getting Started](getting-started.md) -* [Tutorial: Guessing Game](guessing-game.md) -* [Syntax and Semantics](syntax-and-semantics.md) - * [Variable Bindings](variable-bindings.md) - * [Functions](functions.md) - * [Primitive Types](primitive-types.md) - * [Comments](comments.md) - * [if](if.md) - * [Loops](loops.md) - * [Vectors](vectors.md) - * [Ownership](ownership.md) - * [References and Borrowing](references-and-borrowing.md) - * [Lifetimes](lifetimes.md) - * [Mutability](mutability.md) - * [Structs](structs.md) - * [Enums](enums.md) - * [Match](match.md) - * [Patterns](patterns.md) - * [Method Syntax](method-syntax.md) - * [Strings](strings.md) - * [Generics](generics.md) - * [Traits](traits.md) - * [Drop](drop.md) - * [if let](if-let.md) - * [Trait Objects](trait-objects.md) - * [Closures](closures.md) - * [Universal Function Call Syntax](ufcs.md) - * [Crates and Modules](crates-and-modules.md) - * [`const` and `static`](const-and-static.md) - * [Attributes](attributes.md) - * [`type` aliases](type-aliases.md) - * [Casting between types](casting-between-types.md) - * [Associated Types](associated-types.md) - * [Unsized Types](unsized-types.md) - * [Operators and Overloading](operators-and-overloading.md) - * [Deref coercions](deref-coercions.md) - * [Macros](macros.md) - * [Raw Pointers](raw-pointers.md) - * [`unsafe`](unsafe.md) -* [Effective Rust](effective-rust.md) - * [The Stack and the Heap](the-stack-and-the-heap.md) - * [Testing](testing.md) - * [Conditional Compilation](conditional-compilation.md) - * [Documentation](documentation.md) - * [Iterators](iterators.md) - * [Concurrency](concurrency.md) - * [Error Handling](error-handling.md) - * [Choosing your Guarantees](choosing-your-guarantees.md) - * [FFI](ffi.md) - * [Borrow and AsRef](borrow-and-asref.md) - * [Release Channels](release-channels.md) - * [Using Rust without the standard library](using-rust-without-the-standard-library.md) - * [Procedural Macros (and custom derive)](procedural-macros.md) -* [Glossary](glossary.md) -* [Syntax Index](syntax-index.md) -* [Bibliography](bibliography.md) diff --git a/rustbook-en/first-edition/src/associated-types.md b/rustbook-en/first-edition/src/associated-types.md deleted file mode 100644 index 626048e9e..000000000 --- a/rustbook-en/first-edition/src/associated-types.md +++ /dev/null @@ -1,10 +0,0 @@ -# Associated Types - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-03-advanced-traits.html#specifying-placeholder-types-in-trait-definitions-with-associated-types) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/associated-types.html). diff --git a/rustbook-en/first-edition/src/attributes.md b/rustbook-en/first-edition/src/attributes.md deleted file mode 100644 index b39fcdd67..000000000 --- a/rustbook-en/first-edition/src/attributes.md +++ /dev/null @@ -1,10 +0,0 @@ -# Attributes - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/attributes.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/bibliography.md b/rustbook-en/first-edition/src/bibliography.md deleted file mode 100644 index 9609068fd..000000000 --- a/rustbook-en/first-edition/src/bibliography.md +++ /dev/null @@ -1,10 +0,0 @@ -# Bibliography - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/bibliography.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/borrow-and-asref.md b/rustbook-en/first-edition/src/borrow-and-asref.md deleted file mode 100644 index a088bc8d7..000000000 --- a/rustbook-en/first-edition/src/borrow-and-asref.md +++ /dev/null @@ -1,10 +0,0 @@ -# Borrow and AsRef - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-00-smart-pointers.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/borrow-and-asref.html). diff --git a/rustbook-en/first-edition/src/casting-between-types.md b/rustbook-en/first-edition/src/casting-between-types.md deleted file mode 100644 index 34d4e84e5..000000000 --- a/rustbook-en/first-edition/src/casting-between-types.md +++ /dev/null @@ -1,10 +0,0 @@ -# Casting Between Types - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/casting-between-types.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/choosing-your-guarantees.md b/rustbook-en/first-edition/src/choosing-your-guarantees.md deleted file mode 100644 index 9e56d9da2..000000000 --- a/rustbook-en/first-edition/src/choosing-your-guarantees.md +++ /dev/null @@ -1,10 +0,0 @@ -# Choosing your Guarantees - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-00-smart-pointers.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/choosing-your-guarantees.html). diff --git a/rustbook-en/first-edition/src/closures.md b/rustbook-en/first-edition/src/closures.md deleted file mode 100644 index 3852e28f5..000000000 --- a/rustbook-en/first-edition/src/closures.md +++ /dev/null @@ -1,10 +0,0 @@ -# Closures - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch13-01-closures.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/closures.html). diff --git a/rustbook-en/first-edition/src/comments.md b/rustbook-en/first-edition/src/comments.md deleted file mode 100644 index cf56cd67b..000000000 --- a/rustbook-en/first-edition/src/comments.md +++ /dev/null @@ -1,10 +0,0 @@ -# Comments - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-04-comments.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/comments.html). diff --git a/rustbook-en/first-edition/src/concurrency.md b/rustbook-en/first-edition/src/concurrency.md deleted file mode 100644 index adb6e85b8..000000000 --- a/rustbook-en/first-edition/src/concurrency.md +++ /dev/null @@ -1,10 +0,0 @@ -# Concurrency - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch16-00-concurrency.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/concurrency.html). diff --git a/rustbook-en/first-edition/src/conditional-compilation.md b/rustbook-en/first-edition/src/conditional-compilation.md deleted file mode 100644 index 80184ba3e..000000000 --- a/rustbook-en/first-edition/src/conditional-compilation.md +++ /dev/null @@ -1,10 +0,0 @@ -# Conditional Compilation - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/conditional-compilation.html). diff --git a/rustbook-en/first-edition/src/const-and-static.md b/rustbook-en/first-edition/src/const-and-static.md deleted file mode 100644 index aa634112b..000000000 --- a/rustbook-en/first-edition/src/const-and-static.md +++ /dev/null @@ -1,10 +0,0 @@ -# const and static - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-01-unsafe-rust.html#accessing-or-modifying-a-mutable-static-variable) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/const-and-static.html). diff --git a/rustbook-en/first-edition/src/crates-and-modules.md b/rustbook-en/first-edition/src/crates-and-modules.md deleted file mode 100644 index 66262b340..000000000 --- a/rustbook-en/first-edition/src/crates-and-modules.md +++ /dev/null @@ -1,10 +0,0 @@ -# Crates and Modules - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch07-00-managing-growing-projects-with-packages-crates-and-modules.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/crates-and-modules.html). diff --git a/rustbook-en/first-edition/src/deref-coercions.md b/rustbook-en/first-edition/src/deref-coercions.md deleted file mode 100644 index 1e43ff453..000000000 --- a/rustbook-en/first-edition/src/deref-coercions.md +++ /dev/null @@ -1,10 +0,0 @@ -# `Deref` coercions - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/deref-coercions.html). diff --git a/rustbook-en/first-edition/src/documentation.md b/rustbook-en/first-edition/src/documentation.md deleted file mode 100644 index ac9ecba80..000000000 --- a/rustbook-en/first-edition/src/documentation.md +++ /dev/null @@ -1,10 +0,0 @@ -# Documentation - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch14-02-publishing-to-crates-io.html#making-useful-documentation-comments) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/documentation.html). diff --git a/rustbook-en/first-edition/src/drop.md b/rustbook-en/first-edition/src/drop.md deleted file mode 100644 index 1abde150e..000000000 --- a/rustbook-en/first-edition/src/drop.md +++ /dev/null @@ -1,10 +0,0 @@ -# Drop - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch15-03-drop.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/drop.html). diff --git a/rustbook-en/first-edition/src/effective-rust.md b/rustbook-en/first-edition/src/effective-rust.md deleted file mode 100644 index 1087c6541..000000000 --- a/rustbook-en/first-edition/src/effective-rust.md +++ /dev/null @@ -1,10 +0,0 @@ -# Effective Rust - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/effective-rust.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/enums.md b/rustbook-en/first-edition/src/enums.md deleted file mode 100644 index e26e19820..000000000 --- a/rustbook-en/first-edition/src/enums.md +++ /dev/null @@ -1,10 +0,0 @@ -# Enums - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch06-01-defining-an-enum.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/enums.html). diff --git a/rustbook-en/first-edition/src/error-handling.md b/rustbook-en/first-edition/src/error-handling.md deleted file mode 100644 index 35b780ae7..000000000 --- a/rustbook-en/first-edition/src/error-handling.md +++ /dev/null @@ -1,10 +0,0 @@ -# Error Handling - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch09-00-error-handling.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/error-handling.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/ffi.md b/rustbook-en/first-edition/src/ffi.md deleted file mode 100644 index 2adaff9d8..000000000 --- a/rustbook-en/first-edition/src/ffi.md +++ /dev/null @@ -1,10 +0,0 @@ -# Foreign Function Interface - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-01-unsafe-rust.html#calling-rust-functions-from-other-languages) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/ffi.html). diff --git a/rustbook-en/first-edition/src/functions.md b/rustbook-en/first-edition/src/functions.md deleted file mode 100644 index b6af0f670..000000000 --- a/rustbook-en/first-edition/src/functions.md +++ /dev/null @@ -1,10 +0,0 @@ -# Functions - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-03-how-functions-work.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/functions.html). diff --git a/rustbook-en/first-edition/src/generics.md b/rustbook-en/first-edition/src/generics.md deleted file mode 100644 index 953ba03e2..000000000 --- a/rustbook-en/first-edition/src/generics.md +++ /dev/null @@ -1,10 +0,0 @@ -# Generics - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch10-00-generics.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/generics.html). diff --git a/rustbook-en/first-edition/src/getting-started.md b/rustbook-en/first-edition/src/getting-started.md deleted file mode 100644 index cd3ccf775..000000000 --- a/rustbook-en/first-edition/src/getting-started.md +++ /dev/null @@ -1,10 +0,0 @@ -# Getting Started - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch00-00-introduction.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/getting-started.html). diff --git a/rustbook-en/first-edition/src/glossary.md b/rustbook-en/first-edition/src/glossary.md deleted file mode 100644 index 03a2833e4..000000000 --- a/rustbook-en/first-edition/src/glossary.md +++ /dev/null @@ -1,10 +0,0 @@ -# Glossary - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/glossary.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/guessing-game.md b/rustbook-en/first-edition/src/guessing-game.md deleted file mode 100644 index 3191cc972..000000000 --- a/rustbook-en/first-edition/src/guessing-game.md +++ /dev/null @@ -1,10 +0,0 @@ -# Guessing Game - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch02-00-guessing-game-tutorial.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/guessing-game.html). diff --git a/rustbook-en/first-edition/src/if-let.md b/rustbook-en/first-edition/src/if-let.md deleted file mode 100644 index b4a95d24f..000000000 --- a/rustbook-en/first-edition/src/if-let.md +++ /dev/null @@ -1,10 +0,0 @@ -# if let - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch06-03-if-let.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/if-let.html). diff --git a/rustbook-en/first-edition/src/if.md b/rustbook-en/first-edition/src/if.md deleted file mode 100644 index bd8f8e6c7..000000000 --- a/rustbook-en/first-edition/src/if.md +++ /dev/null @@ -1,10 +0,0 @@ -# if - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-05-control-flow.html#if-expressions) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/if.html). diff --git a/rustbook-en/first-edition/src/iterators.md b/rustbook-en/first-edition/src/iterators.md deleted file mode 100644 index d4dbd1e29..000000000 --- a/rustbook-en/first-edition/src/iterators.md +++ /dev/null @@ -1,10 +0,0 @@ -# Iterators - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch13-02-iterators.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/iterators.html). diff --git a/rustbook-en/first-edition/src/lifetimes.md b/rustbook-en/first-edition/src/lifetimes.md deleted file mode 100644 index 2208c966e..000000000 --- a/rustbook-en/first-edition/src/lifetimes.md +++ /dev/null @@ -1,10 +0,0 @@ -# Lifetimes - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch10-03-lifetime-syntax.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/lifetimes.html). diff --git a/rustbook-en/first-edition/src/loops.md b/rustbook-en/first-edition/src/loops.md deleted file mode 100644 index 07ecd3342..000000000 --- a/rustbook-en/first-edition/src/loops.md +++ /dev/null @@ -1,10 +0,0 @@ -# Loops - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-05-control-flow.html#repetition-with-loops) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/loops.html). diff --git a/rustbook-en/first-edition/src/macros.md b/rustbook-en/first-edition/src/macros.md deleted file mode 100644 index 6bafdc1e4..000000000 --- a/rustbook-en/first-edition/src/macros.md +++ /dev/null @@ -1,10 +0,0 @@ -# Macros - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-06-macros.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/macros.html). diff --git a/rustbook-en/first-edition/src/match.md b/rustbook-en/first-edition/src/match.md deleted file mode 100644 index b9808193e..000000000 --- a/rustbook-en/first-edition/src/match.md +++ /dev/null @@ -1,10 +0,0 @@ -# Match - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch06-02-match.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/match.html). diff --git a/rustbook-en/first-edition/src/method-syntax.md b/rustbook-en/first-edition/src/method-syntax.md deleted file mode 100644 index 74c232bf9..000000000 --- a/rustbook-en/first-edition/src/method-syntax.md +++ /dev/null @@ -1,10 +0,0 @@ -# Method Syntax - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch05-03-method-syntax.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/method-syntax.html). diff --git a/rustbook-en/first-edition/src/mutability.md b/rustbook-en/first-edition/src/mutability.md deleted file mode 100644 index 2f557de1d..000000000 --- a/rustbook-en/first-edition/src/mutability.md +++ /dev/null @@ -1,10 +0,0 @@ -# Mutability - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-01-variables-and-mutability.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/mutability.html). diff --git a/rustbook-en/first-edition/src/operators-and-overloading.md b/rustbook-en/first-edition/src/operators-and-overloading.md deleted file mode 100644 index 921a2a685..000000000 --- a/rustbook-en/first-edition/src/operators-and-overloading.md +++ /dev/null @@ -1,10 +0,0 @@ -# Operators and Overloading - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-03-advanced-traits.html#default-generic-type-parameters-and-operator-overloading) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/operators-and-overloading.html). diff --git a/rustbook-en/first-edition/src/ownership.md b/rustbook-en/first-edition/src/ownership.md deleted file mode 100644 index 70fbe4847..000000000 --- a/rustbook-en/first-edition/src/ownership.md +++ /dev/null @@ -1,10 +0,0 @@ -# Ownership - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch04-00-understanding-ownership.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/ownership.html). diff --git a/rustbook-en/first-edition/src/patterns.md b/rustbook-en/first-edition/src/patterns.md deleted file mode 100644 index d722d397e..000000000 --- a/rustbook-en/first-edition/src/patterns.md +++ /dev/null @@ -1,10 +0,0 @@ -# Patterns - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch18-03-pattern-syntax.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/patterns.html). diff --git a/rustbook-en/first-edition/src/primitive-types.md b/rustbook-en/first-edition/src/primitive-types.md deleted file mode 100644 index 39ee0b2d1..000000000 --- a/rustbook-en/first-edition/src/primitive-types.md +++ /dev/null @@ -1,10 +0,0 @@ -# Primitive Types - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-02-data-types.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/primitive-types.html). diff --git a/rustbook-en/first-edition/src/procedural-macros.md b/rustbook-en/first-edition/src/procedural-macros.md deleted file mode 100644 index 9778383d8..000000000 --- a/rustbook-en/first-edition/src/procedural-macros.md +++ /dev/null @@ -1,10 +0,0 @@ -# Procedural Macros (and custom Derive) - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-06-macros.html?highlight=procedural#procedural-macros-for-generating-code-from-attributes) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/procedural-macros.html). diff --git a/rustbook-en/first-edition/src/raw-pointers.md b/rustbook-en/first-edition/src/raw-pointers.md deleted file mode 100644 index c149da868..000000000 --- a/rustbook-en/first-edition/src/raw-pointers.md +++ /dev/null @@ -1,10 +0,0 @@ -# Raw Pointers - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/raw-pointers.html). diff --git a/rustbook-en/first-edition/src/references-and-borrowing.md b/rustbook-en/first-edition/src/references-and-borrowing.md deleted file mode 100644 index 1d8c75e2d..000000000 --- a/rustbook-en/first-edition/src/references-and-borrowing.md +++ /dev/null @@ -1,10 +0,0 @@ -# References and Borrowing - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch04-02-references-and-borrowing.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/references-and-borrowing.html). diff --git a/rustbook-en/first-edition/src/release-channels.md b/rustbook-en/first-edition/src/release-channels.md deleted file mode 100644 index f0a643f27..000000000 --- a/rustbook-en/first-edition/src/release-channels.md +++ /dev/null @@ -1,10 +0,0 @@ -# Release Channels - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/release-channels.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/strings.md b/rustbook-en/first-edition/src/strings.md deleted file mode 100644 index f7648cde5..000000000 --- a/rustbook-en/first-edition/src/strings.md +++ /dev/null @@ -1,10 +0,0 @@ -# Strings - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch08-02-strings.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/strings.html). diff --git a/rustbook-en/first-edition/src/structs.md b/rustbook-en/first-edition/src/structs.md deleted file mode 100644 index acfcdaf51..000000000 --- a/rustbook-en/first-edition/src/structs.md +++ /dev/null @@ -1,10 +0,0 @@ -# Structs - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch05-00-structs.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/structs.html). diff --git a/rustbook-en/first-edition/src/syntax-and-semantics.md b/rustbook-en/first-edition/src/syntax-and-semantics.md deleted file mode 100644 index 62740385c..000000000 --- a/rustbook-en/first-edition/src/syntax-and-semantics.md +++ /dev/null @@ -1,10 +0,0 @@ -# Syntax and Semantics - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch03-00-common-programming-concepts.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/syntax-and-semantics.html). diff --git a/rustbook-en/first-edition/src/syntax-index.md b/rustbook-en/first-edition/src/syntax-index.md deleted file mode 100644 index a2ab62cac..000000000 --- a/rustbook-en/first-edition/src/syntax-index.md +++ /dev/null @@ -1,10 +0,0 @@ -# Syntax Index - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/syntax-index.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/testing.md b/rustbook-en/first-edition/src/testing.md deleted file mode 100644 index d59418979..000000000 --- a/rustbook-en/first-edition/src/testing.md +++ /dev/null @@ -1,10 +0,0 @@ -# Testing - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch11-00-testing.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/testing.html). diff --git a/rustbook-en/first-edition/src/the-stack-and-the-heap.md b/rustbook-en/first-edition/src/the-stack-and-the-heap.md deleted file mode 100644 index 5c53af356..000000000 --- a/rustbook-en/first-edition/src/the-stack-and-the-heap.md +++ /dev/null @@ -1,10 +0,0 @@ -# The Stack and the Heap - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch04-01-what-is-ownership.html#the-stack-and-the-heap) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/the-stack-and-the-heap.html). diff --git a/rustbook-en/first-edition/src/trait-objects.md b/rustbook-en/first-edition/src/trait-objects.md deleted file mode 100644 index 871bad614..000000000 --- a/rustbook-en/first-edition/src/trait-objects.md +++ /dev/null @@ -1,10 +0,0 @@ -# Trait Objects - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch17-02-trait-objects.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/trait-objects.html). diff --git a/rustbook-en/first-edition/src/traits.md b/rustbook-en/first-edition/src/traits.md deleted file mode 100644 index 955776a74..000000000 --- a/rustbook-en/first-edition/src/traits.md +++ /dev/null @@ -1,10 +0,0 @@ -# Traits - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch10-02-traits.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/traits.html). diff --git a/rustbook-en/first-edition/src/type-aliases.md b/rustbook-en/first-edition/src/type-aliases.md deleted file mode 100644 index 7ac51ff19..000000000 --- a/rustbook-en/first-edition/src/type-aliases.md +++ /dev/null @@ -1,10 +0,0 @@ -# Type Aliases - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-04-advanced-types.html#creating-type-synonyms-with-type-aliases) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/type-aliases.html). diff --git a/rustbook-en/first-edition/src/ufcs.md b/rustbook-en/first-edition/src/ufcs.md deleted file mode 100644 index dad121ab3..000000000 --- a/rustbook-en/first-edition/src/ufcs.md +++ /dev/null @@ -1,10 +0,0 @@ -# Universal Function Call Syntax - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/ufcs.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/unsafe.md b/rustbook-en/first-edition/src/unsafe.md deleted file mode 100644 index be816dfd3..000000000 --- a/rustbook-en/first-edition/src/unsafe.md +++ /dev/null @@ -1,10 +0,0 @@ -# Unsafe - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-01-unsafe-rust.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/unsafe.html). diff --git a/rustbook-en/first-edition/src/unsized-types.md b/rustbook-en/first-edition/src/unsized-types.md deleted file mode 100644 index 4ec43ecad..000000000 --- a/rustbook-en/first-edition/src/unsized-types.md +++ /dev/null @@ -1,10 +0,0 @@ -# Unsized Types - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/unsized-types.html). diff --git a/rustbook-en/first-edition/src/using-rust-without-the-standard-library.md b/rustbook-en/first-edition/src/using-rust-without-the-standard-library.md deleted file mode 100644 index 28e4e763b..000000000 --- a/rustbook-en/first-edition/src/using-rust-without-the-standard-library.md +++ /dev/null @@ -1,10 +0,0 @@ -# Using Rust Without the Standard Library - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/using-rust-without-the-standard-library.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/variable-bindings.md b/rustbook-en/first-edition/src/variable-bindings.md deleted file mode 100644 index d11c926fd..000000000 --- a/rustbook-en/first-edition/src/variable-bindings.md +++ /dev/null @@ -1,10 +0,0 @@ -# Variable Bindings - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../index.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/variable-bindings.html). \ No newline at end of file diff --git a/rustbook-en/first-edition/src/vectors.md b/rustbook-en/first-edition/src/vectors.md deleted file mode 100644 index 14f83b7f7..000000000 --- a/rustbook-en/first-edition/src/vectors.md +++ /dev/null @@ -1,10 +0,0 @@ -# Vectors - -The first edition of the book is no longer distributed with Rust's documentation. - -If you came here via a link or web search, you may want to check out [the current -version of the book](../ch08-01-vectors.html) instead. - -If you have an internet connection, you can [find a copy distributed with -Rust -1.30](https://doc.rust-lang.org/1.30.0/book/first-edition/vectors.html). diff --git a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs deleted file mode 100644 index b822b89ff..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-01/src/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -// ANCHOR: all -// ANCHOR: io -use std::io; -// ANCHOR_END: io - -// ANCHOR: main -fn main() { - // ANCHOR_END: main - // ANCHOR: print - println!("Guess the number!"); - - println!("Please input your guess."); - // ANCHOR_END: print - - // ANCHOR: string - let mut guess = String::new(); - // ANCHOR_END: string - - // ANCHOR: read - io::stdin() - .read_line(&mut guess) - // ANCHOR_END: read - // ANCHOR: expect - .expect("Failed to read line"); - // ANCHOR_END: expect - - // ANCHOR: print_guess - println!("You guessed: {}", guess); - // ANCHOR_END: print_guess -} -// ANCHOR: all diff --git a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs deleted file mode 100644 index b35ed0f2f..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-02/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -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/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs deleted file mode 100644 index 1ba2d4d41..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -// 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..=100); - // 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/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt b/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt deleted file mode 100644 index bb997866a..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-04/output.txt +++ /dev/null @@ -1,24 +0,0 @@ -$ cargo build - Compiling libc v0.2.86 - Compiling getrandom v0.2.2 - Compiling cfg-if v1.0.0 - Compiling ppv-lite86 v0.2.10 - Compiling rand_core v0.6.2 - Compiling rand_chacha v0.3.0 - Compiling rand v0.8.5 - 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 `&String`, found `&{integer}` - | | - | arguments to this method are incorrect - | - = note: expected reference `&String` - found reference `&{integer}` -note: method defined here - --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/cmp.rs:840:8 - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `guessing_game` (bin "guessing_game") due to 1 previous error diff --git a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs deleted file mode 100644 index 6e58a7645..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-04/src/main.rs +++ /dev/null @@ -1,32 +0,0 @@ -// ANCHOR: here -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - // --snip-- - // ANCHOR_END: here - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs deleted file mode 100644 index 12f497e18..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-05/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs deleted file mode 100644 index 7fcbb99fb..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/listing-02-06/src/main.rs +++ /dev/null @@ -1,35 +0,0 @@ -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt b/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt deleted file mode 100644 index 33409e38c..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.50s - Running `target/debug/guessing_game` -Hello, world! diff --git a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs deleted file mode 100644 index e7a11a969..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-01-cargo-new/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt b/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt deleted file mode 100644 index 417d4e3cb..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo build - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) -warning: unused `Result` that must be used - --> src/main.rs:10:5 - | -10 | io::stdin().read_line(&mut guess); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this `Result` may be an `Err` variant, which should be handled - = note: `#[warn(unused_must_use)]` on by default -help: use `let _ = ...` to ignore the resulting value - | -10 | let _ = io::stdin().read_line(&mut guess); - | +++++++ - -warning: `guessing_game` (bin "guessing_game") generated 1 warning - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.59s diff --git a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs deleted file mode 100644 index 51046016f..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs deleted file mode 100644 index 7f076c592..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-03-convert-string-to-number/src/main.rs +++ /dev/null @@ -1,33 +0,0 @@ -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs deleted file mode 100644 index f97d1c58c..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-04-looping/src/main.rs +++ /dev/null @@ -1,40 +0,0 @@ -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - // ANCHOR: here - // --snip-- - - println!("The secret number is: {secret_number}"); - - loop { - println!("Please input your guess."); - - // --snip-- - - // ANCHOR_END: here - - let mut guess = String::new(); - - io::stdin() - .read_line(&mut guess) - .expect("Failed to read line"); - - let guess: u32 = guess.trim().parse().expect("Please type a number!"); - - println!("You guessed: {guess}"); - - // ANCHOR: here - match guess.cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => println!("You win!"), - } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs b/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs deleted file mode 100644 index def0a0e7e..000000000 --- a/rustbook-en/listings/ch02-guessing-game-tutorial/no-listing-05-quitting/src/main.rs +++ /dev/null @@ -1,38 +0,0 @@ -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch03-common-programming-concepts/listing-03-02/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/listing-03-02/output.txt deleted file mode 100644 index 3b0deaec6..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-02/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.30s - Running `target/debug/branches` -The value of number is: 5 diff --git a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-02/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/listing-03-02/src/main.rs deleted file mode 100644 index e021e41e8..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-02/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let condition = true; - let number = if condition { 5 } else { 6 }; - - println!("The value of number is: {number}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-03/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/listing-03-03/src/main.rs deleted file mode 100644 index ca070c759..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-03/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -fn main() { - let mut number = 3; - - while number != 0 { - println!("{number}!"); - - number -= 1; - } - - println!("LIFTOFF!!!"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-04/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/listing-03-04/output.txt deleted file mode 100644 index 82408ac82..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-04/output.txt +++ /dev/null @@ -1,9 +0,0 @@ -$ cargo run - Compiling loops v0.1.0 (file:///projects/loops) - Finished `dev` profile [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/rustbook-en/listings/ch03-common-programming-concepts/listing-03-04/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/listing-03-04/src/main.rs deleted file mode 100644 index 38fd301e6..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-04/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/listing-03-05/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/listing-03-05/src/main.rs deleted file mode 100644 index b44e6b7aa..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/listing-03-05/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let a = [10, 20, 30, 40, 50]; - - for element in a { - println!("the value is: {element}"); - } -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt deleted file mode 100644 index 73ca9d62f..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling variables v0.1.0 (file:///projects/variables) -error[E0384]: cannot assign twice to immutable variable `x` - --> src/main.rs:4:5 - | -2 | let x = 5; - | - - | | - | first assignment to `x` - | help: consider making this binding mutable: `mut x` -3 | println!("The value of x is: {x}"); -4 | x = 6; - | ^^^^^ cannot assign twice to immutable variable - -For more information about this error, try `rustc --explain E0384`. -error: could not compile `variables` (bin "variables") due to 1 previous error diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs deleted file mode 100644 index d64f46de4..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-01-variables-are-immutable/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let x = 5; - println!("The value of x is: {x}"); - x = 6; - println!("The value of x is: {x}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt deleted file mode 100644 index ed0c0c342..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/output.txt +++ /dev/null @@ -1,6 +0,0 @@ -$ cargo run - Compiling variables v0.1.0 (file:///projects/variables) - Finished `dev` profile [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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs deleted file mode 100644 index a57709ccf..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-02-adding-mut/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt deleted file mode 100644 index 6ff531b55..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-03-shadowing/output.txt +++ /dev/null @@ -1,6 +0,0 @@ -$ cargo run - Compiling variables v0.1.0 (file:///projects/variables) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s - Running `target/debug/variables` -The value of x in the inner scope is: 12 -The value of x is: 6 diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs deleted file mode 100644 index 03924fe1c..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-03-shadowing/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -fn main() { - let x = 5; - - let x = x + 1; - - { - let x = x * 2; - println!("The value of x in the inner scope is: {x}"); - } - - println!("The value of x is: {x}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt deleted file mode 100644 index 578a1f4aa..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-05-mut-cant-change-types/output.txt +++ /dev/null @@ -1,12 +0,0 @@ -$ cargo run - Compiling variables v0.1.0 (file:///projects/variables) -error[E0308]: mismatched types - --> src/main.rs:3:14 - | -2 | let mut spaces = " "; - | ----- expected due to this value -3 | spaces = spaces.len(); - | ^^^^^^^^^^^^ expected `&str`, found `usize` - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `variables` (bin "variables") due to 1 previous error diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs deleted file mode 100644 index 77c716c14..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-07-numeric-operations/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -fn main() { - // addition - let sum = 5 + 10; - - // subtraction - let difference = 95.5 - 4.3; - - // multiplication - let product = 4 * 30; - - // division - let quotient = 56.7 / 32.2; - let truncated = -5 / 3; // Results in -1 - - // remainder - let remainder = 43 % 5; -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs deleted file mode 100644 index b7b51fb2f..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-10-tuples/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - let tup: (i32, f64, u8) = (500, 6.4, 1); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs deleted file mode 100644 index 3002bdde4..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-11-destructuring-tuples/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let tup = (500, 6.4, 1); - - let (x, y, z) = tup; - - println!("The value of y is: {y}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs deleted file mode 100644 index 1b1e646fd..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-12-tuple-indexing/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs deleted file mode 100644 index d33e3174f..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-14-array-indexing/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let a = [1, 2, 3, 4, 5]; - - let first = a[0]; - let second = a[1]; -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs deleted file mode 100644 index b634c9378..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-15-invalid-array-access/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::io; - -fn main() { - let a = [1, 2, 3, 4, 5]; - - println!("Please enter an array index."); - - let mut index = String::new(); - - io::stdin() - .read_line(&mut index) - .expect("Failed to read line"); - - let index: usize = index - .trim() - .parse() - .expect("Index entered was not a number"); - - let element = a[index]; - - println!("The value of the element at index {index} is: {element}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt deleted file mode 100644 index 898cf5fb6..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-16-functions/output.txt +++ /dev/null @@ -1,6 +0,0 @@ -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.28s - Running `target/debug/functions` -Hello, world! -Another function. diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs deleted file mode 100644 index 38be8565b..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-16-functions/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - println!("Hello, world!"); - - another_function(); -} - -fn another_function() { - println!("Another function."); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt deleted file mode 100644 index 377f72886..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.21s - Running `target/debug/functions` -The value of x is: 5 diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs deleted file mode 100644 index 108da4f81..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-17-functions-with-parameters/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - another_function(5); -} - -fn another_function(x: i32) { - println!("The value of x is: {x}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt deleted file mode 100644 index 91e71c174..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s - Running `target/debug/functions` -The measurement is: 5h diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs deleted file mode 100644 index b070ccb23..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-18-functions-with-multiple-parameters/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - print_labeled_measurement(5, 'h'); -} - -fn print_labeled_measurement(value: i32, unit_label: char) { - println!("The measurement is: {value}{unit_label}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.lock b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.lock deleted file mode 100644 index 89a654d69..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "functions" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt deleted file mode 100644 index 504fdd6ec..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-19-statements-vs-expressions/output.txt +++ /dev/null @@ -1,25 +0,0 @@ -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) -error: expected expression, found `let` statement - --> src/main.rs:2:14 - | -2 | let x = (let y = 6); - | ^^^ - | - = note: only supported directly in conditions of `if` and `while` expressions - -warning: unnecessary parentheses around assigned value - --> src/main.rs:2:13 - | -2 | let x = (let y = 6); - | ^ ^ - | - = note: `#[warn(unused_parens)]` on by default -help: remove these parentheses - | -2 - let x = (let y = 6); -2 + let x = let y = 6; - | - -warning: `functions` (bin "functions") generated 1 warning -error: could not compile `functions` (bin "functions") due to 1 previous error; 1 warning emitted diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs deleted file mode 100644 index 64b873297..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-20-blocks-are-expressions/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - let y = { - let x = 3; - x + 1 - }; - - println!("The value of y is: {y}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt deleted file mode 100644 index e66e4b980..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.30s - Running `target/debug/functions` -The value of x is: 5 diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs deleted file mode 100644 index a11af7ec7..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-21-function-return-values/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn five() -> i32 { - 5 -} - -fn main() { - let x = five(); - - println!("The value of x is: {x}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs deleted file mode 100644 index da9d0ddb3..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-22-function-parameter-and-return/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt deleted file mode 100644 index 18fdfd1b4..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt +++ /dev/null @@ -1,14 +0,0 @@ -$ cargo run - Compiling functions v0.1.0 (file:///projects/functions) -error[E0308]: mismatched types - --> src/main.rs:7:24 - | -7 | fn plus_one(x: i32) -> i32 { - | -------- ^^^ expected `i32`, found `()` - | | - | implicitly returns `()` as its body has no tail or `return` expression -8 | x + 1; - | - help: remove this semicolon to return this value - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `functions` (bin "functions") due to 1 previous error diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs deleted file mode 100644 index 1cec800b6..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs deleted file mode 100644 index 535f4b993..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-24-comments-end-of-line/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - let lucky_number = 7; // I’m feeling lucky today -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs deleted file mode 100644 index 81cd93559..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-25-comments-above-line/src/main.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - // I’m feeling lucky today - let lucky_number = 7; -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt deleted file mode 100644 index d39b3b5fc..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-26-if-true/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s - Running `target/debug/branches` -condition was true diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs deleted file mode 100644 index e64a42adf..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-26-if-true/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let number = 3; - - if number < 5 { - println!("condition was true"); - } else { - println!("condition was false"); - } -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt deleted file mode 100644 index 3aa1e1c05..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s - Running `target/debug/branches` -condition was false diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs deleted file mode 100644 index f7d76cf55..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-27-if-false/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt deleted file mode 100644 index c9c0b0c46..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) -error[E0308]: mismatched types - --> src/main.rs:4:8 - | -4 | if number { - | ^^^^^^ expected `bool`, found integer - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `branches` (bin "branches") due to 1 previous error diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs deleted file mode 100644 index bc4af767b..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-28-if-condition-must-be-bool/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let number = 3; - - if number { - println!("number was three"); - } -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs deleted file mode 100644 index 704650f46..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-29-if-not-equal-0/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let number = 3; - - if number != 0 { - println!("number was something other than zero"); - } -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt deleted file mode 100644 index d5195248a..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-30-else-if/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s - Running `target/debug/branches` -number is divisible by 3 diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs deleted file mode 100644 index d0ef9b2c1..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-30-else-if/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt deleted file mode 100644 index 7fb857f03..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/output.txt +++ /dev/null @@ -1,12 +0,0 @@ -$ cargo run - Compiling branches v0.1.0 (file:///projects/branches) -error[E0308]: `if` and `else` have incompatible types - --> src/main.rs:4:44 - | -4 | let number = if condition { 5 } else { "six" }; - | - ^^^^^ expected integer, found `&str` - | | - | expected because of this - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `branches` (bin "branches") due to 1 previous error diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs deleted file mode 100644 index df7068bcf..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-31-arms-must-return-same-type/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let condition = true; - - let number = if condition { 5 } else { "six" }; - - println!("The value of number is: {number}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/output.txt deleted file mode 100644 index 4977b2b34..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/output.txt +++ /dev/null @@ -1,13 +0,0 @@ -$ cargo run - Compiling loops v0.1.0 (file:///projects/loops) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.58s - Running `target/debug/loops` -count = 0 -remaining = 10 -remaining = 9 -count = 1 -remaining = 10 -remaining = 9 -count = 2 -remaining = 10 -End count = 2 diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/src/main.rs deleted file mode 100644 index dd8856403..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-5-loop-labels/src/main.rs +++ /dev/null @@ -1,21 +0,0 @@ -fn main() { - let mut count = 0; - 'counting_up: loop { - println!("count = {count}"); - let mut remaining = 10; - - loop { - println!("remaining = {remaining}"); - if remaining == 9 { - break; - } - if count == 2 { - break 'counting_up; - } - remaining -= 1; - } - - count += 1; - } - println!("End count = {count}"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs deleted file mode 100644 index f1692e462..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-32-loop/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - loop { - println!("again!"); - } -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs deleted file mode 100644 index 683d18bc1..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-33-return-value-from-loop/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs deleted file mode 100644 index df5b305bc..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/no-listing-34-for-range/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - for number in (1..4).rev() { - println!("{number}!"); - } - println!("LIFTOFF!!!"); -} diff --git a/rustbook-en/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt b/rustbook-en/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt deleted file mode 100644 index ee6a97943..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo build - Compiling no_type_annotations v0.1.0 (file:///projects/no_type_annotations) -error[E0284]: type annotations needed - --> src/main.rs:2:9 - | -2 | let guess = "42".parse().expect("Not a number!"); - | ^^^^^ ----- type must be known at this point - | - = note: cannot satisfy `<_ as FromStr>::Err == _` -help: consider giving `guess` an explicit type - | -2 | let guess: /* Type */ = "42".parse().expect("Not a number!"); - | ++++++++++++ - -For more information about this error, try `rustc --explain E0284`. -error: could not compile `no_type_annotations` (bin "no_type_annotations") due to 1 previous error diff --git a/rustbook-en/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/src/main.rs b/rustbook-en/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/src/main.rs deleted file mode 100644 index f41c55805..000000000 --- a/rustbook-en/listings/ch03-common-programming-concepts/output-only-01-no-type-annotations/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - let guess = "42".parse().expect("Not a number!"); -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-01/Cargo.lock b/rustbook-en/listings/ch04-understanding-ownership/listing-04-01/Cargo.lock deleted file mode 100644 index 9e4e62ddf..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-01/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ownership" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-01/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-01/src/main.rs deleted file mode 100644 index ebcd3691b..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-01/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -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 -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-03/Cargo.lock b/rustbook-en/listings/ch04-understanding-ownership/listing-04-03/Cargo.lock deleted file mode 100644 index 9e4e62ddf..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-03/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ownership" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-03/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-03/src/main.rs deleted file mode 100644 index edf51a947..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-03/src/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/listing-04-04/Cargo.lock b/rustbook-en/listings/ch04-understanding-ownership/listing-04-04/Cargo.lock deleted file mode 100644 index 9e4e62ddf..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-04/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ownership" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-04/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-04/src/main.rs deleted file mode 100644 index e206bec7a..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-04/src/main.rs +++ /dev/null @@ -1,29 +0,0 @@ -fn main() { - let s1 = gives_ownership(); // gives_ownership moves its return - // value into s1 - - let s2 = String::from("hello"); // s2 comes into scope - - let s3 = takes_and_gives_back(s2); // s2 is moved into - // takes_and_gives_back, which also - // moves its return value into s3 -} // Here, s3 goes out of scope and is dropped. s2 was moved, so nothing - // happens. s1 goes out of scope and is dropped. - -fn gives_ownership() -> String { // gives_ownership will move its - // return value into the function - // that calls it - - let some_string = String::from("yours"); // some_string comes into scope - - some_string // some_string is returned and - // moves out to the calling - // function -} - -// This function takes a String and returns one -fn takes_and_gives_back(a_string: String) -> String { // a_string comes into - // scope - - a_string // a_string is returned and moves out to the calling function -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-05/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-05/src/main.rs deleted file mode 100644 index 2782483a7..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-05/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - let s1 = String::from("hello"); - - let (s2, len) = calculate_length(s1); - - println!("The length of '{s2}' is {len}."); -} - -fn calculate_length(s: String) -> (String, usize) { - let length = s.len(); // len() returns the length of a String - - (s, length) -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-06/output.txt b/rustbook-en/listings/ch04-understanding-ownership/listing-04-06/output.txt deleted file mode 100644 index c78cd5d3d..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-06/output.txt +++ /dev/null @@ -1,15 +0,0 @@ -$ 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 - | -8 | some_string.push_str(", world"); - | ^^^^^^^^^^^ `some_string` is a `&` reference, so the data it refers to cannot be borrowed as mutable - | -help: consider changing this to be a mutable reference - | -7 | fn change(some_string: &mut String) { - | +++ - -For more information about this error, try `rustc --explain E0596`. -error: could not compile `ownership` (bin "ownership") due to 1 previous error diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-06/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-06/src/main.rs deleted file mode 100644 index 330ffa68a..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-06/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let s = String::from("hello"); - - change(&s); -} - -fn change(some_string: &String) { - some_string.push_str(", world"); -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/listing-04-07/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-07/src/main.rs deleted file mode 100644 index 3bb3c8580..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-07/src/main.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/rustbook-en/listings/ch04-understanding-ownership/listing-04-08/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-08/src/main.rs deleted file mode 100644 index b6182fe2b..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-08/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/listing-04-09/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/listing-04-09/src/main.rs deleted file mode 100644 index 5a6ceaa1e..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/listing-04-09/src/main.rs +++ /dev/null @@ -1,36 +0,0 @@ -// ANCHOR: here -fn first_word(s: &str) -> &str { - // ANCHOR_END: here - let bytes = s.as_bytes(); - - for (i, &item) in bytes.iter().enumerate() { - if item == b' ' { - return &s[0..i]; - } - } - - &s[..] -} - -// ANCHOR: usage -fn main() { - let my_string = String::from("hello world"); - - // `first_word` works on slices of `String`s, whether partial or whole - let word = first_word(&my_string[0..6]); - let word = first_word(&my_string[..]); - // `first_word` also works on references to `String`s, which are equivalent - // to whole slices of `String`s - let word = first_word(&my_string); - - let my_string_literal = "hello world"; - - // `first_word` works on slices of string literals, whether partial or whole - let word = first_word(&my_string_literal[0..6]); - let word = first_word(&my_string_literal[..]); - - // Because string literals *are* string slices already, - // this works too, without the slice syntax! - let word = first_word(my_string_literal); -} -// ANCHOR_END: usage diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs deleted file mode 100644 index 15bc9d922..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-01-can-mutate-string/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.lock b/rustbook-en/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.lock deleted file mode 100644 index 9e4e62ddf..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-02-string-scope/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ownership" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs deleted file mode 100644 index 7e6d46f83..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-02-string-scope/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs deleted file mode 100644 index a5817e714..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-03-string-move/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - // ANCHOR: here - let s1 = String::from("hello"); - let s2 = s1; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt b/rustbook-en/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt deleted file mode 100644 index 73e6115d6..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt +++ /dev/null @@ -1,21 +0,0 @@ -$ cargo run - Compiling ownership v0.1.0 (file:///projects/ownership) -error[E0382]: borrow of moved value: `s1` - --> src/main.rs:5:15 - | -2 | let s1 = String::from("hello"); - | -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait -3 | let s2 = s1; - | -- value moved here -4 | -5 | println!("{s1}, world!"); - | ^^^^ value borrowed here after move - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider cloning the value if the performance cost is acceptable - | -3 | let s2 = s1.clone(); - | ++++++++ - -For more information about this error, try `rustc --explain E0382`. -error: could not compile `ownership` (bin "ownership") due to 1 previous error diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs deleted file mode 100644 index e35f6d803..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - // ANCHOR: here - let s1 = String::from("hello"); - let s2 = s1; - - println!("{s1}, world!"); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs deleted file mode 100644 index 0b65e5f61..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-05-clone/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - // ANCHOR: here - let s1 = String::from("hello"); - let s2 = s1.clone(); - - println!("s1 = {s1}, s2 = {s2}"); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs deleted file mode 100644 index 6f6d5fb23..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-07-reference/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -// ANCHOR: all -fn main() { - // ANCHOR: here - let s1 = String::from("hello"); - - let len = calculate_length(&s1); - // ANCHOR_END: here - - println!("The length of '{s1}' is {len}."); -} - -fn calculate_length(s: &String) -> usize { - s.len() -} -// ANCHOR_END: all diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.lock b/rustbook-en/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.lock deleted file mode 100644 index 9e4e62ddf..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ownership" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs deleted file mode 100644 index 964fd233f..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-08-reference-with-annotations/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -fn main() { - let s1 = String::from("hello"); - - let len = calculate_length(&s1); - - println!("The length of '{s1}' is {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, it is not dropped. -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs deleted file mode 100644 index fdf7f0a6f..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-09-fixes-listing-04-06/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt b/rustbook-en/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt deleted file mode 100644 index 97be4a258..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/output.txt +++ /dev/null @@ -1,15 +0,0 @@ -$ cargo run - Compiling ownership v0.1.0 (file:///projects/ownership) -error[E0499]: cannot borrow `s` as mutable more than once at a time - --> src/main.rs:5:14 - | -4 | let r1 = &mut s; - | ------ first mutable borrow occurs here -5 | let r2 = &mut s; - | ^^^^^^ second mutable borrow occurs here -6 | -7 | println!("{}, {}", r1, r2); - | -- first borrow later used here - -For more information about this error, try `rustc --explain E0499`. -error: could not compile `ownership` (bin "ownership") due to 1 previous error diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs deleted file mode 100644 index ddbf8120f..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-10-multiple-mut-not-allowed/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs deleted file mode 100644 index 4b1a5a383..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-11-muts-in-separate-scopes/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt b/rustbook-en/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt deleted file mode 100644 index 454882323..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling ownership v0.1.0 (file:///projects/ownership) -error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable - --> src/main.rs:6:14 - | -4 | let r1 = &s; // no problem - | -- immutable borrow occurs here -5 | let r2 = &s; // no problem -6 | let r3 = &mut s; // BIG PROBLEM - | ^^^^^^ mutable borrow occurs here -7 | -8 | println!("{}, {}, and {}", r1, r2, r3); - | -- immutable borrow later used here - -For more information about this error, try `rustc --explain E0502`. -error: could not compile `ownership` (bin "ownership") due to 1 previous error diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs deleted file mode 100644 index 0da04c010..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-12-immutable-and-mutable-not-allowed/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs deleted file mode 100644 index c005414d8..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-13-reference-scope-ends/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - // ANCHOR: here - let mut s = String::from("hello"); - - let r1 = &s; // no problem - let r2 = &s; // no problem - println!("{r1} and {r2}"); - // variables r1 and r2 will not be used after this point - - let r3 = &mut s; // no problem - println!("{r3}"); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt b/rustbook-en/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt deleted file mode 100644 index 0339433f2..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/output.txt +++ /dev/null @@ -1,28 +0,0 @@ -$ cargo run - Compiling ownership v0.1.0 (file:///projects/ownership) -error[E0106]: missing lifetime specifier - --> src/main.rs:5:16 - | -5 | fn dangle() -> &String { - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from -help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static` - | -5 | fn dangle() -> &'static String { - | +++++++ -help: instead, you are more likely to want to return an owned value - | -5 - fn dangle() -> &String { -5 + fn dangle() -> String { - | - -error[E0515]: cannot return reference to local variable `s` - --> src/main.rs:8:5 - | -8 | &s - | ^^ returns a reference to data owned by the current function - -Some errors have detailed explanations: E0106, E0515. -For more information about an error, try `rustc --explain E0106`. -error: could not compile `ownership` (bin "ownership") due to 2 previous errors diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs deleted file mode 100644 index b10269781..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-14-dangling-reference/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let reference_to_nothing = dangle(); -} - -fn dangle() -> &String { - let s = String::from("hello"); - - &s -} diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.lock b/rustbook-en/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.lock deleted file mode 100644 index 9e4e62ddf..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "ownership" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs deleted file mode 100644 index 9fbb372a0..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-15-dangling-reference-annotated/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs deleted file mode 100644 index 9c20a3b2d..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-16-no-dangle/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -fn main() { - let string = no_dangle(); -} - -// ANCHOR: here -fn no_dangle() -> String { - let s = String::from("hello"); - - s -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs deleted file mode 100644 index 44163af99..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-17-slice/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -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/rustbook-en/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs deleted file mode 100644 index f44a970da..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-18-first-word-slice/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/rustbook-en/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt b/rustbook-en/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt deleted file mode 100644 index c29ddf5bf..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-19-slice-error/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling ownership v0.1.0 (file:///projects/ownership) -error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable - --> src/main.rs:18:5 - | -16 | let word = first_word(&s); - | -- immutable borrow occurs here -17 | -18 | s.clear(); // error! - | ^^^^^^^^^ mutable borrow occurs here -19 | -20 | println!("the first word is: {word}"); - | ------ immutable borrow later used here - -For more information about this error, try `rustc --explain E0502`. -error: could not compile `ownership` (bin "ownership") due to 1 previous error diff --git a/rustbook-en/listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs b/rustbook-en/listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs deleted file mode 100644 index b23e45f43..000000000 --- a/rustbook-en/listings/ch04-understanding-ownership/no-listing-19-slice-error/src/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs deleted file mode 100644 index 16dd15b29..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -// ANCHOR: here -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs deleted file mode 100644 index 122d25164..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} - -// ANCHOR: here -fn main() { - let user1 = User { - active: true, - username: String::from("someusername123"), - email: String::from("someone@example.com"), - sign_in_count: 1, - }; -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs deleted file mode 100644 index 35eea8a9a..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} - -// ANCHOR: here -fn main() { - let mut user1 = User { - active: true, - username: String::from("someusername123"), - email: String::from("someone@example.com"), - sign_in_count: 1, - }; - - user1.email = String::from("anotheremail@example.com"); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs deleted file mode 100644 index 8614561c1..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} - -// ANCHOR: here -fn build_user(email: String, username: String) -> User { - User { - active: true, - username: username, - email: email, - sign_in_count: 1, - } -} -// ANCHOR_END: here - -fn main() { - let user1 = build_user( - String::from("someone@example.com"), - String::from("someusername123"), - ); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs deleted file mode 100644 index c893c86a9..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} - -// ANCHOR: here -fn build_user(email: String, username: String) -> User { - User { - active: true, - username, - email, - sign_in_count: 1, - } -} -// ANCHOR_END: here - -fn main() { - let user1 = build_user( - String::from("someone@example.com"), - String::from("someusername123"), - ); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs deleted file mode 100644 index 15e7690e1..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} - -// ANCHOR: here -fn main() { - // --snip-- - // ANCHOR_END: here - - let user1 = User { - email: String::from("someone@example.com"), - username: String::from("someusername123"), - active: true, - sign_in_count: 1, - }; - // ANCHOR: here - - let user2 = User { - active: user1.active, - username: user1.username, - email: String::from("another@example.com"), - sign_in_count: user1.sign_in_count, - }; -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs deleted file mode 100644 index 008ad18f6..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs +++ /dev/null @@ -1,26 +0,0 @@ -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} - -// ANCHOR: here -fn main() { - // --snip-- - // ANCHOR_END: here - - let user1 = User { - email: String::from("someone@example.com"), - username: String::from("someusername123"), - active: true, - sign_in_count: 1, - }; - // ANCHOR: here - - let user2 = User { - email: String::from("another@example.com"), - ..user1 - }; -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt deleted file mode 100644 index 79b830777..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-08/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.42s - Running `target/debug/rectangles` -The area of the rectangle is 1500 square pixels. diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs deleted file mode 100644 index f324529fd..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs deleted file mode 100644 index d4b77ba7a..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs deleted file mode 100644 index 62ef9acd8..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt deleted file mode 100644 index ee169726d..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-11/output.txt +++ /dev/null @@ -1,14 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) -error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` - --> src/main.rs:12:29 - | -12 | println!("rect1 is {}", rect1); - | ^^^^^ `Rectangle` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `Rectangle` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `rectangles` (bin "rectangles") due to 1 previous error diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs deleted file mode 100644 index 0ff8dcc8c..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - println!("rect1 is {}", rect1); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt deleted file mode 100644 index 0c810b1f4..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-12/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s - Running `target/debug/rectangles` -rect1 is Rectangle { width: 30, height: 50 } diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs deleted file mode 100644 index 67e0b92a4..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - println!("rect1 is {rect1:?}"); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs deleted file mode 100644 index e4f45e868..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -#[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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs deleted file mode 100644 index 843dab481..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs deleted file mode 100644 index e6a32723f..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs +++ /dev/null @@ -1,35 +0,0 @@ -#[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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs deleted file mode 100644 index a5d3f772a..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs +++ /dev/null @@ -1,37 +0,0 @@ -#[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/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs deleted file mode 100644 index 0d993162b..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -struct Color(i32, i32, i32); -struct Point(i32, i32, i32); - -fn main() { - let black = Color(0, 0, 0); - let origin = Point(0, 0, 0); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt deleted file mode 100644 index 5f9344c51..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/output.txt +++ /dev/null @@ -1,31 +0,0 @@ -$ cargo run - Compiling structs v0.1.0 (file:///projects/structs) -error[E0106]: missing lifetime specifier - --> src/main.rs:3:15 - | -3 | username: &str, - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -1 ~ struct User<'a> { -2 | active: bool, -3 ~ username: &'a str, - | - -error[E0106]: missing lifetime specifier - --> src/main.rs:4:12 - | -4 | email: &str, - | ^ expected named lifetime parameter - | -help: consider introducing a named lifetime parameter - | -1 ~ struct User<'a> { -2 | active: bool, -3 | username: &str, -4 ~ email: &'a str, - | - -For more information about this error, try `rustc --explain E0106`. -error: could not compile `structs` (bin "structs") due to 2 previous errors diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/src/main.rs deleted file mode 100644 index 96092d042..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-02-reference-in-struct/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -struct User { - active: bool, - username: &str, - email: &str, - sign_in_count: u64, -} - -fn main() { - let user1 = User { - email: "someone@example.com", - username: "someusername123", - active: true, - sign_in_count: 1, - }; -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs deleted file mode 100644 index 47fedc552..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-03-associated-functions/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -// ANCHOR: here -impl Rectangle { - fn square(size: u32) -> Self { - Self { - width: size, - height: size, - } - } -} -// ANCHOR_END: here - -fn main() { - let sq = Rectangle::square(3); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt deleted file mode 100644 index 1c1f07dfb..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/output.txt +++ /dev/null @@ -1,9 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.61s - Running `target/debug/rectangles` -[src/main.rs:10:16] 30 * scale = 60 -[src/main.rs:14:5] &rect1 = Rectangle { - width: 60, - height: 50, -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/src/main.rs deleted file mode 100644 index dd0342959..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-05-dbg-macro/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let scale = 2; - let rect1 = Rectangle { - width: dbg!(30 * scale), - height: 50, - }; - - dbg!(&rect1); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/src/main.rs deleted file mode 100644 index 00e1de83b..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -// ANCHOR: here -impl Rectangle { - fn width(&self) -> bool { - self.width > 0 - } -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - if rect1.width() { - println!("The rectangle has a nonzero width; it is {}", rect1.width); - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt deleted file mode 100644 index 71de1f7bd..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/output.txt +++ /dev/null @@ -1,19 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) -error[E0277]: `Rectangle` doesn't implement `Debug` - --> src/main.rs:12:31 - | -12 | println!("rect1 is {:?}", rect1); - | ^^^^^ `Rectangle` cannot be formatted using `{:?}` - | - = help: the trait `Debug` is not implemented for `Rectangle` - = note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle` - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `Rectangle` with `#[derive(Debug)]` - | -1 + #[derive(Debug)] -2 | struct Rectangle { - | - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `rectangles` (bin "rectangles") due to 1 previous error diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs deleted file mode 100644 index 019a357ab..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-01-debug/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - println!("rect1 is {:?}", rect1); -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt deleted file mode 100644 index 4a6c5a9a1..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/output.txt +++ /dev/null @@ -1,8 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s - Running `target/debug/rectangles` -rect1 is Rectangle { - width: 30, - height: 50, -} diff --git a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs b/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs deleted file mode 100644 index f763b50d3..000000000 --- a/rustbook-en/listings/ch05-using-structs-to-structure-related-data/output-only-02-pretty-debug/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - println!("rect1 is {rect1:#?}"); -} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs deleted file mode 100644 index 5b688e0f2..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-01/src/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -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/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs deleted file mode 100644 index 3ba749788..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-02/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -// ANCHOR: here -enum Message { - Quit, - Move { x: i32, y: i32 }, - Write(String), - ChangeColor(i32, i32, i32), -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs deleted file mode 100644 index 93dce48cb..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-03/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -// ANCHOR: here -enum Coin { - Penny, - Nickel, - Dime, - Quarter, -} - -fn value_in_cents(coin: Coin) -> u8 { - match coin { - Coin::Penny => 1, - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter => 25, - } -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs deleted file mode 100644 index 3ba384fba..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-04/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs deleted file mode 100644 index c86190aa7..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/listing-06-05/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs deleted file mode 100644 index c631e56ba..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-01-defining-enums/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs deleted file mode 100644 index 7d59b811f..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-02-enum-with-data/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs deleted file mode 100644 index 844a14041..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-03-variants-with-different-data/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs deleted file mode 100644 index df451be8b..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-04-structs-similar-to-message-enum/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -// 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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs deleted file mode 100644 index 66e0b6da1..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-05-methods-on-enums/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs deleted file mode 100644 index be552bfa5..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-06-option-examples/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - // ANCHOR: here - let some_number = Some(5); - let some_char = Some('e'); - - let absent_number: Option = None; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt deleted file mode 100644 index dde05f4b3..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo run - Compiling enums v0.1.0 (file:///projects/enums) -error[E0277]: cannot add `Option` to `i8` - --> src/main.rs:5:17 - | -5 | let sum = x + y; - | ^ no implementation for `i8 + Option` - | - = help: the trait `Add>` is not implemented for `i8` - = help: the following other types implement trait `Add`: - <&'a i8 as Add> - <&i8 as Add<&i8>> - > - - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `enums` (bin "enums") due to 1 previous error diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs deleted file mode 100644 index ec65565d4..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - // ANCHOR: here - let x: i8 = 5; - let y: Option = Some(5); - - let sum = x + y; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs deleted file mode 100644 index 3f909dcaf..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-08-match-arm-multiple-lines/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -enum Coin { - Penny, - Nickel, - Dime, - Quarter, -} - -// ANCHOR: here -fn value_in_cents(coin: Coin) -> u8 { - match coin { - Coin::Penny => { - println!("Lucky penny!"); - 1 - } - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter => 25, - } -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs deleted file mode 100644 index 298215d40..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-09-variable-in-pattern/src/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -#[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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt deleted file mode 100644 index 5232f9037..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt +++ /dev/null @@ -1,22 +0,0 @@ -$ 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 - | -note: `Option` defined here - --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/option.rs:571:1 - ::: /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/option.rs:575:5 - | - = note: not covered - = note: the matched value is of type `Option` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown - | -4 ~ Some(i) => Some(i + 1), -5 ~ None => todo!(), - | - -For more information about this error, try `rustc --explain E0004`. -error: could not compile `enums` (bin "enums") due to 1 previous error diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs deleted file mode 100644 index f1963d0c9..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs deleted file mode 100644 index d0d7d8027..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-13-count-and-announce-match/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -#[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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs deleted file mode 100644 index 3bb363035..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-14-count-and-announce-if-let-else/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[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/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs deleted file mode 100644 index 6ce0b5998..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-15-binding-catchall/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -fn main() { - // ANCHOR: here - let dice_roll = 9; - match dice_roll { - 3 => add_fancy_hat(), - 7 => remove_fancy_hat(), - other => move_player(other), - } - - fn add_fancy_hat() {} - fn remove_fancy_hat() {} - fn move_player(num_spaces: u8) {} - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/src/main.rs deleted file mode 100644 index 586e23751..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-16-underscore-catchall/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -fn main() { - // ANCHOR: here - let dice_roll = 9; - match dice_roll { - 3 => add_fancy_hat(), - 7 => remove_fancy_hat(), - _ => reroll(), - } - - fn add_fancy_hat() {} - fn remove_fancy_hat() {} - fn reroll() {} - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/src/main.rs b/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/src/main.rs deleted file mode 100644 index e791742ee..000000000 --- a/rustbook-en/listings/ch06-enums-and-pattern-matching/no-listing-17-underscore-unit/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -fn main() { - // ANCHOR: here - let dice_roll = 9; - match dice_roll { - 3 => add_fancy_hat(), - 7 => remove_fancy_hat(), - _ => (), - } - - fn add_fancy_hat() {} - fn remove_fancy_hat() {} - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs deleted file mode 100644 index 591e24557..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-01/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -mod front_of_house { - mod hosting { - fn add_to_waitlist() {} - - fn seat_at_table() {} - } - - mod serving { - fn take_order() {} - - fn serve_order() {} - - fn take_payment() {} - } -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-03/output.txt b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-03/output.txt deleted file mode 100644 index 2d06c7fd1..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-03/output.txt +++ /dev/null @@ -1,32 +0,0 @@ -$ 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(); - | ^^^^^^^ --------------- function `add_to_waitlist` is not publicly re-exported - | | - | private module - | -note: the module `hosting` is defined here - --> src/lib.rs:2:5 - | -2 | mod hosting { - | ^^^^^^^^^^^ - -error[E0603]: module `hosting` is private - --> src/lib.rs:12:21 - | -12 | front_of_house::hosting::add_to_waitlist(); - | ^^^^^^^ --------------- function `add_to_waitlist` is not publicly re-exported - | | - | private module - | -note: the module `hosting` is defined here - --> src/lib.rs:2:5 - | -2 | mod hosting { - | ^^^^^^^^^^^ - -For more information about this error, try `rustc --explain E0603`. -error: could not compile `restaurant` (lib) due to 2 previous errors diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs deleted file mode 100644 index 0b8a43c6b..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-03/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch07-managing-growing-projects/listing-07-05/output.txt b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-05/output.txt deleted file mode 100644 index 98d8d6e2a..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-05/output.txt +++ /dev/null @@ -1,28 +0,0 @@ -$ cargo build - Compiling restaurant v0.1.0 (file:///projects/restaurant) -error[E0603]: function `add_to_waitlist` is private - --> src/lib.rs:9:37 - | -9 | crate::front_of_house::hosting::add_to_waitlist(); - | ^^^^^^^^^^^^^^^ private function - | -note: the function `add_to_waitlist` is defined here - --> src/lib.rs:3:9 - | -3 | fn add_to_waitlist() {} - | ^^^^^^^^^^^^^^^^^^^^ - -error[E0603]: function `add_to_waitlist` is private - --> src/lib.rs:12:30 - | -12 | front_of_house::hosting::add_to_waitlist(); - | ^^^^^^^^^^^^^^^ private function - | -note: the function `add_to_waitlist` is defined here - --> src/lib.rs:3:9 - | -3 | fn add_to_waitlist() {} - | ^^^^^^^^^^^^^^^^^^^^ - -For more information about this error, try `rustc --explain E0603`. -error: could not compile `restaurant` (lib) due to 2 previous errors diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs deleted file mode 100644 index 05372dbe5..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-05/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs deleted file mode 100644 index 7b89ee7cd..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-07/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -pub fn eat_at_restaurant() { - // Absolute path - crate::front_of_house::hosting::add_to_waitlist(); - - // Relative path - front_of_house::hosting::add_to_waitlist(); -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs deleted file mode 100644 index b3ddb4f0f..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-08/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn deliver_order() {} - -mod back_of_house { - fn fix_incorrect_order() { - cook_order(); - super::deliver_order(); - } - - fn cook_order() {} -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs deleted file mode 100644 index 92c4695d5..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-09/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/rustbook-en/listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs deleted file mode 100644 index 908f1dfb7..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-10/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs deleted file mode 100644 index cf31a9c97..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -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(); -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-12/output.txt b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-12/output.txt deleted file mode 100644 index 0eda25312..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-12/output.txt +++ /dev/null @@ -1,24 +0,0 @@ -$ cargo build - Compiling restaurant v0.1.0 (file:///projects/restaurant) -error[E0433]: failed to resolve: use of undeclared crate or module `hosting` - --> src/lib.rs:11:9 - | -11 | hosting::add_to_waitlist(); - | ^^^^^^^ use of undeclared crate or module `hosting` - | -help: consider importing this module through its public re-export - | -10 + use crate::hosting; - | - -warning: unused import: `crate::front_of_house::hosting` - --> src/lib.rs:7:5 - | -7 | use crate::front_of_house::hosting; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default - -For more information about this error, try `rustc --explain E0433`. -warning: `restaurant` (lib) generated 1 warning -error: could not compile `restaurant` (lib) due to 1 previous error; 1 warning emitted diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs deleted file mode 100644 index afc759423..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -use crate::front_of_house::hosting; - -mod customer { - pub fn eat_at_restaurant() { - hosting::add_to_waitlist(); - } -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs deleted file mode 100644 index c72994efe..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -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(); -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-14/src/main.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-14/src/main.rs deleted file mode 100644 index 4379e7c79..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-14/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::collections::HashMap; - -fn main() { - let mut map = HashMap::new(); - map.insert(1, 2); -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs deleted file mode 100644 index 45cf1bac9..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -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(); -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-18/src/main.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-18/src/main.rs deleted file mode 100644 index 2f69412a4..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-18/src/main.rs +++ /dev/null @@ -1,32 +0,0 @@ -use rand::Rng; -// ANCHOR: here -// --snip-- -use std::{cmp::Ordering, io}; -// --snip-- -// ANCHOR_END: here - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs deleted file mode 100644 index 6875dfdb6..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/front_of_house.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod hosting { - pub fn add_to_waitlist() {} -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs deleted file mode 100644 index d6769556a..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/listing-07-21-and-22/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod front_of_house; - -pub use crate::front_of_house::hosting; - -pub fn eat_at_restaurant() { - hosting::add_to_waitlist(); -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs b/rustbook-en/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs deleted file mode 100644 index 3a02c9963..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -use rand::Rng; -// ANCHOR: here -// --snip-- -use std::cmp::Ordering; -use std::io; -// --snip-- -// ANCHOR_END: here - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs b/rustbook-en/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs deleted file mode 100644 index d65f3afd1..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/front_of_house/hosting.rs +++ /dev/null @@ -1 +0,0 @@ -pub fn add_to_waitlist() {} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/lib.rs b/rustbook-en/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/lib.rs deleted file mode 100644 index d6769556a..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/no-listing-02-extracting-hosting/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod front_of_house; - -pub use crate::front_of_house::hosting; - -pub fn eat_at_restaurant() { - hosting::add_to_waitlist(); -} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/output.txt b/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/output.txt deleted file mode 100644 index 04ac6f6c0..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling backyard v0.1.0 (file:///projects/backyard) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.36s - Running `target/debug/backyard` -I'm growing Asparagus! diff --git a/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/src/garden/vegetables.rs b/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/src/garden/vegetables.rs deleted file mode 100644 index b00f785ef..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/src/garden/vegetables.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[derive(Debug)] -pub struct Asparagus {} diff --git a/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/src/main.rs b/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/src/main.rs deleted file mode 100644 index 0d9a0ca92..000000000 --- a/rustbook-en/listings/ch07-managing-growing-projects/quick-reference-example/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::garden::vegetables::Asparagus; - -pub mod garden; - -fn main() { - let plant = Asparagus {}; - println!("I'm growing {plant:?}!"); -} diff --git a/rustbook-en/listings/ch08-common-collections/listing-08-04/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-04/src/main.rs deleted file mode 100644 index fca332de6..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-04/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -fn main() { - // ANCHOR: here - let v = vec![1, 2, 3, 4, 5]; - - let third: &i32 = &v[2]; - println!("The third element is {third}"); - - let third: Option<&i32> = v.get(2); - match third { - Some(third) => println!("The third element is {third}"), - None => println!("There is no third element."), - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch08-common-collections/listing-08-05/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-05/src/main.rs deleted file mode 100644 index 783d9b110..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-05/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-06/output.txt b/rustbook-en/listings/ch08-common-collections/listing-08-06/output.txt deleted file mode 100644 index f98ab1cde..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-06/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling collections v0.1.0 (file:///projects/collections) -error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable - --> src/main.rs:6:5 - | -4 | let first = &v[0]; - | - immutable borrow occurs here -5 | -6 | v.push(6); - | ^^^^^^^^^ mutable borrow occurs here -7 | -8 | println!("The first element is: {first}"); - | ------- immutable borrow later used here - -For more information about this error, try `rustc --explain E0502`. -error: could not compile `collections` (bin "collections") due to 1 previous error diff --git a/rustbook-en/listings/ch08-common-collections/listing-08-06/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-06/src/main.rs deleted file mode 100644 index 653ac27b0..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-06/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-09/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-09/src/main.rs deleted file mode 100644 index c2198883b..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-09/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-12/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-12/src/main.rs deleted file mode 100644 index d9e5e768a..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-12/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-13/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-13/src/main.rs deleted file mode 100644 index b81e37453..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-13/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - // ANCHOR: here - let s = String::from("initial contents"); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch08-common-collections/listing-08-14/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-14/src/main.rs deleted file mode 100644 index bf737ab44..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-14/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-18/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-18/src/main.rs deleted file mode 100644 index 93939a69f..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-18/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-19/output.txt b/rustbook-en/listings/ch08-common-collections/listing-08-19/output.txt deleted file mode 100644 index 75d9a56f5..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-19/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo run - Compiling collections v0.1.0 (file:///projects/collections) -error[E0277]: the type `str` cannot be indexed by `{integer}` - --> src/main.rs:3:16 - | -3 | let h = s1[0]; - | ^ string indices are ranges of `usize` - | - = help: the trait `SliceIndex` is not implemented for `{integer}`, which is required by `String: Index<_>` - = note: you can use `.chars().nth()` or `.bytes().nth()` - for more information, see chapter 8 in The Book: - = help: the trait `SliceIndex<[_]>` is implemented for `usize` - = help: for that trait implementation, expected `[_]`, found `str` - = note: required for `String` to implement `Index<{integer}>` - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `collections` (bin "collections") due to 1 previous error diff --git a/rustbook-en/listings/ch08-common-collections/listing-08-19/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-19/src/main.rs deleted file mode 100644 index fc08e9cea..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-19/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - // ANCHOR: here - let s1 = String::from("hello"); - let h = s1[0]; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch08-common-collections/listing-08-20/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-20/src/main.rs deleted file mode 100644 index 54c201091..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-20/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-21/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-21/src/main.rs deleted file mode 100644 index 07551549d..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-21/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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).copied().unwrap_or(0); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch08-common-collections/listing-08-22/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-22/src/main.rs deleted file mode 100644 index 2b2a73f94..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-22/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-23/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-23/src/main.rs deleted file mode 100644 index 29025b417..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-23/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-24/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-24/src/main.rs deleted file mode 100644 index 013895632..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-24/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/listing-08-25/src/main.rs b/rustbook-en/listings/ch08-common-collections/listing-08-25/src/main.rs deleted file mode 100644 index 84dd1cd4b..000000000 --- a/rustbook-en/listings/ch08-common-collections/listing-08-25/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs b/rustbook-en/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs deleted file mode 100644 index bb13c86f1..000000000 --- a/rustbook-en/listings/ch08-common-collections/no-listing-03-iterate-over-hashmap/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt b/rustbook-en/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt deleted file mode 100644 index de65b05c0..000000000 --- a/rustbook-en/listings/ch08-common-collections/output-only-01-not-char-boundary/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling collections v0.1.0 (file:///projects/collections) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s - Running `target/debug/collections` -thread 'main' panicked at src/main.rs:4:19: -byte index 1 is not a char boundary; it is inside 'З' (bytes 0..2) of `Здравствуйте` -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/rustbook-en/listings/ch08-common-collections/output-only-01-not-char-boundary/src/main.rs b/rustbook-en/listings/ch08-common-collections/output-only-01-not-char-boundary/src/main.rs deleted file mode 100644 index 9283ff5bd..000000000 --- a/rustbook-en/listings/ch08-common-collections/output-only-01-not-char-boundary/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let hello = "Здравствуйте"; - - let s = &hello[0..1]; -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-01/output.txt b/rustbook-en/listings/ch09-error-handling/listing-09-01/output.txt deleted file mode 100644 index 5f4def009..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-01/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling panic v0.1.0 (file:///projects/panic) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s - Running `target/debug/panic` -thread 'main' panicked at src/main.rs:4:6: -index out of bounds: the len is 3 but the index is 99 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-03/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-03/src/main.rs deleted file mode 100644 index 2342904ed..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-03/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::fs::File; - -fn main() { - let greeting_file_result = File::open("hello.txt"); -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-04/output.txt b/rustbook-en/listings/ch09-error-handling/listing-09-04/output.txt deleted file mode 100644 index b36bdc05f..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-04/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling error-handling v0.1.0 (file:///projects/error-handling) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.73s - Running `target/debug/error-handling` -thread 'main' panicked at src/main.rs:8:23: -Problem opening the file: Os { code: 2, kind: NotFound, message: "No such file or directory" } -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-04/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-04/src/main.rs deleted file mode 100644 index 832f57f0e..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-04/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::fs::File; - -fn main() { - let greeting_file_result = File::open("hello.txt"); - - let greeting_file = match greeting_file_result { - Ok(file) => file, - Err(error) => panic!("Problem opening the file: {error:?}"), - }; -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-05/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-05/src/main.rs deleted file mode 100644 index e0bc55c3f..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-05/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::fs::File; -use std::io::ErrorKind; - -fn main() { - let greeting_file_result = File::open("hello.txt"); - - let greeting_file = match greeting_file_result { - 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/rustbook-en/listings/ch09-error-handling/listing-09-06/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-06/src/main.rs deleted file mode 100644 index a70734cb5..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-06/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -// ANCHOR: here -use std::fs::File; -use std::io::{self, Read}; - -fn read_username_from_file() -> Result { - let username_file_result = File::open("hello.txt"); - - let mut username_file = match username_file_result { - Ok(file) => file, - Err(e) => return Err(e), - }; - - let mut username = String::new(); - - match username_file.read_to_string(&mut username) { - Ok(_) => Ok(username), - Err(e) => Err(e), - } -} -// ANCHOR_END: here - -fn main() { - let username = read_username_from_file().expect("Unable to get username"); -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-07/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-07/src/main.rs deleted file mode 100644 index 0295949d2..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-07/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -// ANCHOR: here -use std::fs::File; -use std::io::{self, Read}; - -fn read_username_from_file() -> Result { - let mut username_file = File::open("hello.txt")?; - let mut username = String::new(); - username_file.read_to_string(&mut username)?; - Ok(username) -} -// ANCHOR_END: here - -fn main() { - let username = read_username_from_file().expect("Unable to get username"); -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-08/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-08/src/main.rs deleted file mode 100644 index ca672caad..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-08/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -// ANCHOR: here -use std::fs::File; -use std::io::{self, Read}; - -fn read_username_from_file() -> Result { - let mut username = String::new(); - - File::open("hello.txt")?.read_to_string(&mut username)?; - - Ok(username) -} -// ANCHOR_END: here - -fn main() { - let username = read_username_from_file().expect("Unable to get username"); -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-09/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-09/src/main.rs deleted file mode 100644 index 4597dc2ee..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-09/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -// ANCHOR: here -use std::fs; -use std::io; - -fn read_username_from_file() -> Result { - fs::read_to_string("hello.txt") -} -// ANCHOR_END: here - -fn main() { - let username = read_username_from_file().expect("Unable to get username"); -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-10/output.txt b/rustbook-en/listings/ch09-error-handling/listing-09-10/output.txt deleted file mode 100644 index dbc9bb13d..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-10/output.txt +++ /dev/null @@ -1,14 +0,0 @@ -$ cargo run - Compiling error-handling v0.1.0 (file:///projects/error-handling) -error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> src/main.rs:4:48 - | -3 | fn main() { - | --------- this function should return `Result` or `Option` to accept `?` -4 | let greeting_file = File::open("hello.txt")?; - | ^ cannot use the `?` operator in a function that returns `()` - | - = help: the trait `FromResidual>` is not implemented for `()` - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `error-handling` (bin "error-handling") due to 1 previous error diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-10/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-10/src/main.rs deleted file mode 100644 index 38b005480..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-10/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::fs::File; - -fn main() { - let greeting_file = File::open("hello.txt")?; -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-11/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-11/src/main.rs deleted file mode 100644 index bd5322786..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-11/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -// ANCHOR: here -fn last_char_of_first_line(text: &str) -> Option { - text.lines().next()?.chars().last() -} -// ANCHOR_END: here - -fn main() { - assert_eq!( - last_char_of_first_line("Hello, world\nHow are you today?"), - Some('d') - ); - - assert_eq!(last_char_of_first_line(""), None); - assert_eq!(last_char_of_first_line("\nhi"), None); -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-12/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-12/src/main.rs deleted file mode 100644 index b0f7445f4..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-12/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::error::Error; -use std::fs::File; - -fn main() -> Result<(), Box> { - let greeting_file = File::open("hello.txt")?; - - Ok(()) -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-13/src/lib.rs b/rustbook-en/listings/ch09-error-handling/listing-09-13/src/lib.rs deleted file mode 100644 index d09383110..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-13/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -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 - } -} diff --git a/rustbook-en/listings/ch09-error-handling/listing-09-13/src/main.rs b/rustbook-en/listings/ch09-error-handling/listing-09-13/src/main.rs deleted file mode 100644 index cda389303..000000000 --- a/rustbook-en/listings/ch09-error-handling/listing-09-13/src/main.rs +++ /dev/null @@ -1,36 +0,0 @@ -use guessing_game::Guess; -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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/rustbook-en/listings/ch09-error-handling/no-listing-01-panic/output.txt b/rustbook-en/listings/ch09-error-handling/no-listing-01-panic/output.txt deleted file mode 100644 index ced4ee719..000000000 --- a/rustbook-en/listings/ch09-error-handling/no-listing-01-panic/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling panic v0.1.0 (file:///projects/panic) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.25s - Running `target/debug/panic` -thread 'main' panicked at src/main.rs:2:5: -crash and burn -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/rustbook-en/listings/ch09-error-handling/no-listing-01-panic/src/main.rs b/rustbook-en/listings/ch09-error-handling/no-listing-01-panic/src/main.rs deleted file mode 100644 index 32a4c243d..000000000 --- a/rustbook-en/listings/ch09-error-handling/no-listing-01-panic/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - panic!("crash and burn"); -} diff --git a/rustbook-en/listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs b/rustbook-en/listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs deleted file mode 100644 index 92e9452f1..000000000 --- a/rustbook-en/listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -use std::fs::File; - -fn main() { - let greeting_file = File::open("hello.txt").unwrap(); -} diff --git a/rustbook-en/listings/ch09-error-handling/no-listing-05-expect/src/main.rs b/rustbook-en/listings/ch09-error-handling/no-listing-05-expect/src/main.rs deleted file mode 100644 index 3d36fa5b1..000000000 --- a/rustbook-en/listings/ch09-error-handling/no-listing-05-expect/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::fs::File; - -fn main() { - let greeting_file = File::open("hello.txt") - .expect("hello.txt should be included in this project"); -} diff --git a/rustbook-en/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs b/rustbook-en/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs deleted file mode 100644 index 3e1835266..000000000 --- a/rustbook-en/listings/ch09-error-handling/no-listing-08-unwrap-that-cant-fail/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - // ANCHOR: here - use std::net::IpAddr; - - let home: IpAddr = "127.0.0.1" - .parse() - .expect("Hardcoded IP address should be valid"); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs b/rustbook-en/listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs deleted file mode 100644 index fc22cbc5e..000000000 --- a/rustbook-en/listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs +++ /dev/null @@ -1,47 +0,0 @@ -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - // 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs deleted file mode 100644 index c9e9bbbd2..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-01/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs deleted file mode 100644 index fd43154a9..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-02/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs deleted file mode 100644 index 1878f5aac..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-03/src/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -// 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs deleted file mode 100644 index ac3b1f7c1..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-04/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -// ANCHOR: here -fn largest_i32(list: &[i32]) -> &i32 { - let mut largest = &list[0]; - - for item in list { - if item > largest { - largest = item; - } - } - - largest -} - -fn largest_char(list: &[char]) -> &char { - let mut largest = &list[0]; - - for item in list { - if item > largest { - largest = item; - } - } - - largest -} - -fn main() { - let number_list = vec![34, 50, 25, 100, 65]; - - let result = largest_i32(&number_list); - println!("The largest number is {result}"); - // ANCHOR_END: here - assert_eq!(*result, 100); - // ANCHOR: here - - let char_list = vec!['y', 'm', 'a', 'q']; - - let result = largest_char(&char_list); - println!("The largest char is {result}"); - // ANCHOR_END: here - assert_eq!(*result, 'y'); - // ANCHOR: here -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt deleted file mode 100644 index 05b96ca17..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo run - Compiling chapter10 v0.1.0 (file:///projects/chapter10) -error[E0369]: binary operation `>` cannot be applied to type `&T` - --> src/main.rs:5:17 - | -5 | if item > largest { - | ---- ^ ------- &T - | | - | &T - | -help: consider restricting type parameter `T` - | -1 | fn largest(list: &[T]) -> &T { - | ++++++++++++++++++++++ - -For more information about this error, try `rustc --explain E0369`. -error: could not compile `chapter10` (bin "chapter10") due to 1 previous error diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs deleted file mode 100644 index 094eb416a..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-05/src/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -fn largest(list: &[T]) -> &T { - let mut largest = &list[0]; - - for item in list { - if item > largest { - largest = item; - } - } - - largest -} - -fn main() { - let number_list = vec![34, 50, 25, 100, 65]; - - let result = largest(&number_list); - println!("The largest number is {result}"); - - let char_list = vec!['y', 'm', 'a', 'q']; - - let result = largest(&char_list); - println!("The largest char is {result}"); -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt deleted file mode 100644 index 5f6c3f465..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo run - Compiling chapter10 v0.1.0 (file:///projects/chapter10) -error[E0308]: mismatched types - --> src/main.rs:7:38 - | -7 | let wont_work = Point { x: 5, y: 4.0 }; - | ^^^ expected integer, found floating-point number - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `chapter10` (bin "chapter10") due to 1 previous error diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs deleted file mode 100644 index 7883db1a6..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-07/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -struct Point { - x: T, - y: T, -} - -fn main() { - let wont_work = Point { x: 5, y: 4.0 }; -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs deleted file mode 100644 index 615b78cfd..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-08/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs deleted file mode 100644 index 4c5b01bdc..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-10/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs deleted file mode 100644 index 86b028108..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-11/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -struct Point { - x: X1, - y: Y1, -} - -impl Point { - fn mixup(self, other: Point) -> Point { - Point { - x: self.x, - y: other.y, - } - } -} - -fn main() { - let p1 = Point { x: 5, y: 10.4 }; - let p2 = Point { x: "Hello", y: 'c' }; - - let p3 = p1.mixup(p2); - - println!("p3.x = {}, p3.y = {}", p3.x, p3.y); -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs deleted file mode 100644 index cfaedb02f..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-12/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait Summary { - fn summarize(&self) -> String; -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs deleted file mode 100644 index c4c83329e..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-13/src/lib.rs +++ /dev/null @@ -1,31 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs deleted file mode 100644 index fb59b84fb..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-14/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/lib.rs deleted file mode 100644 index 669cc5fdc..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-15/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt deleted file mode 100644 index 5c4414226..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-16/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo run - Compiling chapter10 v0.1.0 (file:///projects/chapter10) -error[E0597]: `x` does not live long enough - --> src/main.rs:6:13 - | -5 | let x = 5; - | - binding `x` declared here -6 | r = &x; - | ^^ borrowed value does not live long enough -7 | } - | - `x` dropped here while still borrowed -8 | -9 | println!("r: {r}"); - | --- borrow later used here - -For more information about this error, try `rustc --explain E0597`. -error: could not compile `chapter10` (bin "chapter10") due to 1 previous error diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.lock b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.lock deleted file mode 100644 index 6388bb2b5..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "chapter10" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/rustfmt-ignore b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/rustfmt-ignore deleted file mode 100644 index 9a53c718a..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-17/rustfmt-ignore +++ /dev/null @@ -1,3 +0,0 @@ -We have some weird comments pointing out borrowing scopes that we don't want to change; -unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to -manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.lock b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.lock deleted file mode 100644 index 6388bb2b5..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "chapter10" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/rustfmt-ignore b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/rustfmt-ignore deleted file mode 100644 index 9a53c718a..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-18/rustfmt-ignore +++ /dev/null @@ -1,3 +0,0 @@ -We have some weird comments pointing out borrowing scopes that we don't want to change; -unfortunately I haven't found a way to skip them with rustfmt that works so for now we're going to -manually skip those listings. See: https://github.com/rust-lang/rustfmt/issues/4028 diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs deleted file mode 100644 index 8b64cd000..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-19/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/output.txt b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/output.txt deleted file mode 100644 index a6783b2cc..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling chapter10 v0.1.0 (file:///projects/chapter10) -error[E0106]: missing lifetime specifier - --> src/main.rs:9:33 - | -9 | fn longest(x: &str, y: &str) -> &str { - | ---- ---- ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` -help: consider introducing a named lifetime parameter - | -9 | fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { - | ++++ ++ ++ ++ - -For more information about this error, try `rustc --explain E0106`. -error: could not compile `chapter10` (bin "chapter10") due to 1 previous error diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs deleted file mode 100644 index bf41acd1f..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-20/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs deleted file mode 100644 index 7668de134..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-21/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs deleted file mode 100644 index fc9ff296c..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-22/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/output.txt b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/output.txt deleted file mode 100644 index cb209ab8a..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling chapter10 v0.1.0 (file:///projects/chapter10) -error[E0597]: `string2` does not live long enough - --> src/main.rs:6:44 - | -5 | let string2 = String::from("xyz"); - | ------- binding `string2` declared here -6 | result = longest(string1.as_str(), string2.as_str()); - | ^^^^^^^ borrowed value does not live long enough -7 | } - | - `string2` dropped here while still borrowed -8 | println!("The longest string is {result}"); - | -------- borrow later used here - -For more information about this error, try `rustc --explain E0597`. -error: could not compile `chapter10` (bin "chapter10") due to 1 previous error diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs deleted file mode 100644 index f2e633862..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-23/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -// 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs deleted file mode 100644 index ca3cf86d2..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-24/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -struct ImportantExcerpt<'a> { - part: &'a str, -} - -fn main() { - let novel = String::from("Call me Ishmael. Some years ago..."); - let first_sentence = novel.split('.').next().unwrap(); - let i = ImportantExcerpt { - part: first_sentence, - }; -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs deleted file mode 100644 index 431a261d2..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/listing-10-25/src/main.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/lib.rs deleted file mode 100644 index fa644ca4f..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs deleted file mode 100644 index 0b51121d9..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-01-calling-trait-method/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -use aggregator::{Summary, Tweet}; - -fn main() { - let tweet = Tweet { - username: String::from("horse_ebooks"), - content: String::from( - "of course, as you probably already know, people", - ), - reply: false, - retweet: false, - }; - - println!("1 new tweet: {}", tweet.summarize()); -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/lib.rs deleted file mode 100644 index b6f93a68f..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs deleted file mode 100644 index cc9b98e31..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-02-calling-default-impl/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -use aggregator::{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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs deleted file mode 100644 index 643906f69..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -// 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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs deleted file mode 100644 index e05e8e1c6..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-03-default-impl-calls-other-methods/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use aggregator::{self, Summary, Tweet}; - -fn main() { - // ANCHOR: here - let tweet = Tweet { - username: String::from("horse_ebooks"), - content: String::from( - "of course, as you probably already know, people", - ), - reply: false, - retweet: false, - }; - - println!("1 new tweet: {}", tweet.summarize()); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs deleted file mode 100644 index 261994351..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-04-traits-as-parameters/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs deleted file mode 100644 index a611fce38..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-05-returning-impl-trait/src/lib.rs +++ /dev/null @@ -1,42 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs deleted file mode 100644 index 7cd81d4c3..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-06-impl-trait-returns-one-type/src/lib.rs +++ /dev/null @@ -1,56 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-where-clause/src/lib.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-where-clause/src/lib.rs deleted file mode 100644 index 05b07c31a..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-07-where-clause/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -// ANCHOR: here -fn some_function(t: &T, u: &U) -> i32 -where - T: Display + Clone, - U: Clone + Debug, -{ - // ANCHOR_END: here - unimplemented!() -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs deleted file mode 100644 index 4c35d90e3..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-08-only-one-reference-with-lifetime/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt deleted file mode 100644 index 9b9ef2338..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/output.txt +++ /dev/null @@ -1,13 +0,0 @@ -$ 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 - -For more information about this error, try `rustc --explain E0515`. -error: could not compile `chapter10` (bin "chapter10") due to 1 previous error diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs deleted file mode 100644 index 4d596ec43..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-09-unrelated-lifetime/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs deleted file mode 100644 index c04ec3823..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-10-lifetimes-on-methods/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -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().unwrap(); - let i = ImportantExcerpt { - part: first_sentence, - }; -} diff --git a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs b/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs deleted file mode 100644 index 4b0201fb1..000000000 --- a/rustbook-en/listings/ch10-generic-types-traits-and-lifetimes/no-listing-11-generics-traits-and-lifetimes/src/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -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/rustbook-en/listings/ch11-writing-automated-tests/listing-11-01/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-01/output.txt deleted file mode 100644 index 128309c12..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-01/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.57s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 1 test -test tests::it_works ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs deleted file mode 100644 index 7d12d9af8..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-01/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-03/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-03/output.txt deleted file mode 100644 index cf2c206aa..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-03/output.txt +++ /dev/null @@ -1,23 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.72s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 2 tests -test tests::another ... FAILED -test tests::exploration ... ok - -failures: - ----- tests::another stdout ---- -thread 'tests::another' panicked at src/lib.rs:17:9: -Make this test fail -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::another - -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs deleted file mode 100644 index 866f0238b..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-03/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn exploration() { - let result = add(2, 2); - assert_eq!(result, 4); - } - - #[test] - fn another() { - panic!("Make this test fail"); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs deleted file mode 100644 index 0a03a2b44..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-05/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -#[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 - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-06/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-06/output.txt deleted file mode 100644 index e03add229..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-06/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo test - Compiling rectangle v0.1.0 (file:///projects/rectangle) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s - Running unittests src/lib.rs (target/debug/deps/rectangle-6584c4561e48942e) - -running 1 test -test tests::larger_can_hold_smaller ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests rectangle - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs deleted file mode 100644 index 6ad1512ed..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-06/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -impl Rectangle { - fn can_hold(&self, other: &Rectangle) -> bool { - self.width > other.width && self.height > other.height - } -} - -// ANCHOR: here -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn larger_can_hold_smaller() { - let larger = Rectangle { - width: 8, - height: 7, - }; - let smaller = Rectangle { - width: 5, - height: 1, - }; - - assert!(larger.can_hold(&smaller)); - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-07/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-07/output.txt deleted file mode 100644 index 908ed572c..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-07/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 1 test -test tests::it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs deleted file mode 100644 index 682e8ae17..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-07/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add_two(a: usize) -> usize { - a + 2 -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_adds_two() { - let result = add_two(2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-08/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-08/output.txt deleted file mode 100644 index a5a764377..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-08/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo test - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58s - Running unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d) - -running 1 test -test tests::greater_than_100 - should panic ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests guessing_game - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs deleted file mode 100644 index 54e447bb9..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-08/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -pub struct Guess { - value: i32, -} - -impl Guess { - pub fn new(value: i32) -> Guess { - if value < 1 || value > 100 { - panic!("Guess value must be between 1 and 100, got {value}."); - } - - Guess { value } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[should_panic] - fn greater_than_100() { - Guess::new(200); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs deleted file mode 100644 index 1bb464137..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-09/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -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 = "less than or equal to 100")] - fn greater_than_100() { - Guess::new(200); - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-10/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-10/output.txt deleted file mode 100644 index c67b607d8..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-10/output.txt +++ /dev/null @@ -1,26 +0,0 @@ -$ cargo test - Compiling silly-function v0.1.0 (file:///projects/silly-function) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58s - Running unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166) - -running 2 tests -test tests::this_test_will_fail ... FAILED -test tests::this_test_will_pass ... ok - -failures: - ----- tests::this_test_will_fail stdout ---- -I got the value 8 -thread 'tests::this_test_will_fail' panicked at src/lib.rs:19:9: -assertion `left == right` failed - left: 10 - right: 5 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::this_test_will_fail - -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs deleted file mode 100644 index 3fbde2a1e..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-10/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -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!(value, 10); - } - - #[test] - fn this_test_will_fail() { - let value = prints_and_returns_10(8); - assert_eq!(value, 5); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-11/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-11/output.txt deleted file mode 100644 index a0fe55df1..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-11/output.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.62s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 3 tests -test tests::add_three_and_two ... ok -test tests::add_two_and_two ... ok -test tests::one_hundred ... ok - -test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs deleted file mode 100644 index ccf1eb2a2..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-11/src/lib.rs +++ /dev/null @@ -1,26 +0,0 @@ -pub fn add_two(a: usize) -> usize { - a + 2 -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn add_two_and_two() { - let result = add_two(2); - assert_eq!(result, 4); - } - - #[test] - fn add_three_and_two() { - let result = add_two(3); - assert_eq!(result, 5); - } - - #[test] - fn one_hundred() { - let result = add_two(100); - assert_eq!(result, 102); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs deleted file mode 100644 index 9ba15d8b2..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-12/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -pub fn add_two(a: usize) -> usize { - internal_adder(a, 2) -} - -fn internal_adder(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn internal() { - let result = internal_adder(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/output.txt deleted file mode 100644 index 84344add7..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/output.txt +++ /dev/null @@ -1,23 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 1.31s - Running unittests src/lib.rs (target/debug/deps/adder-1082c4b063a8fbe6) - -running 1 test -test tests::internal ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running tests/integration_test.rs (target/debug/deps/integration_test-1082c4b063a8fbe6) - -running 1 test -test it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs deleted file mode 100644 index 9ba15d8b2..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -pub fn add_two(a: usize) -> usize { - internal_adder(a, 2) -} - -fn internal_adder(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn internal() { - let result = internal_adder(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs b/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs deleted file mode 100644 index d6b88a750..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/listing-11-13/tests/integration_test.rs +++ /dev/null @@ -1,7 +0,0 @@ -use adder::add_two; - -#[test] -fn it_adds_two() { - let result = add_two(2); - assert_eq!(result, 4); -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt deleted file mode 100644 index 79d3ae25c..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.59s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 1 test -test tests::exploration ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs deleted file mode 100644 index 5be58b93f..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-01-changing-test-name/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn exploration() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt deleted file mode 100644 index 63044036d..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo test - Compiling rectangle v0.1.0 (file:///projects/rectangle) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s - Running unittests src/lib.rs (target/debug/deps/rectangle-6584c4561e48942e) - -running 2 tests -test tests::larger_can_hold_smaller ... ok -test tests::smaller_cannot_hold_larger ... ok - -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests rectangle - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs deleted file mode 100644 index ee4fc45b9..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-02-adding-another-rectangle-test/src/lib.rs +++ /dev/null @@ -1,49 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -impl Rectangle { - fn can_hold(&self, other: &Rectangle) -> bool { - self.width > other.width && self.height > other.height - } -} - -// ANCHOR: here -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn larger_can_hold_smaller() { - // --snip-- - // ANCHOR_END: here - let larger = Rectangle { - width: 8, - height: 7, - }; - let smaller = Rectangle { - width: 5, - height: 1, - }; - - assert!(larger.can_hold(&smaller)); - // ANCHOR: here - } - - #[test] - fn smaller_cannot_hold_larger() { - let larger = Rectangle { - width: 8, - height: 7, - }; - let smaller = Rectangle { - width: 5, - height: 1, - }; - - assert!(!smaller.can_hold(&larger)); - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt deleted file mode 100644 index 6d616db37..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt +++ /dev/null @@ -1,23 +0,0 @@ -$ cargo test - Compiling rectangle v0.1.0 (file:///projects/rectangle) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s - Running unittests src/lib.rs (target/debug/deps/rectangle-6584c4561e48942e) - -running 2 tests -test tests::larger_can_hold_smaller ... FAILED -test tests::smaller_cannot_hold_larger ... ok - -failures: - ----- tests::larger_can_hold_smaller stdout ---- -thread 'tests::larger_can_hold_smaller' panicked at src/lib.rs:28:9: -assertion failed: larger.can_hold(&smaller) -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::larger_can_hold_smaller - -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs deleted file mode 100644 index f5968fcaf..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/src/lib.rs +++ /dev/null @@ -1,47 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -// ANCHOR: here -// --snip-- -impl Rectangle { - fn can_hold(&self, other: &Rectangle) -> bool { - self.width < other.width && self.height > other.height - } -} -// ANCHOR_END: here - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn larger_can_hold_smaller() { - let larger = Rectangle { - width: 8, - height: 7, - }; - let smaller = Rectangle { - width: 5, - height: 1, - }; - - assert!(larger.can_hold(&smaller)); - } - - #[test] - fn smaller_cannot_hold_larger() { - let larger = Rectangle { - width: 8, - height: 7, - }; - let smaller = Rectangle { - width: 5, - height: 1, - }; - - assert!(!smaller.can_hold(&larger)); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt deleted file mode 100644 index 927f89144..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt +++ /dev/null @@ -1,24 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.61s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 1 test -test tests::it_adds_two ... FAILED - -failures: - ----- tests::it_adds_two stdout ---- -thread 'tests::it_adds_two' panicked at src/lib.rs:12:9: -assertion `left == right` failed - left: 5 - right: 4 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::it_adds_two - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs deleted file mode 100644 index aed772b0e..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -// ANCHOR: here -pub fn add_two(a: usize) -> usize { - a + 3 -} -// ANCHOR_END: here - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_adds_two() { - let result = add_two(2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs deleted file mode 100644 index 433cf148e..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-05-greeter/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn greeting(name: &str) -> String { - format!("Hello {name}!") -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn greeting_contains_name() { - let result = greeting("Carol"); - assert!(result.contains("Carol")); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt deleted file mode 100644 index 0a7d44dce..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt +++ /dev/null @@ -1,22 +0,0 @@ -$ cargo test - Compiling greeter v0.1.0 (file:///projects/greeter) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.91s - Running unittests src/lib.rs (target/debug/deps/greeter-170b942eb5bf5e3a) - -running 1 test -test tests::greeting_contains_name ... FAILED - -failures: - ----- tests::greeting_contains_name stdout ---- -thread 'tests::greeting_contains_name' panicked at src/lib.rs:12:9: -assertion failed: result.contains("Carol") -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::greeting_contains_name - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs deleted file mode 100644 index 6f28fc52a..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -// ANCHOR: here -pub fn greeting(name: &str) -> String { - String::from("Hello!") -} -// ANCHOR_END: here - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn greeting_contains_name() { - let result = greeting("Carol"); - assert!(result.contains("Carol")); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt deleted file mode 100644 index d2015d56b..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt +++ /dev/null @@ -1,22 +0,0 @@ -$ cargo test - Compiling greeter v0.1.0 (file:///projects/greeter) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.93s - Running unittests src/lib.rs (target/debug/deps/greeter-170b942eb5bf5e3a) - -running 1 test -test tests::greeting_contains_name ... FAILED - -failures: - ----- tests::greeting_contains_name stdout ---- -thread 'tests::greeting_contains_name' panicked at src/lib.rs:12:9: -Greeting did not contain name, value was `Hello!` -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::greeting_contains_name - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs deleted file mode 100644 index 8bbaca53f..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/rustbook-en/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt deleted file mode 100644 index 9b7ec43f7..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/output.txt +++ /dev/null @@ -1,19 +0,0 @@ -$ cargo test - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.62s - Running unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d) - -running 1 test -test tests::greater_than_100 - should panic ... FAILED - -failures: - ----- tests::greater_than_100 stdout ---- -note: test did not panic as expected - -failures: - tests::greater_than_100 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs deleted file mode 100644 index 0f962fcd7..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-08-guess-with-bug/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -pub struct Guess { - value: i32, -} - -// ANCHOR: here -// --snip-- -impl Guess { - pub fn new(value: i32) -> Guess { - if value < 1 { - panic!("Guess value must be between 1 and 100, got {value}."); - } - - Guess { value } - } -} -// ANCHOR_END: here - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - #[should_panic] - fn greater_than_100() { - Guess::new(200); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt deleted file mode 100644 index f30b55ab1..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt +++ /dev/null @@ -1,24 +0,0 @@ -$ cargo test - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.66s - Running unittests src/lib.rs (target/debug/deps/guessing_game-57d70c3acb738f4d) - -running 1 test -test tests::greater_than_100 - should panic ... FAILED - -failures: - ----- tests::greater_than_100 stdout ---- -thread 'tests::greater_than_100' panicked at src/lib.rs:12:13: -Guess value must be greater than or equal to 1, got 200. -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -note: panic did not contain expected string - panic message: `"Guess value must be greater than or equal to 1, got 200."`, - expected substring: `"less than or equal to 100"` - -failures: - tests::greater_than_100 - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs deleted file mode 100644 index fb5fc0e77..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -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 = "less than or equal to 100")] - fn greater_than_100() { - Guess::new(200); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs deleted file mode 100644 index c31cdcae4..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-10-result-in-tests/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - // ANCHOR: here - #[test] - fn it_works() -> Result<(), String> { - let result = add(2, 2); - - if result == 4 { - Ok(()) - } else { - Err(String::from("two plus two does not equal four")) - } - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt deleted file mode 100644 index bc40c96eb..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.60s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 2 tests -test tests::expensive_test ... ignored -test tests::it_works ... ok - -test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs deleted file mode 100644 index 0c8b38def..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-11-ignore-a-test/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -// ANCHOR: here -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } - - #[test] - #[ignore] - fn expensive_test() { - // code that takes an hour to run - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt deleted file mode 100644 index e25839459..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/output.txt +++ /dev/null @@ -1,29 +0,0 @@ -$ cargo test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.89s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 1 test -test tests::internal ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running tests/common.rs (target/debug/deps/common-92948b65e88960b4) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running tests/integration_test.rs (target/debug/deps/integration_test-92948b65e88960b4) - -running 1 test -test it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs deleted file mode 100644 index 9ba15d8b2..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -pub fn add_two(a: usize) -> usize { - internal_adder(a, 2) -} - -fn internal_adder(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn internal() { - let result = internal_adder(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs deleted file mode 100644 index d6b88a750..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-12-shared-test-code-problem/tests/integration_test.rs +++ /dev/null @@ -1,7 +0,0 @@ -use adder::add_two; - -#[test] -fn it_adds_two() { - let result = add_two(2); - assert_eq!(result, 4); -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs deleted file mode 100644 index 9ba15d8b2..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -pub fn add_two(a: usize) -> usize { - internal_adder(a, 2) -} - -fn internal_adder(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn internal() { - let result = internal_adder(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs b/rustbook-en/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs deleted file mode 100644 index d18b5b689..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/no-listing-13-fix-shared-test-code-problem/tests/integration_test.rs +++ /dev/null @@ -1,11 +0,0 @@ -use adder::add_two; - -mod common; - -#[test] -fn it_adds_two() { - common::setup(); - - let result = add_two(2); - assert_eq!(result, 4); -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt deleted file mode 100644 index 58f1ff4a5..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt +++ /dev/null @@ -1,35 +0,0 @@ -$ cargo test -- --show-output - Compiling silly-function v0.1.0 (file:///projects/silly-function) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.60s - Running unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166) - -running 2 tests -test tests::this_test_will_fail ... FAILED -test tests::this_test_will_pass ... ok - -successes: - ----- tests::this_test_will_pass stdout ---- -I got the value 4 - - -successes: - tests::this_test_will_pass - -failures: - ----- tests::this_test_will_fail stdout ---- -I got the value 8 -thread 'tests::this_test_will_fail' panicked at src/lib.rs:19:9: -assertion `left == right` failed - left: 5 - right: 10 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::this_test_will_fail - -test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-01-show-output/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/output-only-01-show-output/src/lib.rs deleted file mode 100644 index 462d22470..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-01-show-output/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -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/rustbook-en/listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt deleted file mode 100644 index 47e2a478e..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-02-single-test/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo test one_hundred - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.69s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 1 test -test tests::one_hundred ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-02-single-test/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/output-only-02-single-test/src/lib.rs deleted file mode 100644 index f56715263..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-02-single-test/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -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/rustbook-en/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt deleted file mode 100644 index d08940aee..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/output.txt +++ /dev/null @@ -1,11 +0,0 @@ -$ cargo test add - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.61s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 2 tests -test tests::add_three_and_two ... ok -test tests::add_two_and_two ... ok - -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/src/lib.rs deleted file mode 100644 index f56715263..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-03-multiple-tests/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -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/rustbook-en/listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt deleted file mode 100644 index 4c7782d07..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-04-running-ignored/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo test -- --ignored - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.61s - Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4) - -running 1 test -test expensive_test ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - - Doc-tests adder - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs deleted file mode 100644 index 2290c699d..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-04-running-ignored/src/lib.rs +++ /dev/null @@ -1,12 +0,0 @@ -// ANCHOR: here -#[test] -fn it_works() { - assert_eq!(2 + 2, 4); -} - -#[test] -#[ignore] -fn expensive_test() { - // code that takes an hour to run -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt b/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt deleted file mode 100644 index 2745d0f81..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo test --test integration_test - Compiling adder v0.1.0 (file:///projects/adder) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.64s - Running tests/integration_test.rs (target/debug/deps/integration_test-82e7799c1bc62298) - -running 1 test -test it_adds_two ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs b/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs deleted file mode 100644 index 9ba15d8b2..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -pub fn add_two(a: usize) -> usize { - internal_adder(a, 2) -} - -fn internal_adder(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn internal() { - let result = internal_adder(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs b/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs deleted file mode 100644 index d6b88a750..000000000 --- a/rustbook-en/listings/ch11-writing-automated-tests/output-only-05-single-integration/tests/integration_test.rs +++ /dev/null @@ -1,7 +0,0 @@ -use adder::add_two; - -#[test] -fn it_adds_two() { - let result = add_two(2); - assert_eq!(result, 4); -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-01/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-01/output.txt deleted file mode 100644 index d2abb056b..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-01/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.61s - Running `target/debug/minigrep` -[src/main.rs:5:5] args = [ - "target/debug/minigrep", -] diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-01/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-01/src/main.rs deleted file mode 100644 index ae7def53d..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-01/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::env; - -fn main() { - let args: Vec = env::args().collect(); - dbg!(args); -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-02/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-02/output.txt deleted file mode 100644 index ad87dcf06..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-02/output.txt +++ /dev/null @@ -1,6 +0,0 @@ -$ cargo run -- test sample.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s - Running `target/debug/minigrep test sample.txt` -Searching for test -In file sample.txt diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-02/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-02/src/main.rs deleted file mode 100644 index afc3c3c9f..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-02/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -use std::env; - -fn main() { - let args: Vec = env::args().collect(); - - let query = &args[1]; - let file_path = &args[2]; - - println!("Searching for {query}"); - println!("In file {file_path}"); -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-03/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-03/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-03/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-03/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-03/src/main.rs deleted file mode 100644 index afc3c3c9f..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-03/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -use std::env; - -fn main() { - let args: Vec = env::args().collect(); - - let query = &args[1]; - let file_path = &args[2]; - - println!("Searching for {query}"); - println!("In file {file_path}"); -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-04/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-04/output.txt deleted file mode 100644 index d8cfe392d..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-04/output.txt +++ /dev/null @@ -1,17 +0,0 @@ -$ cargo run -- the poem.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [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/rustbook-en/listings/ch12-an-io-project/listing-12-04/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-04/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-04/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-04/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-04/src/main.rs deleted file mode 100644 index f34324979..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-04/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -// 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 file_path = &args[2]; - - println!("Searching for {query}"); - // ANCHOR: here - println!("In file {file_path}"); - - let contents = fs::read_to_string(file_path) - .expect("Should have been able to read the file"); - - println!("With text:\n{contents}"); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-05/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-05/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-05/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-05/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-05/src/main.rs deleted file mode 100644 index 838cacf39..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-05/src/main.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::env; -use std::fs; - -// ANCHOR: here -fn main() { - let args: Vec = env::args().collect(); - - let (query, file_path) = parse_config(&args); - - // --snip-- - // ANCHOR_END: here - - println!("Searching for {query}"); - println!("In file {file_path}"); - - let contents = fs::read_to_string(file_path) - .expect("Should have been able to read the file"); - - println!("With text:\n{contents}"); - // ANCHOR: here -} - -fn parse_config(args: &[String]) -> (&str, &str) { - let query = &args[1]; - let file_path = &args[2]; - - (query, file_path) -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-06/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-06/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-06/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-06/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-06/src/main.rs deleted file mode 100644 index c77e848d8..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-06/src/main.rs +++ /dev/null @@ -1,34 +0,0 @@ -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.file_path); - - let contents = fs::read_to_string(config.file_path) - .expect("Should have been able to read the file"); - - // --snip-- - // ANCHOR_END: here - - println!("With text:\n{contents}"); - // ANCHOR: here -} - -struct Config { - query: String, - file_path: String, -} - -fn parse_config(args: &[String]) -> Config { - let query = args[1].clone(); - let file_path = args[2].clone(); - - Config { query, file_path } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-07/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-07/output.txt deleted file mode 100644 index e14b954de..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-07/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s - Running `target/debug/minigrep` -thread 'main' panicked at src/main.rs:27:21: -index out of bounds: the len is 1 but the index is 1 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-07/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-07/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-07/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-07/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-07/src/main.rs deleted file mode 100644 index ff6c29420..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-07/src/main.rs +++ /dev/null @@ -1,40 +0,0 @@ -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.file_path); - - let contents = fs::read_to_string(config.file_path) - .expect("Should have been able to read the file"); - - println!("With text:\n{contents}"); - // ANCHOR: here - - // --snip-- -} - -// --snip-- - -// ANCHOR_END: here -struct Config { - query: String, - file_path: String, -} - -// ANCHOR: here -impl Config { - fn new(args: &[String]) -> Config { - let query = args[1].clone(); - let file_path = args[2].clone(); - - Config { query, file_path } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-08/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-08/output.txt deleted file mode 100644 index c1aa1a93f..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-08/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s - Running `target/debug/minigrep` -thread 'main' panicked at src/main.rs:26:13: -not enough arguments -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-08/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-08/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-08/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-08/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-08/src/main.rs deleted file mode 100644 index cecd15abf..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-08/src/main.rs +++ /dev/null @@ -1,38 +0,0 @@ -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.file_path); - - let contents = fs::read_to_string(config.file_path) - .expect("Should have been able to read the file"); - - println!("With text:\n{contents}"); -} - -struct Config { - query: String, - file_path: 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 file_path = args[2].clone(); - - Config { query, file_path } - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-09/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-09/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-09/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-09/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-09/src/main.rs deleted file mode 100644 index 3418e718c..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-09/src/main.rs +++ /dev/null @@ -1,36 +0,0 @@ -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.file_path); - - let contents = fs::read_to_string(config.file_path) - .expect("Should have been able to read the file"); - - println!("With text:\n{contents}"); -} - -struct Config { - query: String, - file_path: String, -} - -// ANCHOR: here -impl Config { - fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-10/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-10/output.txt deleted file mode 100644 index c5e085b45..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-10/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s - Running `target/debug/minigrep` -Problem parsing arguments: not enough arguments diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-10/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-10/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-10/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-10/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-10/src/main.rs deleted file mode 100644 index ab6d3e548..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-10/src/main.rs +++ /dev/null @@ -1,42 +0,0 @@ -use std::env; -use std::fs; -// ANCHOR: here -use std::process; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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.file_path); - - let contents = fs::read_to_string(config.file_path) - .expect("Should have been able to read the file"); - - println!("With text:\n{contents}"); -} - -struct Config { - query: String, - file_path: String, -} - -impl Config { - fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-11/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-11/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-11/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-11/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-11/src/main.rs deleted file mode 100644 index 3f476b975..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-11/src/main.rs +++ /dev/null @@ -1,50 +0,0 @@ -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::build(&args).unwrap_or_else(|err| { - println!("Problem parsing arguments: {err}"); - process::exit(1); - }); - - // ANCHOR: here - println!("Searching for {}", config.query); - println!("In file {}", config.file_path); - - run(config); -} - -fn run(config: Config) { - let contents = fs::read_to_string(config.file_path) - .expect("Should have been able to read the file"); - - println!("With text:\n{contents}"); -} - -// --snip-- -// ANCHOR_END: here - -struct Config { - query: String, - file_path: String, -} - -impl Config { - fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-12/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-12/output.txt deleted file mode 100644 index 6c5e67ba4..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-12/output.txt +++ /dev/null @@ -1,31 +0,0 @@ -$ cargo run -- the poem.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) -warning: unused `Result` that must be used - --> src/main.rs:19:5 - | -19 | run(config); - | ^^^^^^^^^^^ - | - = note: this `Result` may be an `Err` variant, which should be handled - = note: `#[warn(unused_must_use)]` on by default -help: use `let _ = ...` to ignore the resulting value - | -19 | let _ = run(config); - | +++++++ - -warning: `minigrep` (bin "minigrep") generated 1 warning - Finished `dev` profile [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/rustbook-en/listings/ch12-an-io-project/listing-12-12/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-12/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-12/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-12/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-12/src/main.rs deleted file mode 100644 index ab5fdb894..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-12/src/main.rs +++ /dev/null @@ -1,51 +0,0 @@ -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::build(&args).unwrap_or_else(|err| { - println!("Problem parsing arguments: {err}"); - process::exit(1); - }); - - println!("Searching for {}", config.query); - println!("In file {}", config.file_path); - - run(config); -} - -// ANCHOR: here -fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - println!("With text:\n{contents}"); - - Ok(()) -} -// ANCHOR_END: here - -struct Config { - query: String, - file_path: String, -} - -impl Config { - fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-13/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-13/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-13/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-13/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-13/src/lib.rs deleted file mode 100644 index 1a3c48089..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-13/src/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -// ANCHOR: here -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - // --snip-- - // ANCHOR_END: here - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - // ANCHOR: here - } -} - -pub fn run(config: Config) -> Result<(), Box> { - // --snip-- - // ANCHOR_END: here - let contents = fs::read_to_string(config.file_path)?; - - println!("With text:\n{contents}"); - - Ok(()) - // ANCHOR: here -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-13/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-13/src/main.rs deleted file mode 100644 index 09756ca3f..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-13/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::env; -use std::process; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&args).unwrap_or_else(|err| { - println!("Problem parsing arguments: {err}"); - process::exit(1); - }); - - println!("Searching for {}", config.query); - println!("In file {}", config.file_path); - - if let Err(e) = run(config) { - println!("Application error: {e}"); - process::exit(1); - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-14/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-14/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-14/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-14/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-14/src/lib.rs deleted file mode 100644 index 4f3a4e865..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-14/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - println!("With text:\n{contents}"); - - Ok(()) -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-14/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-14/src/main.rs deleted file mode 100644 index 3b76009b5..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-14/src/main.rs +++ /dev/null @@ -1,29 +0,0 @@ -// 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::build(&args).unwrap_or_else(|err| { - println!("Problem parsing arguments: {err}"); - process::exit(1); - }); - - println!("Searching for {}", config.query); - println!("In file {}", config.file_path); - - // 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/rustbook-en/listings/ch12-an-io-project/listing-12-15/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-15/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-15/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-15/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-15/src/lib.rs deleted file mode 100644 index 20c4a782b..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-15/src/lib.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - Ok(()) -} - -// ANCHOR: here -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn one_result() { - let query = "duct"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three."; - - assert_eq!(vec!["safe, fast, productive."], search(query, contents)); - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-15/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-15/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-15/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-16/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-16/output.txt deleted file mode 100644 index 9f4c64d29..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-16/output.txt +++ /dev/null @@ -1,24 +0,0 @@ -$ cargo test - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.97s - Running unittests src/lib.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) - -running 1 test -test tests::one_result ... FAILED - -failures: - ----- tests::one_result stdout ---- -thread 'tests::one_result' panicked at src/lib.rs:44:9: -assertion `left == right` failed - left: ["safe, fast, productive."] - right: [] -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::one_result - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-16/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-16/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-16/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-16/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-16/src/lib.rs deleted file mode 100644 index f5e593484..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-16/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - Ok(()) -} - -// ANCHOR: here -pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - vec![] -} -// ANCHOR_END: here - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn one_result() { - let query = "duct"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three."; - - assert_eq!(vec!["safe, fast, productive."], search(query, contents)); - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-16/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-16/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-16/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-17/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-17/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-17/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-17/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-17/src/lib.rs deleted file mode 100644 index cb9fab401..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-17/src/lib.rs +++ /dev/null @@ -1,50 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - 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/rustbook-en/listings/ch12-an-io-project/listing-12-17/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-17/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-17/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-18/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-18/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-18/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-18/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-18/src/lib.rs deleted file mode 100644 index a05d046d7..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-18/src/lib.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - 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/rustbook-en/listings/ch12-an-io-project/listing-12-18/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-18/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-18/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-19/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-19/output.txt deleted file mode 100644 index ed87e4f58..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-19/output.txt +++ /dev/null @@ -1,22 +0,0 @@ -$ cargo test - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `test` profile [unoptimized + debuginfo] target(s) in 1.22s - Running unittests src/lib.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) - -running 1 test -test tests::one_result ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running unittests src/main.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests minigrep - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-19/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-19/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-19/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-19/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-19/src/lib.rs deleted file mode 100644 index f5d3ffa9f..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-19/src/lib.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - 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/rustbook-en/listings/ch12-an-io-project/listing-12-19/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-19/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-19/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-20/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-20/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-20/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-20/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-20/src/lib.rs deleted file mode 100644 index a757f7f55..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-20/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - for line in search(&config.query, &contents) { - println!("{line}"); - } - - Ok(()) -} - -pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - let mut results = Vec::new(); - - for line in contents.lines() { - if line.contains(query) { - results.push(line); - } - } - - results -} - -// ANCHOR: here -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn case_sensitive() { - let query = "duct"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three. -Duct tape."; - - assert_eq!(vec!["safe, fast, productive."], search(query, contents)); - } - - #[test] - fn case_insensitive() { - let query = "rUsT"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three. -Trust me."; - - assert_eq!( - vec!["Rust:", "Trust me."], - search_case_insensitive(query, contents) - ); - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-20/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-20/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-20/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-21/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-21/output.txt deleted file mode 100644 index 945df3fd5..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-21/output.txt +++ /dev/null @@ -1,23 +0,0 @@ -$ cargo test - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `test` profile [unoptimized + debuginfo] target(s) in 1.33s - Running unittests src/lib.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) - -running 2 tests -test tests::case_insensitive ... ok -test tests::case_sensitive ... ok - -test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running unittests src/main.rs (target/debug/deps/minigrep-9cd200e5fac0fc94) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Doc-tests minigrep - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-21/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-21/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-21/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-21/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-21/src/lib.rs deleted file mode 100644 index 3aaa04082..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-21/src/lib.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - for line in search(&config.query, &contents) { - println!("{line}"); - } - - Ok(()) -} - -pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - let mut results = Vec::new(); - - for line in contents.lines() { - if line.contains(query) { - results.push(line); - } - } - - results -} - -// ANCHOR: here -pub fn search_case_insensitive<'a>( - query: &str, - contents: &'a str, -) -> Vec<&'a str> { - let query = query.to_lowercase(); - let mut results = Vec::new(); - - for line in contents.lines() { - if line.to_lowercase().contains(&query) { - results.push(line); - } - } - - results -} -// ANCHOR_END: here - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn case_sensitive() { - let query = "duct"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three. -Duct tape."; - - assert_eq!(vec!["safe, fast, productive."], search(query, contents)); - } - - #[test] - fn case_insensitive() { - let query = "rUsT"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three. -Trust me."; - - assert_eq!( - vec!["Rust:", "Trust me."], - search_case_insensitive(query, contents) - ); - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-21/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-21/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-21/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-22/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-22/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-22/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-22/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-22/src/lib.rs deleted file mode 100644 index c3f4723f1..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-22/src/lib.rs +++ /dev/null @@ -1,101 +0,0 @@ -use std::error::Error; -use std::fs; - -// ANCHOR: here -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} -// ANCHOR_END: here - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -// ANCHOR: there -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&config.query, &contents) - }; - - for line in results { - println!("{line}"); - } - - Ok(()) -} -// ANCHOR_END: there - -pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> { - let mut results = Vec::new(); - - for line in contents.lines() { - if line.contains(query) { - results.push(line); - } - } - - results -} - -pub fn search_case_insensitive<'a>( - query: &str, - contents: &'a str, -) -> Vec<&'a str> { - let query = query.to_lowercase(); - let mut results = Vec::new(); - - for line in contents.lines() { - if line.to_lowercase().contains(&query) { - results.push(line); - } - } - - results -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn case_sensitive() { - let query = "duct"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three. -Duct tape."; - - assert_eq!(vec!["safe, fast, productive."], search(query, contents)); - } - - #[test] - fn case_insensitive() { - let query = "rUsT"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three. -Trust me."; - - assert_eq!( - vec!["Rust:", "Trust me."], - search_case_insensitive(query, contents) - ); - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/listing-12-22/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-22/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-22/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-23/output.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-23/output.txt deleted file mode 100644 index 5c6fc0c53..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-23/output.txt +++ /dev/null @@ -1,6 +0,0 @@ -$ cargo run -- to poem.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [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/rustbook-en/listings/ch12-an-io-project/listing-12-23/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-23/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-23/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-23/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-23/src/lib.rs deleted file mode 100644 index 20eda2197..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-23/src/lib.rs +++ /dev/null @@ -1,110 +0,0 @@ -// ANCHOR: here -use std::env; -// --snip-- - -// ANCHOR_END: here -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -// ANCHOR: here -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} -// ANCHOR_END: here - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch12-an-io-project/listing-12-23/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-23/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-23/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/listing-12-24/poem.txt b/rustbook-en/listings/ch12-an-io-project/listing-12-24/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-24/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/listing-12-24/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-24/src/lib.rs deleted file mode 100644 index 292b09789..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-24/src/lib.rs +++ /dev/null @@ -1,104 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch12-an-io-project/listing-12-24/src/main.rs b/rustbook-en/listings/ch12-an-io-project/listing-12-24/src/main.rs deleted file mode 100644 index 1278a6c17..000000000 --- a/rustbook-en/listings/ch12-an-io-project/listing-12-24/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -// ANCHOR: here -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/poem.txt b/rustbook-en/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs b/rustbook-en/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs deleted file mode 100644 index e51319efe..000000000 --- a/rustbook-en/listings/ch12-an-io-project/no-listing-01-handling-errors-in-main/src/main.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; -use std::process; - -// ANCHOR: here -fn main() { - // --snip-- - - // ANCHOR_END: here - let args: Vec = env::args().collect(); - - let config = Config::build(&args).unwrap_or_else(|err| { - println!("Problem parsing arguments: {err}"); - process::exit(1); - }); - - // ANCHOR: here - println!("Searching for {}", config.query); - println!("In file {}", config.file_path); - - 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.file_path)?; - - println!("With text:\n{contents}"); - - Ok(()) -} - -struct Config { - query: String, - file_path: String, -} - -impl Config { - fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/output.txt b/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/output.txt deleted file mode 100644 index 44b203620..000000000 --- a/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run -- frog poem.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.38s - Running `target/debug/minigrep frog poem.txt` -How public, like a frog diff --git a/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/poem.txt b/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs deleted file mode 100644 index e06eae4cd..000000000 --- a/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -// ANCHOR: here -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - 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/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/main.rs b/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/no-listing-02-using-search-in-run/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/output-only-01-with-args/output.txt b/rustbook-en/listings/ch12-an-io-project/output-only-01-with-args/output.txt deleted file mode 100644 index 5f733a7dd..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-01-with-args/output.txt +++ /dev/null @@ -1,9 +0,0 @@ -$ cargo run -- needle haystack - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.57s - Running `target/debug/minigrep needle haystack` -[src/main.rs:5:5] args = [ - "target/debug/minigrep", - "needle", - "haystack", -] diff --git a/rustbook-en/listings/ch12-an-io-project/output-only-01-with-args/src/main.rs b/rustbook-en/listings/ch12-an-io-project/output-only-01-with-args/src/main.rs deleted file mode 100644 index ae7def53d..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-01-with-args/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::env; - -fn main() { - let args: Vec = env::args().collect(); - dbg!(args); -} diff --git a/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt b/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt deleted file mode 100644 index 7e46576b4..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo build - Compiling minigrep v0.1.0 (file:///projects/minigrep) -error[E0106]: missing lifetime specifier - --> src/lib.rs:28:51 - | -28 | pub fn search(query: &str, contents: &str) -> Vec<&str> { - | ---- ---- ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `query` or `contents` -help: consider introducing a named lifetime parameter - | -28 | pub fn search<'a>(query: &'a str, contents: &'a str) -> Vec<&'a str> { - | ++++ ++ ++ ++ - -For more information about this error, try `rustc --explain E0106`. -error: could not compile `minigrep` (lib) due to 1 previous error diff --git a/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/poem.txt b/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs deleted file mode 100644 index df623bdea..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - Ok(()) -} - -// ANCHOR: here -pub fn search(query: &str, contents: &str) -> Vec<&str> { - vec![] -} -// ANCHOR_END: here - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn one_result() { - let query = "duct"; - let contents = "\ -Rust: -safe, fast, productive. -Pick three."; - - assert_eq!(vec!["safe, fast, productive."], search(query, contents)); - } -} diff --git a/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/main.rs b/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-02-missing-lifetimes/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/output.txt b/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/output.txt deleted file mode 100644 index 704df2590..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run -- body poem.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [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/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/poem.txt b/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs deleted file mode 100644 index e06eae4cd..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -// ANCHOR: here -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - 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/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/src/main.rs b/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-03-multiple-matches/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/output.txt b/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/output.txt deleted file mode 100644 index 57f3a617c..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/output.txt +++ /dev/null @@ -1,4 +0,0 @@ -$ cargo run -- monomorphization poem.txt - Compiling minigrep v0.1.0 (file:///projects/minigrep) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.0s - Running `target/debug/minigrep monomorphization poem.txt` diff --git a/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/poem.txt b/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs b/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs deleted file mode 100644 index e06eae4cd..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - Ok(Config { query, file_path }) - } -} - -// ANCHOR: here -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - 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/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/src/main.rs b/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch12-an-io-project/output-only-04-no-matches/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/poem.txt b/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs deleted file mode 100644 index e54343d24..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/src/lib.rs +++ /dev/null @@ -1,106 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -// ANCHOR: ch13 -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} -// ANCHOR_END: ch13 - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/src/main.rs deleted file mode 100644 index a4f8a7411..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-12-23-reproduced/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/poem.txt b/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs deleted file mode 100644 index 292b09789..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/src/lib.rs +++ /dev/null @@ -1,104 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs deleted file mode 100644 index f9d179c8c..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-12-24-reproduced/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -// ANCHOR: ch13 -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&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/rustbook-en/listings/ch13-functional-features/listing-13-01/output.txt b/rustbook-en/listings/ch13-functional-features/listing-13-01/output.txt deleted file mode 100644 index 28c829f4e..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-01/output.txt +++ /dev/null @@ -1,6 +0,0 @@ -$ cargo run - Compiling shirt-company v0.1.0 (file:///projects/shirt-company) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.27s - Running `target/debug/shirt-company` -The user with preference Some(Red) gets Red -The user with preference None gets Blue diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-01/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-01/src/main.rs deleted file mode 100644 index 2c87d6965..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-01/src/main.rs +++ /dev/null @@ -1,52 +0,0 @@ -#[derive(Debug, PartialEq, Copy, Clone)] -enum ShirtColor { - Red, - Blue, -} - -struct Inventory { - shirts: Vec, -} - -impl Inventory { - fn giveaway(&self, user_preference: Option) -> ShirtColor { - user_preference.unwrap_or_else(|| self.most_stocked()) - } - - fn most_stocked(&self) -> ShirtColor { - let mut num_red = 0; - let mut num_blue = 0; - - for color in &self.shirts { - match color { - ShirtColor::Red => num_red += 1, - ShirtColor::Blue => num_blue += 1, - } - } - if num_red > num_blue { - ShirtColor::Red - } else { - ShirtColor::Blue - } - } -} - -fn main() { - let store = Inventory { - shirts: vec![ShirtColor::Blue, ShirtColor::Red, ShirtColor::Blue], - }; - - let user_pref1 = Some(ShirtColor::Red); - let giveaway1 = store.giveaway(user_pref1); - println!( - "The user with preference {:?} gets {:?}", - user_pref1, giveaway1 - ); - - let user_pref2 = None; - let giveaway2 = store.giveaway(user_pref2); - println!( - "The user with preference {:?} gets {:?}", - user_pref2, giveaway2 - ); -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-02/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-02/src/main.rs deleted file mode 100644 index b3f4cc2c2..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-02/src/main.rs +++ /dev/null @@ -1,33 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-03/output.txt b/rustbook-en/listings/ch13-functional-features/listing-13-03/output.txt deleted file mode 100644 index 16716c3ac..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-03/output.txt +++ /dev/null @@ -1,26 +0,0 @@ -$ cargo run - Compiling closure-example v0.1.0 (file:///projects/closure-example) -error[E0308]: mismatched types - --> src/main.rs:5:29 - | -5 | let n = example_closure(5); - | --------------- ^- help: try using a conversion method: `.to_string()` - | | | - | | expected `String`, found integer - | arguments to this function are incorrect - | -note: expected because the closure was earlier called with an argument of type `String` - --> src/main.rs:4:29 - | -4 | let s = example_closure(String::from("hello")); - | --------------- ^^^^^^^^^^^^^^^^^^^^^ expected because this argument is of type `String` - | | - | in this closure call -note: closure parameter defined here - --> src/main.rs:2:28 - | -2 | let example_closure = |x| x; - | ^ - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `closure-example` (bin "closure-example") due to 1 previous error diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-03/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-03/src/main.rs deleted file mode 100644 index ebb2489bf..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-03/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-04/Cargo.lock b/rustbook-en/listings/ch13-functional-features/listing-13-04/Cargo.lock deleted file mode 100644 index 75ff09e51..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-04/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "workout-app" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-04/output.txt b/rustbook-en/listings/ch13-functional-features/listing-13-04/output.txt deleted file mode 100644 index b04a1a36c..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-04/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo run - Locking 1 package to latest compatible version - Adding closure-example v0.1.0 (/Users/carolnichols/rust/book/tmp/listings/ch13-functional-features/listing-13-04) - Compiling closure-example v0.1.0 (file:///projects/closure-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s - Running `target/debug/closure-example` -Before defining closure: [1, 2, 3] -Before calling closure: [1, 2, 3] -From closure: [1, 2, 3] -After calling closure: [1, 2, 3] diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-04/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-04/src/main.rs deleted file mode 100644 index 19f51a6f7..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-04/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() { - let list = vec![1, 2, 3]; - println!("Before defining closure: {list:?}"); - - let only_borrows = || println!("From closure: {list:?}"); - - println!("Before calling closure: {list:?}"); - only_borrows(); - println!("After calling closure: {list:?}"); -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-05/Cargo.lock b/rustbook-en/listings/ch13-functional-features/listing-13-05/Cargo.lock deleted file mode 100644 index 75ff09e51..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-05/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "workout-app" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-05/output.txt b/rustbook-en/listings/ch13-functional-features/listing-13-05/output.txt deleted file mode 100644 index 1fddf5a98..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-05/output.txt +++ /dev/null @@ -1,8 +0,0 @@ -$ cargo run - Locking 1 package to latest compatible version - Adding closure-example v0.1.0 (/Users/carolnichols/rust/book/tmp/listings/ch13-functional-features/listing-13-05) - Compiling closure-example v0.1.0 (file:///projects/closure-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.43s - Running `target/debug/closure-example` -Before defining closure: [1, 2, 3] -After calling closure: [1, 2, 3, 7] diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-05/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-05/src/main.rs deleted file mode 100644 index f6c2a53de..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-05/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let mut list = vec![1, 2, 3]; - println!("Before defining closure: {list:?}"); - - let mut borrows_mutably = || list.push(7); - - borrows_mutably(); - println!("After calling closure: {list:?}"); -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-06/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-06/src/main.rs deleted file mode 100644 index ee9ca0457..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-06/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::thread; - -fn main() { - let list = vec![1, 2, 3]; - println!("Before defining closure: {list:?}"); - - thread::spawn(move || println!("From thread: {list:?}")) - .join() - .unwrap(); -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-07/output.txt b/rustbook-en/listings/ch13-functional-features/listing-13-07/output.txt deleted file mode 100644 index 8c11d84dc..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-07/output.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.41s - Running `target/debug/rectangles` -[ - Rectangle { - width: 3, - height: 5, - }, - Rectangle { - width: 7, - height: 12, - }, - Rectangle { - width: 10, - height: 1, - }, -] diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-07/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-07/src/main.rs deleted file mode 100644 index e7ab8d340..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-07/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let mut list = [ - Rectangle { width: 10, height: 1 }, - Rectangle { width: 3, height: 5 }, - Rectangle { width: 7, height: 12 }, - ]; - - list.sort_by_key(|r| r.width); - println!("{list:#?}"); -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-08/output.txt b/rustbook-en/listings/ch13-functional-features/listing-13-08/output.txt deleted file mode 100644 index 979868dc3..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-08/output.txt +++ /dev/null @@ -1,20 +0,0 @@ -$ cargo run - Compiling rectangles v0.1.0 (file:///projects/rectangles) -error[E0507]: cannot move out of `value`, a captured variable in an `FnMut` closure - --> src/main.rs:18:30 - | -15 | let value = String::from("closure called"); - | ----- captured outer variable -16 | -17 | list.sort_by_key(|r| { - | --- captured by this `FnMut` closure -18 | sort_operations.push(value); - | ^^^^^ move occurs because `value` has type `String`, which does not implement the `Copy` trait - | -help: consider cloning the value if the performance cost is acceptable - | -18 | sort_operations.push(value.clone()); - | ++++++++ - -For more information about this error, try `rustc --explain E0507`. -error: could not compile `rectangles` (bin "rectangles") due to 1 previous error diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-08/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-08/src/main.rs deleted file mode 100644 index e00fec70f..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-08/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let mut list = [ - Rectangle { width: 10, height: 1 }, - Rectangle { width: 3, height: 5 }, - Rectangle { width: 7, height: 12 }, - ]; - - let mut sort_operations = vec![]; - let value = String::from("closure called"); - - list.sort_by_key(|r| { - sort_operations.push(value); - r.width - }); - println!("{list:#?}"); -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-09/Cargo.lock b/rustbook-en/listings/ch13-functional-features/listing-13-09/Cargo.lock deleted file mode 100644 index e090432bc..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-09/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "cacher" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-09/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-09/src/main.rs deleted file mode 100644 index f007e3c04..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-09/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let mut list = [ - Rectangle { width: 10, height: 1 }, - Rectangle { width: 3, height: 5 }, - Rectangle { width: 7, height: 12 }, - ]; - - let mut num_sort_operations = 0; - list.sort_by_key(|r| { - num_sort_operations += 1; - r.width - }); - println!("{list:#?}, sorted in {num_sort_operations} operations"); -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-10/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-10/src/main.rs deleted file mode 100644 index 55a0dd37e..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-10/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - // ANCHOR: here - let v1 = vec![1, 2, 3]; - - let v1_iter = v1.iter(); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-11/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-11/src/main.rs deleted file mode 100644 index b4e85169a..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-11/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-12/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-13-12/src/lib.rs deleted file mode 100644 index 758284044..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-12/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[cfg(test)] -mod tests { - // ANCHOR: here - #[test] - fn iterator_demonstration() { - let v1 = vec![1, 2, 3]; - - let mut v1_iter = v1.iter(); - - assert_eq!(v1_iter.next(), Some(&1)); - assert_eq!(v1_iter.next(), Some(&2)); - assert_eq!(v1_iter.next(), Some(&3)); - assert_eq!(v1_iter.next(), None); - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-13/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-13-13/src/lib.rs deleted file mode 100644 index d1cb54d0a..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-13/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -#[cfg(test)] -mod tests { - // ANCHOR: here - #[test] - fn iterator_sum() { - let v1 = vec![1, 2, 3]; - - let v1_iter = v1.iter(); - - let total: i32 = v1_iter.sum(); - - assert_eq!(total, 6); - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-14/output.txt b/rustbook-en/listings/ch13-functional-features/listing-13-14/output.txt deleted file mode 100644 index d46dd5c42..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-14/output.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ cargo run - Compiling iterators v0.1.0 (file:///projects/iterators) -warning: unused `Map` that must be used - --> src/main.rs:4:5 - | -4 | v1.iter().map(|x| x + 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: iterators are lazy and do nothing unless consumed - = note: `#[warn(unused_must_use)]` on by default -help: use `let _ = ...` to ignore the resulting value - | -4 | let _ = v1.iter().map(|x| x + 1); - | +++++++ - -warning: `iterators` (bin "iterators") generated 1 warning - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.47s - Running `target/debug/iterators` diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-14/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-14/src/main.rs deleted file mode 100644 index 62a68be9b..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-14/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - // ANCHOR: here - let v1: Vec = vec![1, 2, 3]; - - v1.iter().map(|x| x + 1); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-15/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-15/src/main.rs deleted file mode 100644 index db9025d6f..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-15/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-16/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-13-16/src/lib.rs deleted file mode 100644 index 281c3c9e4..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-16/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -#[derive(PartialEq, Debug)] -struct Shoe { - size: u32, - style: String, -} - -fn shoes_in_size(shoes: Vec, shoe_size: u32) -> Vec { - shoes.into_iter().filter(|s| s.size == shoe_size).collect() -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn filters_by_size() { - let shoes = vec![ - Shoe { - size: 10, - style: String::from("sneaker"), - }, - Shoe { - size: 13, - style: String::from("sandal"), - }, - Shoe { - size: 10, - style: String::from("boot"), - }, - ]; - - let in_my_size = shoes_in_size(shoes, 10); - - assert_eq!( - in_my_size, - vec![ - Shoe { - size: 10, - style: String::from("sneaker") - }, - Shoe { - size: 10, - style: String::from("boot") - }, - ] - ); - } -} diff --git a/rustbook-en/listings/ch13-functional-features/listing-13-18/poem.txt b/rustbook-en/listings/ch13-functional-features/listing-13-18/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-18/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-18/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-13-18/src/lib.rs deleted file mode 100644 index 292b09789..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-18/src/lib.rs +++ /dev/null @@ -1,104 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -impl Config { - pub fn build(args: &[String]) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch13-functional-features/listing-13-18/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-18/src/main.rs deleted file mode 100644 index 40109ef63..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-18/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -// ANCHOR: here -fn main() { - let config = Config::build(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/rustbook-en/listings/ch13-functional-features/listing-13-19/poem.txt b/rustbook-en/listings/ch13-functional-features/listing-13-19/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-19/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-19/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-13-19/src/lib.rs deleted file mode 100644 index 79ae2b8f6..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-19/src/lib.rs +++ /dev/null @@ -1,109 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -// ANCHOR: here -impl Config { - pub fn build( - mut args: impl Iterator, - ) -> Result { - // --snip-- - // ANCHOR_END: here - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch13-functional-features/listing-13-19/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-19/src/main.rs deleted file mode 100644 index 9ac022545..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-19/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let config = Config::build(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/rustbook-en/listings/ch13-functional-features/listing-13-20/poem.txt b/rustbook-en/listings/ch13-functional-features/listing-13-20/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-20/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-20/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-13-20/src/lib.rs deleted file mode 100644 index 4410964a7..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-20/src/lib.rs +++ /dev/null @@ -1,113 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -// ANCHOR: here -impl Config { - pub fn build( - mut args: impl Iterator, - ) -> Result { - args.next(); - - let query = match args.next() { - Some(arg) => arg, - None => return Err("Didn't get a query string"), - }; - - let file_path = match args.next() { - Some(arg) => arg, - None => return Err("Didn't get a file path"), - }; - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} -// ANCHOR_END: here - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch13-functional-features/listing-13-20/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-20/src/main.rs deleted file mode 100644 index 9ac022545..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-20/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let config = Config::build(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/rustbook-en/listings/ch13-functional-features/listing-13-22/poem.txt b/rustbook-en/listings/ch13-functional-features/listing-13-22/poem.txt deleted file mode 100644 index 870752731..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-22/poem.txt +++ /dev/null @@ -1,9 +0,0 @@ -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/rustbook-en/listings/ch13-functional-features/listing-13-22/src/lib.rs b/rustbook-en/listings/ch13-functional-features/listing-13-22/src/lib.rs deleted file mode 100644 index d694669b4..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-22/src/lib.rs +++ /dev/null @@ -1,108 +0,0 @@ -use std::env; -use std::error::Error; -use std::fs; - -pub struct Config { - pub query: String, - pub file_path: String, - pub ignore_case: bool, -} - -impl Config { - pub fn build( - mut args: impl Iterator, - ) -> Result { - args.next(); - - let query = match args.next() { - Some(arg) => arg, - None => return Err("Didn't get a query string"), - }; - - let file_path = match args.next() { - Some(arg) => arg, - None => return Err("Didn't get a file path"), - }; - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} - -pub fn run(config: Config) -> Result<(), Box> { - let contents = fs::read_to_string(config.file_path)?; - - let results = if config.ignore_case { - search_case_insensitive(&config.query, &contents) - } else { - search(&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/rustbook-en/listings/ch13-functional-features/listing-13-22/src/main.rs b/rustbook-en/listings/ch13-functional-features/listing-13-22/src/main.rs deleted file mode 100644 index 9ac022545..000000000 --- a/rustbook-en/listings/ch13-functional-features/listing-13-22/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::env; -use std::process; - -use minigrep::Config; - -fn main() { - let config = Config::build(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/rustbook-en/listings/ch14-more-about-cargo/listing-14-01/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-01/src/lib.rs deleted file mode 100644 index ed7abb727..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-01/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -/// 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/rustbook-en/listings/ch14-more-about-cargo/listing-14-02/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-02/src/lib.rs deleted file mode 100644 index 64c9c439c..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-02/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/rustbook-en/listings/ch14-more-about-cargo/listing-14-03/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-03/src/lib.rs deleted file mode 100644 index bffbe058d..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-03/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -// ANCHOR: here -//! # Art -//! -//! A library for modeling artistic concepts. - -pub mod kinds { - /// The primary colors according to the RYB color model. - pub enum PrimaryColor { - Red, - Yellow, - Blue, - } - - /// The secondary colors according to the RYB color model. - pub enum SecondaryColor { - Orange, - Green, - Purple, - } -} - -pub mod utils { - use crate::kinds::*; - - /// Combines two primary colors in equal amounts to create - /// a secondary color. - pub fn mix(c1: PrimaryColor, c2: PrimaryColor) -> SecondaryColor { - // --snip-- - // ANCHOR_END: here - unimplemented!(); - // ANCHOR: here - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch14-more-about-cargo/listing-14-04/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-04/src/lib.rs deleted file mode 100644 index b077a9a71..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-04/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! # 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/rustbook-en/listings/ch14-more-about-cargo/listing-14-04/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-04/src/main.rs deleted file mode 100644 index b1a4bf792..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-04/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -use art::kinds::PrimaryColor; -use art::utils::mix; - -fn main() { - let red = PrimaryColor::Red; - let yellow = PrimaryColor::Yellow; - mix(red, yellow); -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/listing-14-05/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-05/src/lib.rs deleted file mode 100644 index c5aa9e7b0..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-05/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/rustbook-en/listings/ch14-more-about-cargo/listing-14-06/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-06/src/lib.rs deleted file mode 100644 index daabd006d..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-06/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -//! # 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/rustbook-en/listings/ch14-more-about-cargo/listing-14-06/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-06/src/main.rs deleted file mode 100644 index 51f3b761d..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-06/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -// ANCHOR: here -use art::mix; -use art::PrimaryColor; - -fn main() { - // --snip-- - // ANCHOR_END: here - let red = PrimaryColor::Red; - let yellow = PrimaryColor::Yellow; - mix(red, yellow); - // ANCHOR: here -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs deleted file mode 100644 index 131629490..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/listing-14-07/add/adder/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use add_one; - -fn main() { - let num = 10; - println!("Hello, world! {num} plus one is {}!", add_one::add_one(num)); -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/src/main.rs deleted file mode 100644 index e7a11a969..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/no-listing-01-workspace-with-adder-crate/add/adder/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/src/main.rs deleted file mode 100644 index e7a11a969..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/no-listing-02-workspace-with-two-crates/add/adder/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs deleted file mode 100644 index 7deb7962f..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/no-listing-03-workspace-with-external-dependency/add/adder/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -use add_one; - -fn main() { - let num = 10; - println!( - "Hello, world! {} plus one is {}!", - num, - add_one::add_one(num) - ); -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/src/lib.rs deleted file mode 100644 index 40ceb1285..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/add_one/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs deleted file mode 100644 index 7deb7962f..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/no-listing-04-workspace-with-tests/add/adder/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -use add_one; - -fn main() { - let num = 10; - println!( - "Hello, world! {} plus one is {}!", - num, - add_one::add_one(num) - ); -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/output-only-02-add-one/add/add_one/src/lib.rs b/rustbook-en/listings/ch14-more-about-cargo/output-only-02-add-one/add/add_one/src/lib.rs deleted file mode 100644 index 7d12d9af8..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/output-only-02-add-one/add/add_one/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/src/main.rs deleted file mode 100644 index e7a11a969..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/output-only-02-add-one/add/adder/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/rustbook-en/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs b/rustbook-en/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs deleted file mode 100644 index eb4050dc3..000000000 --- a/rustbook-en/listings/ch14-more-about-cargo/output-only-03-use-rand/add/adder/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -use add_one; -use rand; - -fn main() { - let num = 10; - println!( - "Hello, world! {} plus one is {}!", - num, - add_one::add_one(num) - ); -} diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-02/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-02/src/main.rs deleted file mode 100644 index 84640b9b9..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-02/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -// ANCHOR: here -enum List { - Cons(i32, List), - Nil, -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-03/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-03/output.txt deleted file mode 100644 index 2563fb647..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-03/output.txt +++ /dev/null @@ -1,28 +0,0 @@ -$ 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 { - | ^^^^^^^^^ -2 | Cons(i32, List), - | ---- recursive without indirection - | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle - | -2 | Cons(i32, Box), - | ++++ + - -error[E0391]: cycle detected when computing when `List` needs drop - --> src/main.rs:1:1 - | -1 | enum List { - | ^^^^^^^^^ - | - = note: ...which immediately requires computing when `List` needs drop again - = note: cycle used when computing whether `List` needs drop - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -Some errors have detailed explanations: E0072, E0391. -For more information about an error, try `rustc --explain E0072`. -error: could not compile `cons-list` (bin "cons-list") due to 2 previous errors diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-03/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-03/src/main.rs deleted file mode 100644 index a96f3d7b1..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-03/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-05/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-05/src/main.rs deleted file mode 100644 index 22f7d8338..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-05/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-08/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-08/src/main.rs deleted file mode 100644 index f48594673..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-08/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -// ANCHOR: here -struct MyBox(T); - -impl MyBox { - fn new(x: T) -> MyBox { - MyBox(x) - } -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-09/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-09/output.txt deleted file mode 100644 index a295d2628..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-09/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo run - Compiling deref-example v0.1.0 (file:///projects/deref-example) -error[E0614]: type `MyBox<{integer}>` cannot be dereferenced - --> src/main.rs:14:19 - | -14 | assert_eq!(5, *y); - | ^^ - -For more information about this error, try `rustc --explain E0614`. -error: could not compile `deref-example` (bin "deref-example") due to 1 previous error diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-09/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-09/src/main.rs deleted file mode 100644 index d07f2d78a..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-09/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-10/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-10/src/main.rs deleted file mode 100644 index cce754d08..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-10/src/main.rs +++ /dev/null @@ -1,27 +0,0 @@ -// ANCHOR: here -use std::ops::Deref; - -impl Deref for MyBox { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} -// ANCHOR_END: here - -struct MyBox(T); - -impl MyBox { - fn new(x: T) -> MyBox { - MyBox(x) - } -} - -fn main() { - let x = 5; - let y = MyBox::new(x); - - assert_eq!(5, x); - assert_eq!(5, *y); -} diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-11/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-11/src/main.rs deleted file mode 100644 index 77a88c91f..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-11/src/main.rs +++ /dev/null @@ -1,7 +0,0 @@ -// ANCHOR: here -fn hello(name: &str) { - println!("Hello, {name}!"); -} -// ANCHOR_END: here - -fn main() {} diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-12/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-12/src/main.rs deleted file mode 100644 index 8cd3893cb..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-12/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-13/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-13/src/main.rs deleted file mode 100644 index 9debe2a31..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-13/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-14/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-14/output.txt deleted file mode 100644 index 1393d44b3..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-14/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling drop-example v0.1.0 (file:///projects/drop-example) - Finished `dev` profile [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/rustbook-en/listings/ch15-smart-pointers/listing-15-15/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-15/output.txt deleted file mode 100644 index 8a53b2852..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-15/output.txt +++ /dev/null @@ -1,15 +0,0 @@ -$ cargo run - Compiling drop-example v0.1.0 (file:///projects/drop-example) -error[E0040]: explicit use of destructor method - --> src/main.rs:16:7 - | -16 | c.drop(); - | ^^^^ explicit destructor calls not allowed - | -help: consider using `drop` function - | -16 | drop(c); - | +++++ ~ - -For more information about this error, try `rustc --explain E0040`. -error: could not compile `drop-example` (bin "drop-example") due to 1 previous error diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-16/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-16/output.txt deleted file mode 100644 index f032d84b6..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-16/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling drop-example v0.1.0 (file:///projects/drop-example) - Finished `dev` profile [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/rustbook-en/listings/ch15-smart-pointers/listing-15-17/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-17/output.txt deleted file mode 100644 index 757a65fb5..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-17/output.txt +++ /dev/null @@ -1,14 +0,0 @@ -$ cargo run - Compiling cons-list v0.1.0 (file:///projects/cons-list) -error[E0382]: use of moved value: `a` - --> src/main.rs:11:30 - | -9 | let a = Cons(5, Box::new(Cons(10, Box::new(Nil)))); - | - move occurs because `a` has type `List`, which does not implement the `Copy` trait -10 | let b = Cons(3, Box::new(a)); - | - value moved here -11 | let c = Cons(4, Box::new(a)); - | ^ value used here after move - -For more information about this error, try `rustc --explain E0382`. -error: could not compile `cons-list` (bin "cons-list") due to 1 previous error diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-17/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-17/src/main.rs deleted file mode 100644 index 47c33e4c4..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-17/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-18/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-18/src/main.rs deleted file mode 100644 index 602f7de40..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-18/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-19/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-19/output.txt deleted file mode 100644 index 252ccae89..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-19/output.txt +++ /dev/null @@ -1,8 +0,0 @@ -$ cargo run - Compiling cons-list v0.1.0 (file:///projects/cons-list) - Finished `dev` profile [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/rustbook-en/listings/ch15-smart-pointers/listing-15-19/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-19/src/main.rs deleted file mode 100644 index 1bd7bc533..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-19/src/main.rs +++ /dev/null @@ -1,21 +0,0 @@ -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/rustbook-en/listings/ch15-smart-pointers/listing-15-20/src/lib.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-20/src/lib.rs deleted file mode 100644 index a5181834c..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-20/src/lib.rs +++ /dev/null @@ -1,38 +0,0 @@ -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: &'a T, max: usize) -> LimitTracker<'a, T> { - 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/rustbook-en/listings/ch15-smart-pointers/listing-15-21/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-21/output.txt deleted file mode 100644 index 3509e8ec6..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-21/output.txt +++ /dev/null @@ -1,19 +0,0 @@ -$ cargo test - Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker) -error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a `&` reference - --> src/lib.rs:58:13 - | -58 | self.sent_messages.push(String::from(message)); - | ^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable - | -help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition - | -2 ~ fn send(&mut self, msg: &str); -3 | } - ... -56 | impl Messenger for MockMessenger { -57 ~ fn send(&mut self, message: &str) { - | - -For more information about this error, try `rustc --explain E0596`. -error: could not compile `limit-tracker` (lib test) due to 1 previous error diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-21/src/lib.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-21/src/lib.rs deleted file mode 100644 index 4572d4313..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-21/src/lib.rs +++ /dev/null @@ -1,73 +0,0 @@ -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: &'a T, max: usize) -> LimitTracker<'a, T> { - 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/rustbook-en/listings/ch15-smart-pointers/listing-15-22/src/lib.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-22/src/lib.rs deleted file mode 100644 index a77ffa41c..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-22/src/lib.rs +++ /dev/null @@ -1,78 +0,0 @@ -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: &'a T, max: usize) -> LimitTracker<'a, T> { - LimitTracker { - messenger, - value: 0, - max, - } - } - - pub fn set_value(&mut self, value: usize) { - self.value = value; - - let percentage_of_max = self.value as f64 / self.max as f64; - - if percentage_of_max >= 1.0 { - self.messenger.send("Error: You are over your quota!"); - } else if percentage_of_max >= 0.9 { - self.messenger - .send("Urgent warning: You've used up over 90% of your quota!"); - } else if percentage_of_max >= 0.75 { - self.messenger - .send("Warning: You've used up over 75% of your quota!"); - } - } -} - -// ANCHOR: here -#[cfg(test)] -mod tests { - use super::*; - use std::cell::RefCell; - - struct MockMessenger { - sent_messages: RefCell>, - } - - impl MockMessenger { - fn new() -> MockMessenger { - MockMessenger { - sent_messages: RefCell::new(vec![]), - } - } - } - - impl Messenger for MockMessenger { - fn send(&self, message: &str) { - self.sent_messages.borrow_mut().push(String::from(message)); - } - } - - #[test] - fn it_sends_an_over_75_percent_warning_message() { - // --snip-- - // ANCHOR_END: here - let mock_messenger = MockMessenger::new(); - let mut limit_tracker = LimitTracker::new(&mock_messenger, 100); - - limit_tracker.set_value(80); - // ANCHOR: here - - // ANCHOR: here - assert_eq!(mock_messenger.sent_messages.borrow().len(), 1); - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-23/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-23/output.txt deleted file mode 100644 index d3e560297..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-23/output.txt +++ /dev/null @@ -1,22 +0,0 @@ -$ cargo test - Compiling limit-tracker v0.1.0 (file:///projects/limit-tracker) - Finished `test` profile [unoptimized + debuginfo] target(s) in 0.91s - Running unittests src/lib.rs (target/debug/deps/limit_tracker-e599811fa246dbde) - -running 1 test -test tests::it_sends_an_over_75_percent_warning_message ... FAILED - -failures: - ----- tests::it_sends_an_over_75_percent_warning_message stdout ---- -thread 'tests::it_sends_an_over_75_percent_warning_message' panicked at src/lib.rs:60:53: -already borrowed: BorrowMutError -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - - -failures: - tests::it_sends_an_over_75_percent_warning_message - -test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -error: test failed, to rerun pass `--lib` diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-23/src/lib.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-23/src/lib.rs deleted file mode 100644 index 7d288e680..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-23/src/lib.rs +++ /dev/null @@ -1,78 +0,0 @@ -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: &'a T, max: usize) -> LimitTracker<'a, T> { - 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/rustbook-en/listings/ch15-smart-pointers/listing-15-24/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-24/output.txt deleted file mode 100644 index bbdc588c6..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-24/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling cons-list v0.1.0 (file:///projects/cons-list) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.63s - Running `target/debug/cons-list` -a after = Cons(RefCell { value: 15 }, Nil) -b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil)) -c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil)) diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-24/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-24/src/main.rs deleted file mode 100644 index e3dda1a19..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-24/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -#[derive(Debug)] -enum List { - Cons(Rc>, Rc), - Nil, -} - -use crate::List::{Cons, Nil}; -use std::cell::RefCell; -use std::rc::Rc; - -fn main() { - let value = Rc::new(RefCell::new(5)); - - let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); - - let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a)); - let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a)); - - *value.borrow_mut() += 10; - - println!("a after = {a:?}"); - println!("b after = {b:?}"); - println!("c after = {c:?}"); -} diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-25/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-25/src/main.rs deleted file mode 100644 index f36c7fd06..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-25/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::List::{Cons, Nil}; -use std::cell::RefCell; -use std::rc::Rc; - -#[derive(Debug)] -enum List { - Cons(i32, RefCell>), - Nil, -} - -impl List { - fn tail(&self) -> Option<&RefCell>> { - match self { - Cons(_, item) => Some(item), - Nil => None, - } - } -} - -fn main() {} diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-26/output.txt b/rustbook-en/listings/ch15-smart-pointers/listing-15-26/output.txt deleted file mode 100644 index b8e70e47d..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-26/output.txt +++ /dev/null @@ -1,11 +0,0 @@ -$ cargo run - Compiling cons-list v0.1.0 (file:///projects/cons-list) - Finished `dev` profile [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/rustbook-en/listings/ch15-smart-pointers/listing-15-26/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-26/src/main.rs deleted file mode 100644 index 08963aaa5..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-26/src/main.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::List::{Cons, Nil}; -use std::cell::RefCell; -use std::rc::Rc; - -#[derive(Debug)] -enum List { - Cons(i32, RefCell>), - Nil, -} - -impl List { - fn tail(&self) -> Option<&RefCell>> { - match self { - Cons(_, item) => Some(item), - Nil => None, - } - } -} - -// ANCHOR: here -fn main() { - let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil)))); - - println!("a initial rc count = {}", Rc::strong_count(&a)); - println!("a next item = {:?}", a.tail()); - - let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a)))); - - println!("a rc count after b creation = {}", Rc::strong_count(&a)); - println!("b initial rc count = {}", Rc::strong_count(&b)); - println!("b next item = {:?}", b.tail()); - - if let Some(link) = a.tail() { - *link.borrow_mut() = Rc::clone(&b); - } - - println!("b rc count after changing a = {}", Rc::strong_count(&b)); - println!("a rc count after changing a = {}", Rc::strong_count(&a)); - - // Uncomment the next line to see that we have a cycle; - // it will overflow the stack - // println!("a next item = {:?}", a.tail()); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-27/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-27/src/main.rs deleted file mode 100644 index 335d154dd..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-27/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -// ANCHOR: here -use std::cell::RefCell; -use std::rc::Rc; - -#[derive(Debug)] -struct Node { - value: i32, - children: RefCell>>, -} -// ANCHOR_END: here - -// ANCHOR: there -fn main() { - let leaf = Rc::new(Node { - value: 3, - children: RefCell::new(vec![]), - }); - - let branch = Rc::new(Node { - value: 5, - children: RefCell::new(vec![Rc::clone(&leaf)]), - }); -} -// ANCHOR_END: there diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-28/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-28/src/main.rs deleted file mode 100644 index fabd1cbce..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-28/src/main.rs +++ /dev/null @@ -1,33 +0,0 @@ -// ANCHOR: here -use std::cell::RefCell; -use std::rc::{Rc, Weak}; - -#[derive(Debug)] -struct Node { - value: i32, - parent: RefCell>, - children: RefCell>>, -} -// ANCHOR_END: here - -// ANCHOR: there -fn main() { - let leaf = Rc::new(Node { - value: 3, - parent: RefCell::new(Weak::new()), - children: RefCell::new(vec![]), - }); - - println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); - - let branch = Rc::new(Node { - value: 5, - parent: RefCell::new(Weak::new()), - children: RefCell::new(vec![Rc::clone(&leaf)]), - }); - - *leaf.parent.borrow_mut() = Rc::downgrade(&branch); - - println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); -} -// ANCHOR_END: there diff --git a/rustbook-en/listings/ch15-smart-pointers/listing-15-29/src/main.rs b/rustbook-en/listings/ch15-smart-pointers/listing-15-29/src/main.rs deleted file mode 100644 index ea13df0eb..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/listing-15-29/src/main.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::cell::RefCell; -use std::rc::{Rc, Weak}; - -#[derive(Debug)] -struct Node { - value: i32, - parent: RefCell>, - children: RefCell>>, -} - -// ANCHOR: here -fn main() { - let leaf = Rc::new(Node { - value: 3, - parent: RefCell::new(Weak::new()), - children: RefCell::new(vec![]), - }); - - println!( - "leaf strong = {}, weak = {}", - Rc::strong_count(&leaf), - Rc::weak_count(&leaf), - ); - - { - let branch = Rc::new(Node { - value: 5, - parent: RefCell::new(Weak::new()), - children: RefCell::new(vec![Rc::clone(&leaf)]), - }); - - *leaf.parent.borrow_mut() = Rc::downgrade(&branch); - - println!( - "branch strong = {}, weak = {}", - Rc::strong_count(&branch), - Rc::weak_count(&branch), - ); - - println!( - "leaf strong = {}, weak = {}", - Rc::strong_count(&leaf), - Rc::weak_count(&leaf), - ); - } - - println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); - println!( - "leaf strong = {}, weak = {}", - Rc::strong_count(&leaf), - Rc::weak_count(&leaf), - ); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt b/rustbook-en/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt deleted file mode 100644 index 95b9b68a8..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/no-listing-01-cant-borrow-immutable-as-mutable/output.txt +++ /dev/null @@ -1,15 +0,0 @@ -$ 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 - | -3 | let y = &mut x; - | ^^^^^^ cannot borrow as mutable - | -help: consider changing this to be mutable - | -2 | let mut x = 5; - | +++ - -For more information about this error, try `rustc --explain E0596`. -error: could not compile `borrowing` (bin "borrowing") due to 1 previous error diff --git a/rustbook-en/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt b/rustbook-en/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt deleted file mode 100644 index d1eccd2b2..000000000 --- a/rustbook-en/listings/ch15-smart-pointers/output-only-01-comparing-to-reference/output.txt +++ /dev/null @@ -1,13 +0,0 @@ -$ cargo run - Compiling deref-example v0.1.0 (file:///projects/deref-example) -error[E0277]: can't compare `{integer}` with `&{integer}` - --> src/main.rs:6:5 - | -6 | assert_eq!(5, y); - | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == &{integer}` - | - = help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `deref-example` (bin "deref-example") due to 1 previous error diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-01/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-01/src/main.rs deleted file mode 100644 index ea10ba282..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-01/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::thread; -use std::time::Duration; - -fn main() { - thread::spawn(|| { - for i in 1..10 { - println!("hi number {i} from the spawned thread!"); - thread::sleep(Duration::from_millis(1)); - } - }); - - for i in 1..5 { - println!("hi number {i} from the main thread!"); - thread::sleep(Duration::from_millis(1)); - } -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-02/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-02/src/main.rs deleted file mode 100644 index 33bf53f40..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-02/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::thread; -use std::time::Duration; - -fn main() { - let handle = thread::spawn(|| { - for i in 1..10 { - println!("hi number {i} from the spawned thread!"); - thread::sleep(Duration::from_millis(1)); - } - }); - - for i in 1..5 { - println!("hi number {i} from the main thread!"); - thread::sleep(Duration::from_millis(1)); - } - - handle.join().unwrap(); -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-03/output.txt b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-03/output.txt deleted file mode 100644 index 3de4d4d3f..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-03/output.txt +++ /dev/null @@ -1,25 +0,0 @@ -$ cargo run - Compiling threads v0.1.0 (file:///projects/threads) -error[E0373]: closure may outlive the current function, but it borrows `v`, which is owned by the current function - --> src/main.rs:6:32 - | -6 | let handle = thread::spawn(|| { - | ^^ may outlive borrowed value `v` -7 | println!("Here's a vector: {v:?}"); - | - `v` is borrowed here - | -note: function requires argument type to outlive `'static` - --> src/main.rs:6:18 - | -6 | let handle = thread::spawn(|| { - | __________________^ -7 | | println!("Here's a vector: {v:?}"); -8 | | }); - | |______^ -help: to force the closure to take ownership of `v` (and any other referenced variables), use the `move` keyword - | -6 | let handle = thread::spawn(move || { - | ++++ - -For more information about this error, try `rustc --explain E0373`. -error: could not compile `threads` (bin "threads") due to 1 previous error diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-03/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-03/src/main.rs deleted file mode 100644 index b2231c5b8..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-03/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch16-fearless-concurrency/listing-16-04/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-04/src/main.rs deleted file mode 100644 index f0a9058a1..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-04/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch16-fearless-concurrency/listing-16-05/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-05/src/main.rs deleted file mode 100644 index 76783e614..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-05/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch16-fearless-concurrency/listing-16-07/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-07/src/main.rs deleted file mode 100644 index 7859b64da..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-07/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -use std::sync::mpsc; -use std::thread; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let val = String::from("hi"); - tx.send(val).unwrap(); - }); -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-08/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-08/src/main.rs deleted file mode 100644 index e7ac452dc..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-08/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -use std::sync::mpsc; -use std::thread; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let val = String::from("hi"); - tx.send(val).unwrap(); - }); - - let received = rx.recv().unwrap(); - println!("Got: {received}"); -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-09/output.txt b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-09/output.txt deleted file mode 100644 index 2e95105fe..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-09/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling message-passing v0.1.0 (file:///projects/message-passing) -error[E0382]: borrow of moved value: `val` - --> src/main.rs:10:26 - | -8 | let val = String::from("hi"); - | --- move occurs because `val` has type `String`, which does not implement the `Copy` trait -9 | tx.send(val).unwrap(); - | --- value moved here -10 | println!("val is {val}"); - | ^^^^^ value borrowed here after move - | - = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - -For more information about this error, try `rustc --explain E0382`. -error: could not compile `message-passing` (bin "message-passing") due to 1 previous error diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-09/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-09/src/main.rs deleted file mode 100644 index fe20d3474..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-09/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -use std::sync::mpsc; -use std::thread; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let val = String::from("hi"); - tx.send(val).unwrap(); - println!("val is {val}"); - }); - - let received = rx.recv().unwrap(); - println!("Got: {received}"); -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-10/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-10/src/main.rs deleted file mode 100644 index c9702bd85..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-10/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::sync::mpsc; -use std::thread; -use std::time::Duration; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let vals = vec![ - String::from("hi"), - String::from("from"), - String::from("the"), - String::from("thread"), - ]; - - for val in vals { - tx.send(val).unwrap(); - thread::sleep(Duration::from_secs(1)); - } - }); - - for received in rx { - println!("Got: {received}"); - } -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-11/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-11/src/main.rs deleted file mode 100644 index 174a5d14b..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-11/src/main.rs +++ /dev/null @@ -1,46 +0,0 @@ -use std::sync::mpsc; -use std::thread; -use std::time::Duration; - -fn main() { - // ANCHOR: here - // --snip-- - - let (tx, rx) = mpsc::channel(); - - let tx1 = tx.clone(); - thread::spawn(move || { - let vals = vec![ - String::from("hi"), - String::from("from"), - String::from("the"), - String::from("thread"), - ]; - - for val in vals { - tx1.send(val).unwrap(); - thread::sleep(Duration::from_secs(1)); - } - }); - - thread::spawn(move || { - let vals = vec![ - String::from("more"), - String::from("messages"), - String::from("for"), - String::from("you"), - ]; - - for val in vals { - tx.send(val).unwrap(); - thread::sleep(Duration::from_secs(1)); - } - }); - - for received in rx { - println!("Got: {received}"); - } - - // --snip-- - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-12/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-12/src/main.rs deleted file mode 100644 index 99ba5b489..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-12/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch16-fearless-concurrency/listing-16-13/output.txt b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-13/output.txt deleted file mode 100644 index a4db0dcc3..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-13/output.txt +++ /dev/null @@ -1,26 +0,0 @@ -$ cargo run - Compiling shared-state v0.1.0 (file:///projects/shared-state) -error[E0382]: borrow of moved value: `counter` - --> src/main.rs:21:29 - | -5 | let counter = Mutex::new(0); - | ------- move occurs because `counter` has type `Mutex`, which does not implement the `Copy` trait -... -8 | for _ in 0..10 { - | -------------- inside of this loop -9 | let handle = thread::spawn(move || { - | ------- value moved into closure here, in previous iteration of loop -... -21 | println!("Result: {}", *counter.lock().unwrap()); - | ^^^^^^^ value borrowed here after move - | -help: consider moving the expression out of the loop so it is only moved once - | -8 ~ let mut value = counter.lock(); -9 ~ for _ in 0..10 { -10 | let handle = thread::spawn(move || { -11 ~ let mut num = value.unwrap(); - | - -For more information about this error, try `rustc --explain E0382`. -error: could not compile `shared-state` (bin "shared-state") due to 1 previous error diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-13/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-13/src/main.rs deleted file mode 100644 index 4e380a59a..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-13/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -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/rustbook-en/listings/ch16-fearless-concurrency/listing-16-14/output.txt b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-14/output.txt deleted file mode 100644 index cb4167a5b..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-14/output.txt +++ /dev/null @@ -1,28 +0,0 @@ -$ cargo run - Compiling shared-state v0.1.0 (file:///projects/shared-state) -error[E0277]: `Rc>` cannot be sent between threads safely - --> src/main.rs:11:36 - | -11 | let handle = thread::spawn(move || { - | ------------- ^------ - | | | - | ______________________|_____________within this `{closure@src/main.rs:11:36: 11:43}` - | | | - | | required by a bound introduced by this call -12 | | let mut num = counter.lock().unwrap(); -13 | | -14 | | *num += 1; -15 | | }); - | |_________^ `Rc>` cannot be sent between threads safely - | - = help: within `{closure@src/main.rs:11:36: 11:43}`, the trait `Send` is not implemented for `Rc>`, which is required by `{closure@src/main.rs:11:36: 11:43}: Send` -note: required because it's used within this closure - --> src/main.rs:11:36 - | -11 | let handle = thread::spawn(move || { - | ^^^^^^^ -note: required by a bound in `spawn` - --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/thread/mod.rs:691:1 - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `shared-state` (bin "shared-state") due to 1 previous error diff --git a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-14/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-14/src/main.rs deleted file mode 100644 index d940b1a34..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-14/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -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/rustbook-en/listings/ch16-fearless-concurrency/listing-16-15/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/listing-16-15/src/main.rs deleted file mode 100644 index 30247dd52..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/listing-16-15/src/main.rs +++ /dev/null @@ -1,23 +0,0 @@ -use std::sync::{Arc, Mutex}; -use std::thread; - -fn main() { - let counter = Arc::new(Mutex::new(0)); - let mut handles = vec![]; - - for _ in 0..10 { - let counter = Arc::clone(&counter); - let handle = thread::spawn(move || { - let mut num = counter.lock().unwrap(); - - *num += 1; - }); - handles.push(handle); - } - - for handle in handles { - handle.join().unwrap(); - } - - println!("Result: {}", *counter.lock().unwrap()); -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs deleted file mode 100644 index 7023a90f6..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/no-listing-01-join-too-early/src/main.rs +++ /dev/null @@ -1,18 +0,0 @@ -use std::thread; -use std::time::Duration; - -fn main() { - let handle = thread::spawn(|| { - for i in 1..10 { - println!("hi number {i} from the spawned thread!"); - thread::sleep(Duration::from_millis(1)); - } - }); - - handle.join().unwrap(); - - for i in 1..5 { - println!("hi number {i} from the main thread!"); - thread::sleep(Duration::from_millis(1)); - } -} diff --git a/rustbook-en/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/src/main.rs deleted file mode 100644 index dbb139771..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/no-listing-02-no-loop-to-understand-error/src/main.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/rustbook-en/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt b/rustbook-en/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt deleted file mode 100644 index 929354c13..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/output-only-01-move-drop/output.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ cargo run - Compiling threads v0.1.0 (file:///projects/threads) -error[E0382]: use of moved value: `v` - --> src/main.rs:10:10 - | -4 | let v = vec![1, 2, 3]; - | - move occurs because `v` has type `Vec`, which does not implement the `Copy` trait -5 | -6 | let handle = thread::spawn(move || { - | ------- value moved into closure here -7 | println!("Here's a vector: {v:?}"); - | - variable moved due to use in closure -... -10 | drop(v); // oh no! - | ^ value used here after move - -For more information about this error, try `rustc --explain E0382`. -error: could not compile `threads` (bin "threads") due to 1 previous error diff --git a/rustbook-en/listings/ch16-fearless-concurrency/output-only-01-move-drop/src/main.rs b/rustbook-en/listings/ch16-fearless-concurrency/output-only-01-move-drop/src/main.rs deleted file mode 100644 index cc71cbab0..000000000 --- a/rustbook-en/listings/ch16-fearless-concurrency/output-only-01-move-drop/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-01/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-01/Cargo.lock deleted file mode 100644 index 471d8dfc3..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-01/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "averaged-collection" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-01/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-01/src/lib.rs deleted file mode 100644 index b5ce2ab64..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-01/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub struct AveragedCollection { - list: Vec, - average: f64, -} diff --git a/rustbook-en/listings/ch17-oop/listing-17-02/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-02/Cargo.lock deleted file mode 100644 index 471d8dfc3..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-02/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "averaged-collection" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-02/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-02/src/lib.rs deleted file mode 100644 index bb407ec5f..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-02/src/lib.rs +++ /dev/null @@ -1,33 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-03/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-03/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-03/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-04/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-04/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-04/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-05/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-05/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-05/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-06/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-06/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-06/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-07/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-07/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-07/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-07/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-07/src/lib.rs deleted file mode 100644 index b16cd0155..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-07/src/lib.rs +++ /dev/null @@ -1,29 +0,0 @@ -pub trait Draw { - fn draw(&self); -} - -pub struct Screen { - pub components: Vec>, -} - -impl Screen { - pub fn run(&self) { - for component in self.components.iter() { - component.draw(); - } - } -} - -// ANCHOR: here -pub struct Button { - pub width: u32, - pub height: u32, - pub label: String, -} - -impl Draw for Button { - fn draw(&self) { - // code to actually draw a button - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch17-oop/listing-17-08/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-08/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-08/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-08/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-08/src/lib.rs deleted file mode 100644 index 960fee23d..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-08/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-08/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-08/src/main.rs deleted file mode 100644 index 9575d407e..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-08/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/rustbook-en/listings/ch17-oop/listing-17-09/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-09/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-09/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-09/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-09/src/lib.rs deleted file mode 100644 index 960fee23d..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-09/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-09/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-09/src/main.rs deleted file mode 100644 index 4eb13f6b7..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-09/src/main.rs +++ /dev/null @@ -1,40 +0,0 @@ -use gui::Draw; - -struct SelectBox { - width: u32, - height: u32, - options: Vec, -} - -impl Draw for SelectBox { - fn draw(&self) { - // code to actually draw a select box - } -} - -// ANCHOR: here -use gui::{Button, Screen}; - -fn main() { - let screen = Screen { - components: vec![ - Box::new(SelectBox { - width: 75, - height: 10, - options: vec![ - String::from("Yes"), - String::from("Maybe"), - String::from("No"), - ], - }), - Box::new(Button { - width: 50, - height: 10, - label: String::from("OK"), - }), - ], - }; - - screen.run(); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch17-oop/listing-17-10/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-10/Cargo.lock deleted file mode 100644 index 00d7b2182..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-10/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "gui" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-10/output.txt b/rustbook-en/listings/ch17-oop/listing-17-10/output.txt deleted file mode 100644 index 78d7c39a3..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-10/output.txt +++ /dev/null @@ -1,13 +0,0 @@ -$ cargo run - Compiling gui v0.1.0 (file:///projects/gui) -error[E0277]: the trait bound `String: Draw` is not satisfied - --> src/main.rs:5:26 - | -5 | components: vec![Box::new(String::from("Hi"))], - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Draw` is not implemented for `String` - | - = help: the trait `Draw` is implemented for `Button` - = note: required for the cast from `Box` to `Box` - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `gui` (bin "gui") due to 1 previous error diff --git a/rustbook-en/listings/ch17-oop/listing-17-10/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-10/src/lib.rs deleted file mode 100644 index 960fee23d..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-10/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-11/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-11/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-11/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-11/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-11/src/main.rs deleted file mode 100644 index d99170a97..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-11/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -// 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/rustbook-en/listings/ch17-oop/listing-17-12/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-12/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-12/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-12/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-12/src/lib.rs deleted file mode 100644 index b8156c39d..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-12/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-12/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-12/src/main.rs deleted file mode 100644 index 14b4c0824..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-12/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-13/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-13/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-13/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-13/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-13/src/lib.rs deleted file mode 100644 index bd68557a0..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-13/src/lib.rs +++ /dev/null @@ -1,28 +0,0 @@ -pub struct Post { - state: Option>, - content: String, -} - -// ANCHOR: here -impl Post { - // --snip-- - // ANCHOR_END: here - pub fn new() -> Post { - Post { - state: Some(Box::new(Draft {})), - content: String::new(), - } - } - - // ANCHOR: here - pub fn add_text(&mut self, text: &str) { - self.content.push_str(text); - } -} -// ANCHOR_END: here - -trait State {} - -struct Draft {} - -impl State for Draft {} diff --git a/rustbook-en/listings/ch17-oop/listing-17-13/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-13/src/main.rs deleted file mode 100644 index 14b4c0824..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-13/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-14/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-14/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-14/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-14/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-14/src/lib.rs deleted file mode 100644 index 09cf0c466..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-14/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -pub struct Post { - state: Option>, - content: String, -} - -// ANCHOR: here -impl Post { - // --snip-- - // ANCHOR_END: here - pub fn new() -> Post { - Post { - state: Some(Box::new(Draft {})), - content: String::new(), - } - } - - pub fn add_text(&mut self, text: &str) { - self.content.push_str(text); - } - - // ANCHOR: here - pub fn content(&self) -> &str { - "" - } -} -// ANCHOR_END: here - -trait State {} - -struct Draft {} - -impl State for Draft {} diff --git a/rustbook-en/listings/ch17-oop/listing-17-14/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-14/src/main.rs deleted file mode 100644 index 14b4c0824..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-14/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-15/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-15/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-15/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-15/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-15/src/lib.rs deleted file mode 100644 index 909dd5274..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-15/src/lib.rs +++ /dev/null @@ -1,52 +0,0 @@ -pub struct Post { - state: Option>, - content: String, -} - -// ANCHOR: here -impl Post { - // --snip-- - // ANCHOR_END: here - pub fn new() -> Post { - Post { - state: Some(Box::new(Draft {})), - content: String::new(), - } - } - - pub fn add_text(&mut self, text: &str) { - self.content.push_str(text); - } - - pub fn content(&self) -> &str { - "" - } - - // ANCHOR: here - pub fn request_review(&mut self) { - if let Some(s) = self.state.take() { - self.state = Some(s.request_review()) - } - } -} - -trait State { - fn request_review(self: Box) -> Box; -} - -struct Draft {} - -impl State for Draft { - fn request_review(self: Box) -> Box { - Box::new(PendingReview {}) - } -} - -struct PendingReview {} - -impl State for PendingReview { - fn request_review(self: Box) -> Box { - self - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch17-oop/listing-17-15/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-15/src/main.rs deleted file mode 100644 index 14b4c0824..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-15/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-16/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-16/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-16/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-16/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-16/src/lib.rs deleted file mode 100644 index 92cb29813..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-16/src/lib.rs +++ /dev/null @@ -1,85 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-16/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-16/src/main.rs deleted file mode 100644 index 14b4c0824..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-16/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-17/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-17/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-17/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-17/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-17/src/lib.rs deleted file mode 100644 index 0beee7b8d..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-17/src/lib.rs +++ /dev/null @@ -1,82 +0,0 @@ -pub struct Post { - state: Option>, - content: String, -} - -// ANCHOR: here -impl Post { - // --snip-- - // ANCHOR_END: here - pub fn new() -> Post { - Post { - state: Some(Box::new(Draft {})), - content: String::new(), - } - } - - pub fn add_text(&mut self, text: &str) { - self.content.push_str(text); - } - - // ANCHOR: here - pub fn content(&self) -> &str { - self.state.as_ref().unwrap().content(self) - } - // --snip-- - // ANCHOR_END: here - - pub fn request_review(&mut self) { - if let Some(s) = self.state.take() { - self.state = Some(s.request_review()) - } - } - - pub fn approve(&mut self) { - if let Some(s) = self.state.take() { - self.state = Some(s.approve()) - } - } - // ANCHOR: here -} -// ANCHOR_END: here - -trait State { - fn request_review(self: Box) -> Box; - fn approve(self: Box) -> Box; -} - -struct Draft {} - -impl State for Draft { - fn request_review(self: Box) -> Box { - Box::new(PendingReview {}) - } - - fn approve(self: Box) -> Box { - self - } -} - -struct PendingReview {} - -impl State for PendingReview { - fn request_review(self: Box) -> Box { - self - } - - fn approve(self: Box) -> Box { - Box::new(Published {}) - } -} - -struct Published {} - -impl State for Published { - fn request_review(self: Box) -> Box { - self - } - - fn approve(self: Box) -> Box { - self - } -} diff --git a/rustbook-en/listings/ch17-oop/listing-17-17/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-17/src/main.rs deleted file mode 100644 index 14b4c0824..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-17/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-18/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-18/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-18/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-18/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-18/src/lib.rs deleted file mode 100644 index 1bac8a87a..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-18/src/lib.rs +++ /dev/null @@ -1,94 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-18/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-18/src/main.rs deleted file mode 100644 index 14b4c0824..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-18/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-19/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-19/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-19/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-19/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-19/src/lib.rs deleted file mode 100644 index bfe034eaf..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-19/src/lib.rs +++ /dev/null @@ -1,25 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-20/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-20/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-20/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-20/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-20/src/lib.rs deleted file mode 100644 index 3b82ec05d..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-20/src/lib.rs +++ /dev/null @@ -1,48 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-21/Cargo.lock b/rustbook-en/listings/ch17-oop/listing-17-21/Cargo.lock deleted file mode 100644 index b6f4232c6..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-21/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "blog" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch17-oop/listing-17-21/src/lib.rs b/rustbook-en/listings/ch17-oop/listing-17-21/src/lib.rs deleted file mode 100644 index 38500a651..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-21/src/lib.rs +++ /dev/null @@ -1,43 +0,0 @@ -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/rustbook-en/listings/ch17-oop/listing-17-21/src/main.rs b/rustbook-en/listings/ch17-oop/listing-17-21/src/main.rs deleted file mode 100644 index 720c55e6a..000000000 --- a/rustbook-en/listings/ch17-oop/listing-17-21/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-01/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-01/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-01/src/main.rs deleted file mode 100644 index fc87768fb..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-01/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -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, {color}, as the background"); - } 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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-02/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/output.txt b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/output.txt deleted file mode 100644 index 9add287fa..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling patterns v0.1.0 (file:///projects/patterns) - Finished `dev` profile [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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/src/main.rs deleted file mode 100644 index 218c18063..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-03/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - // ANCHOR: here - let v = vec!['a', 'b', 'c']; - - for (index, value) in v.iter().enumerate() { - println!("{value} is at index {index}"); - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-04/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-05/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-05/output.txt b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-05/output.txt deleted file mode 100644 index 8002272a7..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-05/output.txt +++ /dev/null @@ -1,15 +0,0 @@ -$ cargo run - Compiling patterns v0.1.0 (file:///projects/patterns) -error[E0308]: mismatched types - --> src/main.rs:2:9 - | -2 | let (x, y) = (1, 2, 3); - | ^^^^^^ --------- this expression has type `({integer}, {integer}, {integer})` - | | - | expected a tuple with 3 elements, found one with 2 elements - | - = note: expected tuple `({integer}, {integer}, {integer})` - found tuple `(_, _)` - -For more information about this error, try `rustc --explain E0308`. -error: could not compile `patterns` (bin "patterns") due to 1 previous error diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-06/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-07/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-07/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-07/src/main.rs deleted file mode 100644 index 70069424c..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-07/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn print_coordinates(&(x, y): &(i32, i32)) { - println!("Current location: ({x}, {y})"); -} - -fn main() { - let point = (3, 5); - print_coordinates(&point); -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/output.txt b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/output.txt deleted file mode 100644 index 6ce3dfc58..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/output.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ cargo run - Compiling patterns v0.1.0 (file:///projects/patterns) -error[E0005]: refutable pattern in local binding - --> src/main.rs:3:9 - | -3 | let Some(x) = some_option_value; - | ^^^^^^^ pattern `None` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html - = note: the matched value is of type `Option` -help: you might want to use `let else` to handle the variant that isn't matched - | -3 | let Some(x) = some_option_value else { todo!() }; - | ++++++++++++++++ - -For more information about this error, try `rustc --explain E0005`. -error: could not compile `patterns` (bin "patterns") due to 1 previous error diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/src/main.rs deleted file mode 100644 index 7baa02a49..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-08/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - let some_option_value: Option = None; - // ANCHOR: here - let Some(x) = some_option_value; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-09/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-09/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-09/src/main.rs deleted file mode 100644 index e378c3703..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-09/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-10/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-10/output.txt b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-10/output.txt deleted file mode 100644 index 97bc014ec..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-10/output.txt +++ /dev/null @@ -1,16 +0,0 @@ -$ cargo run - Compiling patterns v0.1.0 (file:///projects/patterns) -warning: irrefutable `if let` pattern - --> src/main.rs:2:8 - | -2 | if let x = 5 { - | ^^^^^^^^^ - | - = note: this pattern will always match, so the `if let` is useless - = help: consider replacing the `if let` with a `let` - = note: `#[warn(irrefutable_let_patterns)]` on by default - -warning: `patterns` (bin "patterns") generated 1 warning - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.39s - Running `target/debug/patterns` -5 diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-11/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-11/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-11/src/main.rs deleted file mode 100644 index 055212803..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-11/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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 = {x:?}, y = {y}"); - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-12/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-13/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-14/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-15/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs deleted file mode 100644 index 9407cc16a..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-15/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -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 {x} and in the y direction {y}"); - } - Message::Write(text) => { - println!("Text message: {text}"); - } - Message::ChangeColor(r, g, b) => { - println!("Change the color to red {r}, green {g}, and blue {b}") - } - } -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-16/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs deleted file mode 100644 index 1e7ad5f19..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-16/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -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 color to red {r}, green {g}, and blue {b}"); - } - Message::ChangeColor(Color::Hsv(h, s, v)) => { - println!("Change color to hue {h}, saturation {s}, value {v}") - } - _ => (), - } -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-17/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-18/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-18/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-18/src/main.rs deleted file mode 100644 index 2b8877620..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-18/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-19/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-19/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-19/src/main.rs deleted file mode 100644 index e28dab111..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-19/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-20/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-21/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-21/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-21/src/main.rs deleted file mode 100644 index 320db62f5..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-21/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-22/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-22/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-22/src/main.rs deleted file mode 100644 index 9df1492b2..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-22/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -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/rustbook-en/listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-23/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-24/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-24/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-24/src/main.rs deleted file mode 100644 index 3f9aaafc2..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-24/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let numbers = (2, 4, 8, 16, 32); - - match numbers { - (first, .., last) => { - println!("Some numbers: {first}, {last}"); - } - } -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/Cargo.lock deleted file mode 100644 index a233623e5..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/Cargo.lock +++ /dev/null @@ -1,4 +0,0 @@ -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/output.txt b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/output.txt deleted file mode 100644 index bd5e0f9d7..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/output.txt +++ /dev/null @@ -1,11 +0,0 @@ -$ cargo run - Compiling patterns v0.1.0 (file:///projects/patterns) -error: `..` can only be used once per tuple pattern - --> src/main.rs:5:22 - | -5 | (.., second, ..) => { - | -- ^^ can only be used once per tuple pattern - | | - | previously used here - -error: could not compile `patterns` (bin "patterns") due to 1 previous error diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/src/main.rs deleted file mode 100644 index 6c3b24b7d..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-25/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let numbers = (2, 4, 8, 16, 32); - - match numbers { - (.., second, ..) => { - println!("Some numbers: {second}") - }, - } -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-26/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-26/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-26/src/main.rs deleted file mode 100644 index 2566169a7..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-26/src/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -fn main() { - // ANCHOR: here - let num = Some(4); - - match num { - Some(x) if x % 2 == 0 => println!("The number {x} is even"), - Some(x) => println!("The number {x} is odd"), - None => (), - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-27/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-27/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-27/src/main.rs deleted file mode 100644 index 06fd94996..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-27/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -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 = {x:?}, y = {y}"); -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-28/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-29/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-29/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/listing-18-29/src/main.rs deleted file mode 100644 index e36fda878..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/listing-18-29/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -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/rustbook-en/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-01-literals/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-02-multiple-patterns/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-03-ranges/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs b/rustbook-en/listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs deleted file mode 100644 index a3ebe7af0..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-03-ranges/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() { - // ANCHOR: here - let x = 5; - - match x { - 1..=5 => println!("one through five"), - _ => println!("something else"), - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-04-ranges-of-char/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock b/rustbook-en/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock deleted file mode 100644 index 2b4fa2903..000000000 --- a/rustbook-en/listings/ch18-patterns-and-matching/no-listing-05-destructuring-structs-and-tuples/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "patterns" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-01/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-01/src/main.rs deleted file mode 100644 index 893f57890..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-01/src/main.rs +++ /dev/null @@ -1,8 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/listing-19-03/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-03/src/main.rs deleted file mode 100644 index 02a0be6b0..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-03/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/listing-19-05/output.txt b/rustbook-en/listings/ch19-advanced-features/listing-19-05/output.txt deleted file mode 100644 index 514e25331..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-05/output.txt +++ /dev/null @@ -1,19 +0,0 @@ -$ cargo run - Compiling unsafe-example v0.1.0 (file:///projects/unsafe-example) -error[E0499]: cannot borrow `*values` as mutable more than once at a time - --> src/main.rs:6:31 - | -1 | fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { - | - let's call the lifetime of this reference `'1` -... -6 | (&mut values[..mid], &mut values[mid..]) - | --------------------------^^^^^^-------- - | | | | - | | | second mutable borrow occurs here - | | first mutable borrow occurs here - | returning this value requires that `*values` is borrowed for `'1` - | - = help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices - -For more information about this error, try `rustc --explain E0499`. -error: could not compile `unsafe-example` (bin "unsafe-example") due to 1 previous error diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-05/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-05/src/main.rs deleted file mode 100644 index dabf63de1..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-05/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -// ANCHOR: here -fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { - let len = values.len(); - - assert!(mid <= len); - - (&mut values[..mid], &mut values[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/rustbook-en/listings/ch19-advanced-features/listing-19-06/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-06/src/main.rs deleted file mode 100644 index 3af21f761..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-06/src/main.rs +++ /dev/null @@ -1,22 +0,0 @@ -// ANCHOR: here -use std::slice; - -fn split_at_mut(values: &mut [i32], mid: usize) -> (&mut [i32], &mut [i32]) { - let len = values.len(); - let ptr = values.as_mut_ptr(); - - assert!(mid <= len); - - unsafe { - ( - slice::from_raw_parts_mut(ptr, mid), - slice::from_raw_parts_mut(ptr.add(mid), len - mid), - ) - } -} -// ANCHOR_END: here - -fn main() { - let mut vector = vec![1, 2, 3, 4, 5, 6]; - let (left, right) = split_at_mut(&mut vector, 3); -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-07/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-07/src/main.rs deleted file mode 100644 index b4d6cdb7c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-07/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn main() { - // ANCHOR: here - use std::slice; - - let address = 0x01234usize; - let r = address as *mut i32; - - let values: &[i32] = unsafe { slice::from_raw_parts_mut(r, 10000) }; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-08/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-08/src/main.rs deleted file mode 100644 index 8b56630c9..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-08/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern "C" { - fn abs(input: i32) -> i32; -} - -fn main() { - unsafe { - println!("Absolute value of -3 according to C: {}", abs(-3)); - } -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-09/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-09/src/main.rs deleted file mode 100644 index fda5179af..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-09/src/main.rs +++ /dev/null @@ -1,5 +0,0 @@ -static HELLO_WORLD: &str = "Hello, world!"; - -fn main() { - println!("name is: {HELLO_WORLD}"); -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-10/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-10/src/main.rs deleted file mode 100644 index b5559fd3a..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-10/src/main.rs +++ /dev/null @@ -1,15 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/listing-19-12/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-12/src/lib.rs deleted file mode 100644 index dbe04620e..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-12/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub trait Iterator { - type Item; - - fn next(&mut self) -> Option; -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-14/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-14/src/main.rs deleted file mode 100644 index 9111fbc55..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-14/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::ops::Add; - -#[derive(Debug, Copy, Clone, PartialEq)] -struct Point { - x: i32, - y: i32, -} - -impl Add for Point { - type Output = Point; - - fn add(self, other: Point) -> Point { - Point { - x: self.x + other.x, - y: self.y + other.y, - } - } -} - -fn main() { - assert_eq!( - Point { x: 1, y: 0 } + Point { x: 2, y: 3 }, - Point { x: 3, y: 3 } - ); -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-15/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-15/src/lib.rs deleted file mode 100644 index f38bf475c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-15/src/lib.rs +++ /dev/null @@ -1,12 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/listing-19-18/output.txt b/rustbook-en/listings/ch19-advanced-features/listing-19-18/output.txt deleted file mode 100644 index d7e315bfa..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-18/output.txt +++ /dev/null @@ -1,7 +0,0 @@ -$ cargo run - Compiling traits-example v0.1.0 (file:///projects/traits-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.46s - Running `target/debug/traits-example` -This is your captain speaking. -Up! -*waving arms furiously* diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-19/output.txt b/rustbook-en/listings/ch19-advanced-features/listing-19-19/output.txt deleted file mode 100644 index b6e283f20..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-19/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling traits-example v0.1.0 (file:///projects/traits-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.54s - Running `target/debug/traits-example` -A baby dog is called a Spot diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-20/output.txt b/rustbook-en/listings/ch19-advanced-features/listing-19-20/output.txt deleted file mode 100644 index 0e78ae2d9..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-20/output.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ cargo run - Compiling traits-example v0.1.0 (file:///projects/traits-example) -error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type - --> src/main.rs:20:43 - | -2 | fn baby_name() -> String; - | ------------------------- `Animal::baby_name` defined here -... -20 | println!("A baby dog is called a {}", Animal::baby_name()); - | ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait - | -help: use the fully-qualified path to the only available implementation - | -20 | println!("A baby dog is called a {}", ::baby_name()); - | +++++++ + - -For more information about this error, try `rustc --explain E0790`. -error: could not compile `traits-example` (bin "traits-example") due to 1 previous error diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-21/output.txt b/rustbook-en/listings/ch19-advanced-features/listing-19-21/output.txt deleted file mode 100644 index f59d0bc27..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-21/output.txt +++ /dev/null @@ -1,5 +0,0 @@ -$ cargo run - Compiling traits-example v0.1.0 (file:///projects/traits-example) - Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.48s - Running `target/debug/traits-example` -A baby dog is called a puppy diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-22/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-22/src/main.rs deleted file mode 100644 index 7069fef17..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-22/src/main.rs +++ /dev/null @@ -1,17 +0,0 @@ -// 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/rustbook-en/listings/ch19-advanced-features/listing-19-23/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-23/src/main.rs deleted file mode 100644 index f8c8366b4..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-23/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/listing-19-27/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-27/src/main.rs deleted file mode 100644 index 312df2412..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-27/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs deleted file mode 100644 index 839ec8359..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/hello_macro_derive/src/lib.rs +++ /dev/null @@ -1,12 +0,0 @@ -use proc_macro::TokenStream; -use quote::quote; - -#[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/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/src/lib.rs deleted file mode 100644 index e74793184..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait HelloMacro { - fn hello_macro(); -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/src/main.rs deleted file mode 100644 index 10b028b2d..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-31/hello_macro/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs deleted file mode 100644 index ba1215f51..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/hello_macro_derive/src/lib.rs +++ /dev/null @@ -1,26 +0,0 @@ -use proc_macro::TokenStream; -use quote::quote; - -#[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/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/src/lib.rs deleted file mode 100644 index e74793184..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait HelloMacro { - fn hello_macro(); -} diff --git a/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/src/main.rs b/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/src/main.rs deleted file mode 100644 index 10b028b2d..000000000 --- a/rustbook-en/listings/ch19-advanced-features/listing-19-33/hello_macro/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock deleted file mode 100644 index 497817bf2..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-01-unsafe-fn/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "unsafe-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock deleted file mode 100644 index b1977d01e..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "traits-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt b/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt deleted file mode 100644 index 41af68689..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/output.txt +++ /dev/null @@ -1,34 +0,0 @@ -$ 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:23 - | -20 | impl OutlinePrint for Point {} - | ^^^^^ `Point` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `Point` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -note: required by a bound in `OutlinePrint` - --> src/main.rs:3:21 - | -3 | trait OutlinePrint: fmt::Display { - | ^^^^^^^^^^^^ required by this bound in `OutlinePrint` - -error[E0277]: `Point` doesn't implement `std::fmt::Display` - --> src/main.rs:24:7 - | -24 | p.outline_print(); - | ^^^^^^^^^^^^^ `Point` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `Point` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -note: required by a bound in `OutlinePrint::outline_print` - --> src/main.rs:3:21 - | -3 | trait OutlinePrint: fmt::Display { - | ^^^^^^^^^^^^ required by this bound in `OutlinePrint::outline_print` -4 | fn outline_print(&self) { - | ------------- required by a bound in this associated function - -For more information about this error, try `rustc --explain E0277`. -error: could not compile `traits-example` (bin "traits-example") due to 2 previous errors diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs deleted file mode 100644 index 0e45f3c28..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-02-impl-outlineprint-for-point/src/main.rs +++ /dev/null @@ -1,27 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock deleted file mode 100644 index b1977d01e..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "traits-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs deleted file mode 100644 index fa5be1c7c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-03-impl-display-for-point/src/main.rs +++ /dev/null @@ -1,33 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-04-kilometers-alias/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock deleted file mode 100644 index b1977d01e..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-05-write-trait/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "traits-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock deleted file mode 100644 index b1977d01e..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-06-result-alias/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "traits-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock deleted file mode 100644 index b1977d01e..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-07-never-type/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "traits-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs deleted file mode 100644 index 6d56008ad..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-08-match-arms-different-types/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn main() { - let guess = "3"; - // ANCHOR: here - let guess = match guess.trim().parse() { - Ok(_) => 5, - Err(_) => "hello", - }; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-09-unwrap-definition/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs deleted file mode 100644 index aa4f937ff..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-09-unwrap-definition/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-10-loop-returns-never/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-11-cant-create-str/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs deleted file mode 100644 index 075d5110c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-11-cant-create-str/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -fn main() { - // ANCHOR: here - let s1: str = "Hello there!"; - let s2: str = "How's it going?"; - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-12-generic-fn-definition/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-13-generic-implicit-sized-bound/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock deleted file mode 100644 index c0c98a79c..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-14-generic-maybe-sized/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "types-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock deleted file mode 100644 index b2327c755..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-16-map-function/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "functions-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock deleted file mode 100644 index b2327c755..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-17-map-initializer/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "functions-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs deleted file mode 100644 index 60fb73005..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-17-map-initializer/src/main.rs +++ /dev/null @@ -1,10 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock deleted file mode 100644 index b2327c755..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "functions-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt b/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt deleted file mode 100644 index bc736bd68..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/output.txt +++ /dev/null @@ -1,20 +0,0 @@ -$ cargo build - Compiling functions-example v0.1.0 (file:///projects/functions-example) -error[E0746]: return type cannot have an unboxed trait object - --> src/lib.rs:1:25 - | -1 | fn returns_closure() -> dyn Fn(i32) -> i32 { - | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | -help: return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type - | -1 | fn returns_closure() -> impl Fn(i32) -> i32 { - | ~~~~ -help: box the return type, and wrap all of the returned values in `Box::new` - | -1 ~ fn returns_closure() -> Box i32> { -2 ~ Box::new(|x| x + 1) - | - -For more information about this error, try `rustc --explain E0746`. -error: could not compile `functions-example` (lib) due to 1 previous error diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs deleted file mode 100644 index d699ac34e..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-18-returns-closure/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn returns_closure() -> dyn Fn(i32) -> i32 { - |x| x + 1 -} diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock deleted file mode 100644 index b2327c755..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "functions-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml b/rustbook-en/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml deleted file mode 100644 index b196f35b5..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-19-returns-closure-trait-object/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "functions-example" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock deleted file mode 100644 index 39afcf282..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello_macro" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs deleted file mode 100644 index e74793184..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/hello_macro/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait HelloMacro { - fn hello_macro(); -} diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs deleted file mode 100644 index 10b028b2d..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-20-impl-hellomacro-for-pancakes/pancakes/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock deleted file mode 100644 index 39afcf282..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello_macro" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/src/lib.rs deleted file mode 100644 index 654b6bee5..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/hello_macro_derive/src/lib.rs +++ /dev/null @@ -1,24 +0,0 @@ -use proc_macro::TokenStream; -use quote::quote; - -#[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/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/lib.rs deleted file mode 100644 index e74793184..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub trait HelloMacro { - fn hello_macro(); -} diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/main.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/main.rs deleted file mode 100644 index 10b028b2d..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-21-pancakes/hello_macro/src/main.rs +++ /dev/null @@ -1,13 +0,0 @@ -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/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/Cargo.lock deleted file mode 100644 index 58b70c5b7..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "counter" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/Cargo.toml b/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/Cargo.toml deleted file mode 100644 index 9e103f3eb..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "counter" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/src/lib.rs b/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/src/lib.rs deleted file mode 100644 index 04c7f38f5..000000000 --- a/rustbook-en/listings/ch19-advanced-features/no-listing-22-iterator-on-counter/src/lib.rs +++ /dev/null @@ -1,25 +0,0 @@ -struct Counter { - count: u32, -} - -impl Counter { - fn new() -> Counter { - Counter { count: 0 } - } -} - -// ANCHOR: ch19 -impl Iterator for Counter { - type Item = u32; - - fn next(&mut self) -> Option { - // --snip-- - // ANCHOR_END: ch19 - if self.count < 5 { - self.count += 1; - Some(self.count) - } else { - None - } - } -} diff --git a/rustbook-en/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock b/rustbook-en/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock deleted file mode 100644 index 497817bf2..000000000 --- a/rustbook-en/listings/ch19-advanced-features/output-only-01-missing-unsafe/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "unsafe-example" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt b/rustbook-en/listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt deleted file mode 100644 index b14994cdd..000000000 --- a/rustbook-en/listings/ch19-advanced-features/output-only-01-missing-unsafe/output.txt +++ /dev/null @@ -1,12 +0,0 @@ -$ cargo run - Compiling unsafe-example v0.1.0 (file:///projects/unsafe-example) -error[E0133]: call to unsafe function `dangerous` is unsafe and requires unsafe function or block - --> src/main.rs:4:5 - | -4 | dangerous(); - | ^^^^^^^^^^^ call to unsafe function - | - = note: consult the function's documentation for information on how to avoid undefined behavior - -For more information about this error, try `rustc --explain E0133`. -error: could not compile `unsafe-example` (bin "unsafe-example") due to 1 previous error diff --git a/rustbook-en/listings/ch20-web-server/listing-20-01/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-01/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-01/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-02/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-02/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-02/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-02/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-02/src/main.rs deleted file mode 100644 index f139846c6..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-02/src/main.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::{ - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - handle_connection(stream); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let http_request: Vec<_> = buf_reader - .lines() - .map(|result| result.unwrap()) - .take_while(|line| !line.is_empty()) - .collect(); - - println!("Request: {http_request:#?}"); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-03/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-03/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-03/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-03/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-03/src/main.rs deleted file mode 100644 index c72d4a9c6..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-03/src/main.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::{ - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - handle_connection(stream); - } -} - -// ANCHOR: here -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let http_request: Vec<_> = buf_reader - .lines() - .map(|result| result.unwrap()) - .take_while(|line| !line.is_empty()) - .collect(); - - let response = "HTTP/1.1 200 OK\r\n\r\n"; - - stream.write_all(response.as_bytes()).unwrap(); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-05/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-05/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-05/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-05/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-05/src/main.rs deleted file mode 100644 index d4b78b640..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-05/src/main.rs +++ /dev/null @@ -1,38 +0,0 @@ -// ANCHOR: here -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, -}; -// --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) { - let buf_reader = BufReader::new(&mut stream); - let http_request: Vec<_> = buf_reader - .lines() - .map(|result| result.unwrap()) - .take_while(|line| !line.is_empty()) - .collect(); - - let status_line = "HTTP/1.1 200 OK"; - let contents = fs::read_to_string("hello.html").unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-06/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-06/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-06/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-06/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-06/src/main.rs deleted file mode 100644 index 5523a42d7..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-06/src/main.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - handle_connection(stream); - } -} -// ANCHOR: here -// --snip-- - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - if request_line == "GET / HTTP/1.1" { - let status_line = "HTTP/1.1 200 OK"; - let contents = fs::read_to_string("hello.html").unwrap(); - let length = contents.len(); - - let response = format!( - "{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}" - ); - - stream.write_all(response.as_bytes()).unwrap(); - } else { - // some other request - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-07/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-07/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-07/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-07/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-07/src/main.rs deleted file mode 100644 index a14b7d538..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-07/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - handle_connection(stream); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - if request_line == "GET / HTTP/1.1" { - let status_line = "HTTP/1.1 200 OK"; - let contents = fs::read_to_string("hello.html").unwrap(); - let length = contents.len(); - - let response = format!( - "{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}" - ); - - stream.write_all(response.as_bytes()).unwrap(); - // ANCHOR: here - // --snip-- - } else { - let status_line = "HTTP/1.1 404 NOT FOUND"; - let contents = fs::read_to_string("404.html").unwrap(); - let length = contents.len(); - - let response = format!( - "{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}" - ); - - stream.write_all(response.as_bytes()).unwrap(); - } - // ANCHOR_END: here -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-09/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-09/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-09/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-09/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-09/src/main.rs deleted file mode 100644 index ffc51e803..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-09/src/main.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - handle_connection(stream); - } -} -// ANCHOR: here -// --snip-- - -fn handle_connection(mut stream: TcpStream) { - // --snip-- - // ANCHOR_END: here - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - // ANCHOR: here - - let (status_line, filename) = if request_line == "GET / HTTP/1.1" { - ("HTTP/1.1 200 OK", "hello.html") - } else { - ("HTTP/1.1 404 NOT FOUND", "404.html") - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-10/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-10/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-10/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-10/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-10/src/main.rs deleted file mode 100644 index 5a18b45c0..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-10/src/main.rs +++ /dev/null @@ -1,52 +0,0 @@ -// ANCHOR: here -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - 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 buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - // ANCHOR: here - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - // --snip-- - // ANCHOR_END: here - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); - // ANCHOR: here -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-11/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-11/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-11/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-11/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-11/src/main.rs deleted file mode 100644 index 1181357b0..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-11/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - 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 buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-12/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-12/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-12/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-12/output.txt b/rustbook-en/listings/ch20-web-server/listing-20-12/output.txt deleted file mode 100644 index 0faae9920..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-12/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo check - Checking hello v0.1.0 (file:///projects/hello) -error[E0433]: failed to resolve: use of undeclared type `ThreadPool` - --> src/main.rs:11:16 - | -11 | let pool = ThreadPool::new(4); - | ^^^^^^^^^^ use of undeclared type `ThreadPool` - -For more information about this error, try `rustc --explain E0433`. -error: could not compile `hello` (bin "hello") due to 1 previous error diff --git a/rustbook-en/listings/ch20-web-server/listing-20-12/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-12/src/main.rs deleted file mode 100644 index 21b9a80f1..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-12/src/main.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - 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 buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-13/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-13/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-13/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-13/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-13/src/lib.rs deleted file mode 100644 index 35960e7c0..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-13/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -pub struct ThreadPool; - -// ANCHOR: here -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - ThreadPool - } - - // --snip-- - // ANCHOR_END: here - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - } - // ANCHOR: here -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-13/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-13/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-13/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-14/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-14/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-14/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-14/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-14/src/lib.rs deleted file mode 100644 index c1fa1828b..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-14/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -// 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/rustbook-en/listings/ch20-web-server/listing-20-14/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-14/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-14/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-15/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-15/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-15/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-15/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-15/src/lib.rs deleted file mode 100644 index 80a6eeeb3..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-15/src/lib.rs +++ /dev/null @@ -1,53 +0,0 @@ -// ANCHOR: here -use std::thread; - -pub struct ThreadPool { - workers: Vec, -} - -impl ThreadPool { - // --snip-- - // ANCHOR_END: here - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - // ANCHOR: here - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id)); - } - - ThreadPool { workers } - } - // --snip-- - // ANCHOR_END: here - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - } - // ANCHOR: here -} - -struct Worker { - id: usize, - thread: thread::JoinHandle<()>, -} - -impl Worker { - fn new(id: usize) -> Worker { - let thread = thread::spawn(|| {}); - - Worker { id, thread } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-15/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-15/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-15/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-16/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-16/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-16/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-16/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-16/src/lib.rs deleted file mode 100644 index 411c1d003..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-16/src/lib.rs +++ /dev/null @@ -1,58 +0,0 @@ -// ANCHOR: here -use std::{sync::mpsc, thread}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -struct Job; - -impl ThreadPool { - // --snip-- - // ANCHOR_END: here - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - // ANCHOR: here - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id)); - } - - ThreadPool { workers, sender } - } - // --snip-- - // ANCHOR_END: here - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - } - // ANCHOR: here -} -// ANCHOR_END: here - -struct Worker { - id: usize, - thread: thread::JoinHandle<()>, -} - -impl Worker { - fn new(id: usize) -> Worker { - let thread = thread::spawn(|| {}); - - Worker { id, thread } - } -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-16/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-16/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-16/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-17/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-17/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-17/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-17/output.txt b/rustbook-en/listings/ch20-web-server/listing-20-17/output.txt deleted file mode 100644 index 276826551..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-17/output.txt +++ /dev/null @@ -1,27 +0,0 @@ -$ cargo check - Checking hello v0.1.0 (file:///projects/hello) -error[E0382]: use of moved value: `receiver` - --> src/lib.rs:26:42 - | -21 | let (sender, receiver) = mpsc::channel(); - | -------- move occurs because `receiver` has type `std::sync::mpsc::Receiver`, which does not implement the `Copy` trait -... -25 | for id in 0..size { - | ----------------- inside of this loop -26 | workers.push(Worker::new(id, receiver)); - | ^^^^^^^^ value moved here, in previous iteration of loop - | -note: consider changing this parameter type in method `new` to borrow instead if owning the value isn't necessary - --> src/lib.rs:47:33 - | -47 | fn new(id: usize, receiver: mpsc::Receiver) -> Worker { - | --- in this method ^^^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value -help: consider moving the expression out of the loop so it is only moved once - | -25 ~ let mut value = Worker::new(id, receiver); -26 ~ for id in 0..size { -27 ~ workers.push(value); - | - -For more information about this error, try `rustc --explain E0382`. -error: could not compile `hello` (lib) due to 1 previous error diff --git a/rustbook-en/listings/ch20-web-server/listing-20-17/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-17/src/lib.rs deleted file mode 100644 index d764879e5..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-17/src/lib.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::{sync::mpsc, thread}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -struct Job; - -// ANCHOR: here -impl ThreadPool { - // --snip-- - // ANCHOR_END: here - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - // ANCHOR: here - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, receiver)); - } - - ThreadPool { workers, sender } - } - // --snip-- - // ANCHOR_END: here - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - } - // ANCHOR: here -} - -// --snip-- - -// ANCHOR_END: here - -struct Worker { - id: usize, - thread: thread::JoinHandle<()>, -} - -// ANCHOR: here -impl Worker { - fn new(id: usize, receiver: mpsc::Receiver) -> Worker { - let thread = thread::spawn(|| { - receiver; - }); - - Worker { id, thread } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-17/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-17/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-17/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-18/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-18/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-18/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-18/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-18/src/lib.rs deleted file mode 100644 index 4bff8acad..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-18/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -// ANCHOR: here -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; -// --snip-- - -// ANCHOR_END: here -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -struct Job; - -// ANCHOR: here -impl ThreadPool { - // --snip-- - // ANCHOR_END: here - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - // ANCHOR: here - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - // --snip-- - // ANCHOR_END: here - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - } - // ANCHOR: here -} - -// --snip-- - -// ANCHOR_END: here -struct Worker { - id: usize, - thread: thread::JoinHandle<()>, -} - -// ANCHOR: here -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - // --snip-- - // ANCHOR_END: here - let thread = thread::spawn(|| { - receiver; - }); - - Worker { id, thread } - // ANCHOR: here - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-18/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-18/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-18/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-19/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-19/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-19/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-19/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-19/src/lib.rs deleted file mode 100644 index aeb1facd6..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-19/src/lib.rs +++ /dev/null @@ -1,69 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -// ANCHOR: here -// --snip-- - -type Job = Box; - -impl ThreadPool { - // --snip-- - // ANCHOR_END: here - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - // ANCHOR: here - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -// --snip-- -// ANCHOR_END: here - -struct Worker { - id: usize, - thread: thread::JoinHandle<()>, -} - -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - let thread = thread::spawn(|| { - receiver; - }); - - Worker { id, thread } - } -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-19/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-19/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-19/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-20/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-20/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-20/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-20/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-20/src/lib.rs deleted file mode 100644 index 86157c9e7..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-20/src/lib.rs +++ /dev/null @@ -1,68 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -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 {id} got a job; executing."); - - job(); - }); - - Worker { id, thread } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-20/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-20/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-20/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-21/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-21/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-21/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-21/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-21/src/lib.rs deleted file mode 100644 index 17b37e77b..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-21/src/lib.rs +++ /dev/null @@ -1,67 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -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 {id} got a job; executing."); - - job(); - } - }); - - Worker { id, thread } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-21/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-21/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-21/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-22/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-22/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-22/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-22/output.txt b/rustbook-en/listings/ch20-web-server/listing-20-22/output.txt deleted file mode 100644 index 84ebe928b..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-22/output.txt +++ /dev/null @@ -1,15 +0,0 @@ -$ cargo check - Checking hello v0.1.0 (file:///projects/hello) -error[E0507]: cannot move out of `worker.thread` which is behind a mutable reference - --> src/lib.rs:52:13 - | -52 | worker.thread.join().unwrap(); - | ^^^^^^^^^^^^^ ------ `worker.thread` moved due to this method call - | | - | move occurs because `worker.thread` has type `JoinHandle<()>`, which does not implement the `Copy` trait - | -note: `JoinHandle::::join` takes ownership of the receiver `self`, which moves `worker.thread` - --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/thread/mod.rs:1718:17 - -For more information about this error, try `rustc --explain E0507`. -error: could not compile `hello` (lib) due to 1 previous error diff --git a/rustbook-en/listings/ch20-web-server/listing-20-22/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-22/src/lib.rs deleted file mode 100644 index 72a8c4808..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-22/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -// 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 {id} got a job; executing."); - - job(); - }); - - Worker { id, thread } - } -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-22/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-22/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-22/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-23/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-23/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-23/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-23/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-23/src/lib.rs deleted file mode 100644 index eea339b02..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-23/src/lib.rs +++ /dev/null @@ -1,95 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -// ANCHOR: here -pub struct ThreadPool { - workers: Vec, - sender: Option>, -} -// --snip-- -// ANCHOR_END: here - -type Job = Box; - -// ANCHOR: here -impl ThreadPool { - // 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 { - // --snip-- - - // ANCHOR_END: here - 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))); - } - - // ANCHOR: here - ThreadPool { - workers, - sender: Some(sender), - } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.as_ref().unwrap().send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - drop(self.sender.take()); - - 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 {id} got a job; executing."); - - job(); - }); - - Worker { - id, - thread: Some(thread), - } - } -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-23/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-23/src/main.rs deleted file mode 100644 index b6aa046d1..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-23/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming().take(2) { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } - - println!("Shutting down."); -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-24/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-24/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-24/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-24/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-24/src/lib.rs deleted file mode 100644 index 28c0dea26..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-24/src/lib.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: Option>, -} - -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: Some(sender), - } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.as_ref().unwrap().send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - drop(self.sender.take()); - - 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(); - - match message { - Ok(job) => { - println!("Worker {id} got a job; executing."); - - job(); - } - Err(_) => { - println!("Worker {id} disconnected; shutting down."); - break; - } - } - }); - - Worker { - id, - thread: Some(thread), - } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/listing-20-24/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-24/src/main.rs deleted file mode 100644 index b6aa046d1..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-24/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming().take(2) { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } - - println!("Shutting down."); -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-25/Cargo.lock b/rustbook-en/listings/ch20-web-server/listing-20-25/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-25/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/listing-20-25/src/lib.rs b/rustbook-en/listings/ch20-web-server/listing-20-25/src/lib.rs deleted file mode 100644 index 54c0489ab..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-25/src/lib.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: Option>, -} - -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: Some(sender), - } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.as_ref().unwrap().send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - drop(self.sender.take()); - - 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(); - - match message { - Ok(job) => { - println!("Worker {id} got a job; executing."); - - job(); - } - Err(_) => { - println!("Worker {id} disconnected; shutting down."); - break; - } - } - }); - - Worker { - id, - thread: Some(thread), - } - } -} diff --git a/rustbook-en/listings/ch20-web-server/listing-20-25/src/main.rs b/rustbook-en/listings/ch20-web-server/listing-20-25/src/main.rs deleted file mode 100644 index 86e8d9e78..000000000 --- a/rustbook-en/listings/ch20-web-server/listing-20-25/src/main.rs +++ /dev/null @@ -1,47 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - 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 buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock b/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt b/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt deleted file mode 100644 index 85ebfb813..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo check - Checking hello v0.1.0 (file:///projects/hello) -error[E0599]: no function or associated item named `new` found for struct `ThreadPool` in the current scope - --> src/main.rs:12:28 - | -12 | let pool = ThreadPool::new(4); - | ^^^ function or associated item not found in `ThreadPool` - -For more information about this error, try `rustc --explain E0599`. -error: could not compile `hello` (bin "hello") due to 1 previous error diff --git a/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/main.rs b/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/main.rs deleted file mode 100644 index f7b42167f..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-01-define-threadpool-struct/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -// ANCHOR: here -use hello::ThreadPool; -// ANCHOR_END: here -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock b/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt b/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt deleted file mode 100644 index 667041862..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/output.txt +++ /dev/null @@ -1,10 +0,0 @@ -$ cargo check - Checking hello v0.1.0 (file:///projects/hello) -error[E0599]: no method named `execute` found for struct `ThreadPool` in the current scope - --> src/main.rs:17:14 - | -17 | pool.execute(|| { - | -----^^^^^^^ method not found in `ThreadPool` - -For more information about this error, try `rustc --explain E0599`. -error: could not compile `hello` (bin "hello") due to 1 previous error diff --git a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs b/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs deleted file mode 100644 index f0e1890bb..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub struct ThreadPool; - -impl ThreadPool { - pub fn new(size: usize) -> ThreadPool { - ThreadPool - } -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/main.rs b/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-02-impl-threadpool-new/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock b/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs b/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs deleted file mode 100644 index 1321ab873..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/src/lib.rs +++ /dev/null @@ -1,18 +0,0 @@ -pub struct ThreadPool; - -// ANCHOR: here -impl ThreadPool { - // --snip-- - // ANCHOR_END: here - pub fn new(size: usize) -> ThreadPool { - ThreadPool - } - - // ANCHOR: here - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/src/main.rs b/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-03-define-execute/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock b/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt b/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt deleted file mode 100644 index 1ffe5206b..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt +++ /dev/null @@ -1,31 +0,0 @@ -$ cargo check - Checking hello v0.1.0 (file:///projects/hello) -error[E0599]: no method named `join` found for enum `Option` in the current scope - --> src/lib.rs:52:27 - | -52 | worker.thread.join().unwrap(); - | ^^^^ method not found in `Option>` - | -note: the method `join` exists on the type `JoinHandle<()>` - --> /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/thread/mod.rs:1718:5 -help: consider using `Option::expect` to unwrap the `JoinHandle<()>` value, panicking if the value is an `Option::None` - | -52 | worker.thread.expect("REASON").join().unwrap(); - | +++++++++++++++++ - -error[E0308]: mismatched types - --> src/lib.rs:72:22 - | -72 | Worker { id, thread } - | ^^^^^^ expected `Option>`, found `JoinHandle<_>` - | - = note: expected enum `Option>` - found struct `JoinHandle<_>` -help: try wrapping the expression in `Some` - | -72 | Worker { id, thread: Some(thread) } - | +++++++++++++ + - -Some errors have detailed explanations: E0308, E0599. -For more information about an error, try `rustc --explain E0308`. -error: could not compile `hello` (lib) due to 2 previous errors diff --git a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs b/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs deleted file mode 100644 index 6ef710a26..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - for worker in &mut self.workers { - println!("Shutting down worker {}", worker.id); - - worker.thread.join().unwrap(); - } - } -} - -// ANCHOR: here -struct Worker { - id: usize, - thread: Option>, -} -// ANCHOR_END: here - -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - let thread = thread::spawn(move || loop { - let job = receiver.lock().unwrap().recv().unwrap(); - - println!("Worker {id} got a job; executing."); - - job(); - }); - - Worker { id, thread } - } -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs b/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-04-update-worker-definition/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock b/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs b/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs deleted file mode 100644 index ede3750a1..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - for worker in &mut self.workers { - println!("Shutting down worker {}", worker.id); - - worker.thread.join().unwrap(); - } - } -} - -struct Worker { - id: usize, - thread: Option>, -} - -// ANCHOR: here -impl Worker { - fn new(id: usize, receiver: Arc>>) -> Worker { - // --snip-- - - // ANCHOR_END: here - let thread = thread::spawn(move || loop { - let job = receiver.lock().unwrap().recv().unwrap(); - - println!("Worker {id} got a job; executing."); - - job(); - }); - - // ANCHOR: here - Worker { - id, - thread: Some(thread), - } - } -} -// ANCHOR_END: here diff --git a/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs b/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs deleted file mode 100644 index 79efb28a2..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-05-fix-worker-new/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming() { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock b/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs b/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs deleted file mode 100644 index b795ea53b..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/lib.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: mpsc::Sender, -} - -type Job = Box; - -impl ThreadPool { - /// Create a new ThreadPool. - /// - /// The size is the number of threads in the pool. - /// - /// # Panics - /// - /// The `new` function will panic if the size is zero. - pub fn new(size: usize) -> ThreadPool { - assert!(size > 0); - - let (sender, receiver) = mpsc::channel(); - - let receiver = Arc::new(Mutex::new(receiver)); - - let mut workers = Vec::with_capacity(size); - - for id in 0..size { - workers.push(Worker::new(id, Arc::clone(&receiver))); - } - - ThreadPool { workers, sender } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.send(job).unwrap(); - } -} - -// 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 {id} got a job; executing."); - - job(); - }); - - Worker { - id, - thread: Some(thread), - } - } -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/main.rs b/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/main.rs deleted file mode 100644 index b6aa046d1..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-06-fix-threadpool-drop/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming().take(2) { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } - - println!("Shutting down."); -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/Cargo.lock b/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/Cargo.lock deleted file mode 100644 index f2d069f46..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "hello" -version = "0.1.0" - diff --git a/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/src/lib.rs b/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/src/lib.rs deleted file mode 100644 index 54c0489ab..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/src/lib.rs +++ /dev/null @@ -1,92 +0,0 @@ -use std::{ - sync::{mpsc, Arc, Mutex}, - thread, -}; - -pub struct ThreadPool { - workers: Vec, - sender: Option>, -} - -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: Some(sender), - } - } - - pub fn execute(&self, f: F) - where - F: FnOnce() + Send + 'static, - { - let job = Box::new(f); - - self.sender.as_ref().unwrap().send(job).unwrap(); - } -} - -impl Drop for ThreadPool { - fn drop(&mut self) { - drop(self.sender.take()); - - 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(); - - match message { - Ok(job) => { - println!("Worker {id} got a job; executing."); - - job(); - } - Err(_) => { - println!("Worker {id} disconnected; shutting down."); - break; - } - } - }); - - Worker { - id, - thread: Some(thread), - } - } -} diff --git a/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/src/main.rs b/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/src/main.rs deleted file mode 100644 index b6aa046d1..000000000 --- a/rustbook-en/listings/ch20-web-server/no-listing-07-final-code/src/main.rs +++ /dev/null @@ -1,45 +0,0 @@ -use hello::ThreadPool; -use std::{ - fs, - io::{prelude::*, BufReader}, - net::{TcpListener, TcpStream}, - thread, - time::Duration, -}; - -fn main() { - let listener = TcpListener::bind("127.0.0.1:7878").unwrap(); - let pool = ThreadPool::new(4); - - for stream in listener.incoming().take(2) { - let stream = stream.unwrap(); - - pool.execute(|| { - handle_connection(stream); - }); - } - - println!("Shutting down."); -} - -fn handle_connection(mut stream: TcpStream) { - let buf_reader = BufReader::new(&mut stream); - let request_line = buf_reader.lines().next().unwrap().unwrap(); - - let (status_line, filename) = match &request_line[..] { - "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"), - "GET /sleep HTTP/1.1" => { - thread::sleep(Duration::from_secs(5)); - ("HTTP/1.1 200 OK", "hello.html") - } - _ => ("HTTP/1.1 404 NOT FOUND", "404.html"), - }; - - let contents = fs::read_to_string(filename).unwrap(); - let length = contents.len(); - - let response = - format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}"); - - stream.write_all(response.as_bytes()).unwrap(); -} diff --git a/rustbook-en/nostarch/appendix.md b/rustbook-en/nostarch/appendix.md deleted file mode 100644 index 98432a1da..000000000 --- a/rustbook-en/nostarch/appendix.md +++ /dev/null @@ -1,775 +0,0 @@ - - -[TOC] - -## Appendix A: Keywords - -The following lists contain keywords that are reserved for current or future -use by the Rust language. As such, they cannot be used as identifiers (except -as raw identifiers, as we’ll discuss in “Raw Identifiers” on page XX). -*Identifiers* are names of functions, variables, parameters, struct fields, -modules, crates, constants, macros, static values, attributes, types, traits, -or lifetimes. - -## Keywords Currently in Use - -The following is a list of keywords currently in use, with their functionality -described. - -* **`as` **: perform primitive casting, disambiguate the specific trait -containing an item, or rename items in `use` statements -* **`async` **: return a `Future` instead of blocking the current thread -* **`await` **: suspend execution until the result of a `Future` is ready -* **`break` **: exit a loop immediately -* **`const` **: define constant items or constant raw pointers -* **`continue` **: continue to the next loop iteration -* **`crate` **: in a module path, refers to the crate root -* **`dyn` **: dynamic dispatch to a trait object -* **`else` **: fallback for `if` and `if let` control flow constructs -* **`enum` **: define an enumeration -* **`extern` **: link an external function or variable -* **`false` **: Boolean false literal -* **`fn` **: define a function or the function pointer type -* **`for` **: loop over items from an iterator, implement a trait, or specify a -higher-ranked lifetime -* **`if` **: branch based on the result of a conditional expression -* **`impl` **: implement inherent or trait functionality -* **`in` **: part of `for` loop syntax -* **`let` **: bind a variable -* **`loop` **: loop unconditionally -* **`match` **: match a value to patterns -* **`mod` **: define a module -* **`move` **: make a closure take ownership of all its captures -* **`mut` **: denote mutability in references, raw pointers, or pattern bindings -* **`pub` **: denote public visibility in struct fields, `impl` blocks, or -modules -* **`ref` **: bind by reference -* **`return` **: return from function -* **`Self` **: a type alias for the type we are defining or implementing -* **`self` **: method subject or current module -* **`static` **: global variable or lifetime lasting the entire program -execution -* **`struct` **: define a structure -* **`super` **: parent module of the current module -* **`trait` **: define a trait -* **`true` **: Boolean true literal -* **`type` **: define a type alias or associated type -* **`union` **: define a union; is a keyword only when used in a union -declaration -* **`unsafe` **: denote unsafe code, functions, traits, or implementations -* **`use` **: bring symbols into scope -* **`where` **: denote clauses that constrain a type -* **`while` **: loop conditionally based on the result of an expression - -## Keywords Reserved for Future Use - -The following keywords do not yet have any functionality but are reserved by -Rust for potential future use: - -* `abstract` -* `become` -* `box` -* `do` -* `final` -* `macro` -* `override` -* `priv` -* `try` -* `typeof` -* `unsized` -* `virtual` -* `yield` - -## Raw Identifiers - -*Raw identifiers* are the syntax that lets you use keywords where they wouldn’t -normally be allowed. You use a raw identifier by prefixing a keyword with `r#`. - -For example, `match` is a keyword. If you try to compile the following function -that uses `match` as its name: - -Filename: src/main.rs - -``` -fn match(needle: &str, haystack: &str) -> bool { - haystack.contains(needle) -} -``` - -you’ll get this error: - -``` -error: expected identifier, found keyword `match` - --> src/main.rs:4:4 - | -4 | fn match(needle: &str, haystack: &str) -> bool { - | ^^^^^ expected identifier, found keyword -``` - -The error shows that you can’t use the keyword `match` as the function -identifier. To use `match` as a function name, you need to use the raw -identifier syntax, like this: - -Filename: src/main.rs - -``` -fn r#match(needle: &str, haystack: &str) -> bool { - haystack.contains(needle) -} - -fn main() { - assert!(r#match("foo", "foobar")); -} -``` - -This code will compile without any errors. Note the `r#` prefix on the function -name in its definition as well as where the function is called in `main`. - -Raw identifiers allow you to use any word you choose as an identifier, even if -that word happens to be a reserved keyword. This gives us more freedom to -choose identifier names, as well as lets us integrate with programs written in -a language where these words aren’t keywords. In addition, raw identifiers -allow you to use libraries written in a different Rust edition than your crate -uses. For example, `try` isn’t a keyword in the 2015 edition but is in the 2018 -and 2021 editions. If you depend on a library that is written using the 2015 -edition and has a `try` function, you’ll need to use the raw identifier syntax, -`r#try` in this case, to call that function from your 2021 edition code. See -Appendix E for more information on editions. - -## Appendix B: Operators and Symbols - -This appendix contains a glossary of Rust’s syntax, including operators and -other symbols that appear by themselves or in the context of paths, generics, -trait bounds, macros, attributes, comments, tuples, and brackets. - -## Operators - -Table B-1 contains the operators in Rust, an example of how the operator would -appear in context, a short explanation, and whether that operator is -overloadable. If an operator is overloadable, the relevant trait to use to -overload that operator is listed. - -Table B-1: Operators - -| Operator | Example | Explanation | Overloadable? | -|---|---|---|---| -| `!` | `ident!(...)`, `ident!{...}`, `ident![...]` | Macro expansion | | -| `!` | `!expr` | Bitwise or logical complement | `Not` | -| `!=` | `expr != expr` | Nonequality comparison | `PartialEq` | -| `% | `expr % expr` | Arithmetic remainder | `Rem` | -| `%=` | `var %= expr` | Arithmetic remainder and assignment | `RemAssign` | -| `& | `&expr`, `&mut expr` | Borrow | | -| `&` | `&type`, `&mut type`, `&'a type`, `&'a mut type` | Borrowed pointer -type | | -| `&` | `expr & expr` | Bitwise AND | `BitAnd` | -| `&=` | `var &= expr` | Bitwise AND and assignment | `BitAndAssign` | -| `&&` | `expr && expr` | Short-circuiting logical AND | | -| `* | `expr * expr` | Arithmetic multiplication | `Mul` | -| `*=` | `var *= expr` | Arithmetic multiplication and assignment | `MulAssign` -| -| `*` | `*expr` | Dereference | `Deref` | -| `*` | `*const type`, `*mut type | Raw pointer | | -| `+ | `trait + trait`, `'a + trait` | Compound type constraint | | -| `+ | `expr + expr` | Arithmetic addition | `Add` | -| `+=` | `var += expr` | Arithmetic addition and assignment | `AddAssign` | -| `,` | `expr, expr` | Argument and element separator | | -| `- | `- expr` | Arithmetic negation | `Neg` | -| `- | `expr - expr` | Arithmetic subtraction | `Sub` | -| `-=` | `var -= expr` | Arithmetic subtraction and assignment | `SubAssign` | -| `-> | `fn(...) -> type`, `|…| -> type` | Function and closure return type | | -| `. | `expr.ident` | Member access | | -| `..` | `..`, `expr..`, `..expr`, `expr..expr` | Right-exclusive range literal -| `PartialOrd` | -| `..=` | `..=expr`, `expr..=expr` | Right-inclusive range literal | -`PartialOrd` | -| `..` | `..expr` | Struct literal update syntax | | -| `..` | `variant(x, ..)`, `struct_type { x, .. }` | “And the rest” pattern -binding | | -| `...` | `expr...expr` | (Deprecated, use `..=` instead) In a pattern: -inclusive range pattern | | -| `/ | `expr / expr` | Arithmetic division | `Div` | -| `/=` | `var /= expr` | Arithmetic division and assignment | `DivAssign` | -| `: | `pat: type`, `ident: type` | Constraints | | -| `:` | `ident: expr` | Struct field initializer | | -| `:` | `'a: loop {...}` | Loop label | | -| `; | `expr;` | Statement and item terminator | | -| `;` | `[...; len]` | Part of fixed-size array syntax | | -| `<<` | `expr << expr` | Left-shift | `Shl` | -| `<<=` | `var <<= expr` | Left-shift and assignment | `ShlAssign` | -| `<` | `expr < expr` | Less than comparison | `PartialOrd` | -| `<=` | `expr <= expr` | Less than or equal to comparison | `PartialOrd` | -| `=` | `var = expr`, `ident = type` | Assignment/equivalence | | -| `==` | `expr == expr` | Equality comparison | `PartialEq` | -| `=>` | `pat => expr` | Part of match arm syntax | | -| `>` | `expr > expr` | Greater than comparison | `PartialOrd` | -| `>=` | `expr >= expr` | Greater than or equal to comparison | `PartialOrd` | -| `>>` | `expr >> expr` | Right-shift | `Shr` | -| `>>=` | `var >>= expr` | Right-shift and assignment | `ShrAssign` | -| `@ | `ident @ pat` | Pattern binding | | -| `^` | `expr ^ expr` | Bitwise exclusive OR | `BitXor` | -| `^=` | `var ^= expr` | Bitwise exclusive OR and assignment | `BitXorAssign` | -| `| | `pat | pat` | Pattern alternatives | | -| `|` | `expr | expr` | Bitwise OR | `BitOr` | -| `|=` | `var |= expr` | Bitwise OR and assignment | `BitOrAssign` | -| `||` | `expr || expr` | Short-circuiting logical OR | | -| `? | `expr?` | Error propagation | | - -## Non-operator Symbols - -The following tables contain all symbols that don’t function as operators; that -is, they don’t behave like a function or method call. - -Table B-2 shows symbols that appear on their own and are valid in a variety of -locations. - -Table B-2: Stand-Alone Syntax - -| Symbol | Explanation | -|---|---| -| `'ident | Named lifetime or loop label | -| `...u8`, `...i32`, `...f64`, `...usize`, and so on | Numeric literal of -specific type | -| `"..." | String literal | -| `r"..."`, `r#"..."#`, `r##"..."##`, and so on | Raw string literal; escape -characters not processed | -| `b"..."` | Byte string literal; constructs an array of bytes instead of a -string | -| `br"..."`, `br#"..."#`, `br##"..."##`, and so on | Raw byte string literal; -combination of raw and byte string literal | -| `'...' | Character literal | -| `b'...' | ASCII byte literal | -| `|…| expr | Closure | -| `! | Always-empty bottom type for diverging functions | -| `_ | “Ignored” pattern binding; also used to make integer literals readable | - -Table B-3 shows symbols that appear in the context of a path through the module -hierarchy to an item. - -Table B-3: Path-Related Syntax - -| Symbol | Explanation | -|---|---| -| `ident::ident | Namespace path | -| `::path` | Path relative to the crate root (that is, an explicitly absolute -path) | -| `self::path` | Path relative to the current module (that is, an explicitly -relative path) | -| `super::path` | Path relative to the parent of the current module | -| `type::ident`, `::ident | Associated constants, functions, and -types | -| `::...` | Associated item for a type that cannot be directly named (for -example, `<&T>::...`, `<[T]>::...`, and so on) | -| `trait::method(...)` | Disambiguating a method call by naming the trait that -defines it | -| `type::method(...)` | Disambiguating a method call by naming the type for -which it’s defined | -| `::method(...)` | Disambiguating a method call by naming the -trait and type | - -Table B-4 shows symbols that appear in the context of using generic type -parameters. - -Table B-4: Generics - -| Symbol | Explanation | -|---|---| -| `path<...>` | Specifies parameters to a generic type in a type (for example, -`Vec`) | -| `path::<...>, method::<...>` | Specifies parameters to a generic type, -function, or method in an expression; often referred to as turbofish (for -example, `"42".parse::()`) | -| `fn ident<...> ...` | Define generic function | -| `struct ident<...> ...` | Define generic structure | -| `enum ident<...> ...` | Define generic enumeration | -| `impl<...> ...` | Define generic implementation | -| `for<...> type` | Higher-ranked lifetime bounds | -| `type` | A generic type where one or more associated types have -specific assignments (for example, `Iterator`) | - -Table B-5 shows symbols that appear in the context of constraining generic type -parameters with trait bounds. - -Table B-5: Trait Bound Constraints - -| Symbol | Explanation | -|---|---| -| T: U` | Generic parameter `T` constrained to types that implement `U` | -| `T: 'a` | Generic type `T` must outlive lifetime `'a` (meaning the type -cannot transitively contain any references with lifetimes shorter than `'a`) | -| `T: 'static` | Generic type `T` contains no borrowed references other than -`'static` ones | -| `'b: 'a` | Generic lifetime `'b` must outlive lifetime `'a` | -| `T: ?Sized` | Allow generic type parameter to be a dynamically sized type | -| `'a + trait`, `trait + trait` | Compound type constraint | - -Table B-6 shows symbols that appear in the context of calling or defining -macros and specifying attributes on an item. - -Table B-6: Macros and Attributes - -| Symbol | Explanation | -|---|---| -| `#[meta]` | Outer attribute | -| `#![meta]` | Inner attribute | -| `$ident` | Macro substitution | -| `$ident:kind` | Macro capture | -| `$(…)…` | Macro repetition | -| `ident!(...)`, `ident!{...}`, `ident![...]` | Macro invocation | - -Table B-7 shows symbols that create comments. - -Table B-7: Comments - -| Symbol | Explanation | -|---|---| -| `//` | Line comment | -| `//!` | Inner line doc comment | -| `///` | Outer line doc comment | -| `/*...*/` | Block comment | -| `/*!...*/` | Inner block doc comment | -| `/**...*/` | Outer block doc comment | - -Table B-8 shows symbols that appear in the context of using tuples. - -Table B-8: Tuples - -| Symbol | Explanation | -|---|---| -| `() | Empty tuple (aka unit), both literal and type | -| `(expr)` | Parenthesized expression | -| `(expr,)` | Single-element tuple expression | -| `(type,)` | Single-element tuple type | -| `(expr, ...)` | Tuple expression | -| `(type, ...)` | Tuple type | -| `expr(expr, ...)` | Function call expression; also used to initialize tuple -`struct`s and tuple `enum` variants | -| `expr.0`, `expr.1`, and so on | Tuple indexing | - -Table B-9 shows the contexts in which curly brackets are used. - -Table B-9: Curly Brackets - -| Context | Explanation | -|---|---| -| `{...}` | Block expression | -| `Type {...}` | `struct` literal | - -Table B-10 shows the contexts in which square brackets are used. - -Table B-10: Square Brackets - -| Context | Explanation | -|---|---| -| `[...]` | Array literal | -| `[expr; len]` | Array literal containing `len` copies of `expr` | -| `[type; len]` | Array type containing `len` instances of `type` | -| `expr[expr]` | Collection indexing; overloadable (`Index`, `IndexMut`) | -| `expr[..]`, `expr[a..]`, `expr[..b]`, `expr[a..b]` | Collection indexing -pretending to be collection slicing, using `Range`, `RangeFrom`, `RangeTo`, or -`RangeFull` as the “index” | - -## Appendix C: Derivable Traits - -In various places in the book, we’ve discussed the `derive` attribute, which -you can apply to a struct or enum definition. The `derive` attribute generates -code that will implement a trait with its own default implementation on the -type you’ve annotated with the `derive` syntax. - -In this appendix, we provide a reference of all the traits in the standard -library that you can use with `derive`. Each section covers: - -* What operators and methods deriving this trait will enable -* What the implementation of the trait provided by `derive` does -* What implementing the trait signifies about the type -* The conditions in which you’re allowed or not allowed to implement the trait -* Examples of operations that require the trait - -If you want different behavior from that provided by the `derive` attribute, -consult the standard library documentation for each trait for details on how to -manually implement them. - -The traits listed here are the only ones defined by the standard library that -can be implemented on your types using `derive`. Other traits defined in the -standard library don’t have sensible default behavior, so it’s up to you to -implement them in the way that makes sense for what you’re trying to accomplish. - -An example of a trait that can’t be derived is `Display`, which handles -formatting for end users. You should always consider the appropriate way to -display a type to an end user. What parts of the type should an end user be -allowed to see? What parts would they find relevant? What format of the data -would be most relevant to them? The Rust compiler doesn’t have this insight, so -it can’t provide appropriate default behavior for you. - -The list of derivable traits provided in this appendix is not comprehensive: -libraries can implement `derive` for their own traits, making the list of -traits you can use `derive` with truly open ended. Implementing `derive` -involves using a procedural macro, which is covered in “Macros” on page XX. - -## Debug for Programmer Output - -The `Debug` trait enables debug formatting in format strings, which you -indicate by adding `:?` within `{}` placeholders. - -The `Debug` trait allows you to print instances of a type for debugging -purposes, so you and other programmers using your type can inspect an instance -at a particular point in a program’s execution. - -The `Debug` trait is required, for example, in the use of the `assert_eq!` -macro. This macro prints the values of instances given as arguments if the -equality assertion fails so programmers can see why the two instances weren’t -equal. - -## PartialEq and Eq for Equality Comparisons - -The `PartialEq` trait allows you to compare instances of a type to check for -equality and enables use of the `==` and `!=` operators. - -Deriving `PartialEq` implements the `eq` method. When `PartialEq` is derived on -structs, two instances are equal only if *all* fields are equal, and the -instances are not equal if any fields are not equal. When derived on enums, -each variant is equal to itself and not equal to the other variants. - -The `PartialEq` trait is required, for example, with the use of the -`assert_eq!` macro, which needs to be able to compare two instances of a type -for equality. - -The `Eq` trait has no methods. Its purpose is to signal that for every value of -the annotated type, the value is equal to itself. The `Eq` trait can only be -applied to types that also implement `PartialEq`, although not all types that -implement `PartialEq` can implement `Eq`. One example of this is floating-point -number types: the implementation of floating-point numbers states that two -instances of the not-a-number (`NaN`) value are not equal to each other. - -An example of when `Eq` is required is for keys in a `HashMap` so that -the `HashMap` can tell whether two keys are the same. - -## PartialOrd and Ord for Ordering Comparisons - -The `PartialOrd` trait allows you to compare instances of a type for sorting -purposes. A type that implements `PartialOrd` can be used with the `<`, `>`, -`<=`, and `>=` operators. You can only apply the `PartialOrd` trait to types -that also implement `PartialEq`. - -Deriving `PartialOrd` implements the `partial_cmp` method, which returns an -`Option` that will be `None` when the values given don’t produce an -ordering. An example of a value that doesn’t produce an ordering, even though -most values of that type can be compared, is the not-a-number (`NaN`) floating -point value. Calling `partial_cmp` with any floating-point number and the `NaN` -floating-point value will return `None`. - -When derived on structs, `PartialOrd` compares two instances by comparing the -value in each field in the order in which the fields appear in the struct -definition. When derived on enums, variants of the enum declared earlier in the -enum definition are considered less than the variants listed later. - -The `PartialOrd` trait is required, for example, for the `gen_range` method -from the `rand` crate that generates a random value in the range specified by a -range expression. - -The `Ord` trait allows you to know that for any two values of the annotated -type, a valid ordering will exist. The `Ord` trait implements the `cmp` method, -which returns an `Ordering` rather than an `Option` because a valid -ordering will always be possible. You can only apply the `Ord` trait to types -that also implement `PartialOrd` and `Eq` (and `Eq` requires `PartialEq`). When -derived on structs and enums, `cmp` behaves the same way as the derived -implementation for `partial_cmp` does with `PartialOrd`. - -An example of when `Ord` is required is when storing values in a `BTreeSet`, -a data structure that stores data based on the sort order of the values. - -## Clone and Copy for Duplicating Values - -The `Clone` trait allows you to explicitly create a deep copy of a value, and -the duplication process might involve running arbitrary code and copying heap -data. See “Variables and Data Interacting with Clone” on page XX for more -information on `Clone`. - -Deriving `Clone` implements the `clone` method, which when implemented for the -whole type, calls `clone` on each of the parts of the type. This means all the -fields or values in the type must also implement `Clone` to derive `Clone`. - -An example of when `Clone` is required is when calling the `to_vec` method on a -slice. The slice doesn’t own the type instances it contains, but the vector -returned from `to_vec` will need to own its instances, so `to_vec` calls -`clone` on each item. Thus the type stored in the slice must implement `Clone`. - -The `Copy` trait allows you to duplicate a value by only copying bits stored on -the stack; no arbitrary code is necessary. See “Stack-Only Data: Copy” on page -XX for more information on `Copy`. - -The `Copy` trait doesn’t define any methods to prevent programmers from -overloading those methods and violating the assumption that no arbitrary code -is being run. That way, all programmers can assume that copying a value will be -very fast. - -You can derive `Copy` on any type whose parts all implement `Copy`. A type that -implements `Copy` must also implement `Clone` because a type that implements -`Copy` has a trivial implementation of `Clone` that performs the same task as -`Copy`. - -The `Copy` trait is rarely required; types that implement `Copy` have -optimizations available, meaning you don’t have to call `clone`, which makes -the code more concise. - -Everything possible with `Copy` you can also accomplish with `Clone`, but the -code might be slower or have to use `clone` in places. - -## Hash for Mapping a Value to a Value of Fixed Size - -The `Hash` trait allows you to take an instance of a type of arbitrary size and -map that instance to a value of fixed size using a hash function. Deriving -`Hash` implements the `hash` method. The derived implementation of the `hash` -method combines the result of calling `hash` on each of the parts of the type, -meaning all fields or values must also implement `Hash` to derive `Hash`. - -An example of when `Hash` is required is in storing keys in a `HashMap` -to store data efficiently. - -## Default for Default Values - -The `Default` trait allows you to create a default value for a type. Deriving -`Default` implements the `default` function. The derived implementation of the -`default` function calls the `default` function on each part of the type, -meaning all fields or values in the type must also implement `Default` to -derive `Default`. - -The `Default::default` function is commonly used in combination with the struct -update syntax discussed in “Creating Instances from Other Instances with Struct -Update Syntax” on page XX. You can customize a few fields of a struct and then -set and use a default value for the rest of the fields by using -`..Default::default()`. - -The `Default` trait is required when you use the method `unwrap_or_default` on -`Option` instances, for example. If the `Option` is `None`, the method -`unwrap_or_default` will return the result of `Default::default` for the type -`T` stored in the `Option`. - -## Appendix D: Useful Development Tools - -In this appendix, we talk about some useful development tools that the Rust -project provides. We’ll look at automatic formatting, quick ways to apply -warning fixes, a linter, and integrating with IDEs. - -## Automatic Formatting with rustfmt - -The `rustfmt` tool reformats your code according to the community code style. -Many collaborative projects use `rustfmt` to prevent arguments about which -style to use when writing Rust: everyone formats their code using the tool. - -Rust installations include `rustfmt` by default, so you should already have the -programs `rustfmt` and `cargo-fmt` on your system. These two commands are -analagous to `rustc` and `cargo` in that `rustfmt` allows finer-grained control -and `cargo-fmt` understands conventions of a project that uses Cargo. To format -any Cargo project, enter the following: - -``` -$ cargo fmt -``` - -Running this command reformats all the Rust code in the current crate. This -should only change the code style, not the code semantics. For more information -on `rustfmt`, see its documentation at *https://github.com/rust-lang/rustfmt*. - -## Fix Your Code with rustfix - -The `rustfix` tool is included with Rust installations and can automatically -fix compiler warnings that have a clear way to correct the problem that’s -likely what you want. You’ve probably seen compiler warnings before. For -example, consider this code: - -Filename: src/main.rs - -``` -fn do_something() {} - -fn main() { - for i in 0..100 { - do_something(); - } -} -``` - -Here, we’re calling the `do_something` function 100 times, but we never use the -variable `i` in the body of the `for` loop. Rust warns us about that: - -``` -$ cargo build - Compiling myprogram v0.1.0 (file:///projects/myprogram) -warning: unused variable: `i` - --> src/main.rs:4:9 - | -4 | for i in 0..100 { - | ^ help: consider using `_i` instead - | - = note: #[warn(unused_variables)] on by default - - Finished dev [unoptimized + debuginfo] target(s) in 0.50s -``` - -The warning suggests that we use `_i` as a name instead: the underscore -indicates that we intend for this variable to be unused. We can automatically -apply that suggestion using the `rustfix` tool by running the command `cargo -fix`: - -``` -$ cargo fix - Checking myprogram v0.1.0 (file:///projects/myprogram) - Fixing src/main.rs (1 fix) - Finished dev [unoptimized + debuginfo] target(s) in 0.59s -``` - -When we look at *src/main.rs* again, we’ll see that `cargo fix` has changed the -code: - -Filename: src/main.rs - -``` -fn do_something() {} - -fn main() { - for _i in 0..100 { - do_something(); - } -} -``` - -The `for` loop variable is now named `_i`, and the warning no longer appears. - -You can also use the `cargo fix` command to transition your code between -different Rust editions. Editions are covered in Appendix E. - -## More Lints with Clippy - -The Clippy tool is a collection of lints to analyze your code so you can catch -common mistakes and improve your Rust code. Clippy is included with standard -Rust installations. - -To run Clippy’s lints on any Cargo project, enter the following: - -``` -$ cargo clippy -``` - -For example, say you write a program that uses an approximation of a -mathematical constant, such as pi, as this program does: - -Filename: src/main.rs - -``` -fn main() { - let x = 3.1415; - let r = 8.0; - println!("the area of the circle is {}", x * r * r); -} -``` - -Running `cargo clippy` on this project results in this error: - -``` -error: approximate value of `f{32, 64}::consts::PI` found - --> src/main.rs:2:13 - | -2 | let x = 3.1415; - | ^^^^^^ - | - = note: `#[deny(clippy::approx_constant)]` on by default - = help: consider using the constant directly - = help: for further information visit https://rust-lang.github.io/rust- -clippy/master/index.html#approx_constant -``` - -This error lets you know that Rust already has a more precise `PI` constant -defined, and that your program would be more correct if you used the constant -instead. You would then change your code to use the `PI` constant. - -The following code doesn’t result in any errors or warnings from Clippy: - -Filename: src/main.rs - -``` -fn main() { - let x = std::f64::consts::PI; - let r = 8.0; - println!("the area of the circle is {}", x * r * r); -} -``` - -For more information on Clippy, see its documentation at -*https://github.com/rust-lang/rust-clippy**.* - -## IDE Integration Using rust-analyzer - -To help with IDE integration, the Rust community recommends using -`rust-analyzer`. This tool is a set of compiler-centric utilities that speak -Language Server Protocol, which is a specification for IDEs and programming -languages to communicate with each other. Different clients can use -`rust-analyzer`, such as the Rust analyzer plug-in for Visual Studio Code at -*https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer*. - -Visit the `rust-analyzer` project’s home page at -*https://rust-analyzer.github.io* for installation instructions, then install -the language server support in your particular IDE. Your IDE will gain -capabilities such as autocompletion, jump to definition, and inline errors - -## Appendix E: Editions - -In Chapter 1, you saw that `cargo new` adds a bit of metadata to your -*Cargo.toml* file about an edition. This appendix talks about what that means! - -The Rust language and compiler have a six-week release cycle, meaning users get -a constant stream of new features. Other programming languages release larger -changes less often; Rust releases smaller updates more frequently. After a -while, all of these tiny changes add up. But from release to release, it can be -difficult to look back and say, “Wow, between Rust 1.10 and Rust 1.31, Rust has -changed a lot!” - -Every two or three years, the Rust team produces a new Rust *edition*. Each -edition brings together the features that have landed into a clear package with -fully updated documentation and tooling. New editions ship as part of the usual -six-week release process. - -Editions serve different purposes for different people: - -* For active Rust users, a new edition brings together incremental changes into -an easy-to-understand package. -* For non-users, a new edition signals that some major advancements have -landed, which might make Rust worth another look. -* For those developing Rust, a new edition provides a rallying point for the -project as a whole. - -At the time of this writing, three Rust editions are available: Rust 2015, Rust -2018, and Rust 2021. This book is written using Rust 2021 edition idioms. - -The `edition` key in *Cargo.toml* indicates which edition the compiler should -use for your code. If the key doesn’t exist, Rust uses `2015` as the edition -value for backward compatibility reasons. - -Each project can opt in to an edition other than the default 2015 edition. -Editions can contain incompatible changes, such as including a new keyword that -conflicts with identifiers in code. However, unless you opt in to those -changes, your code will continue to compile even as you upgrade the Rust -compiler version you use. - -All Rust compiler versions support any edition that existed prior to that -compiler’s release, and they can link crates of any supported editions -together. Edition changes only affect the way the compiler initially parses -code. Therefore, if you’re using Rust 2015 and one of your dependencies uses -Rust 2018, your project will compile and be able to use that dependency. The -opposite situation, where your project uses Rust 2018 and a dependency uses -Rust 2015, works as well. - -To be clear: most features will be available on all editions. Developers using -any Rust edition will continue to see improvements as new stable releases are -made. However, in some cases, mainly when new keywords are added, some new -features might only be available in later editions. You will need to switch -editions if you want to take advantage of such features. - -For more details, *The* *Edition Guide* at -*https://doc.rust-lang.org/stable/edition-guide* is a complete book about -editions that enumerates the differences between editions and explains how to -automatically upgrade your code to a new edition via `cargo fix`. - diff --git a/rustbook-en/nostarch/book.toml b/rustbook-en/nostarch/book.toml deleted file mode 100644 index 55528625d..000000000 --- a/rustbook-en/nostarch/book.toml +++ /dev/null @@ -1,15 +0,0 @@ -[book] -title = "The Rust Programming Language" -authors = ["Steve Klabnik", "Carol Nichols", "Contributions from the Rust Community"] -src = "../src" # needs to be explicit (it is implicit in `/book.toml`). - -[output.html] -additional-css = ["../ferris.css", "../theme/2018-edition.css", "../theme/semantic-notes.css"] -additional-js = ["../ferris.js"] -git-repository-url = "https://github.com/rust-lang/book" - -[build] -build-dir = "../tmp" - -[preprocessor.trpl-listing] -output-mode = "simple" diff --git a/rustbook-en/nostarch/chapter02.md b/rustbook-en/nostarch/chapter02.md deleted file mode 100644 index b01770dc5..000000000 --- a/rustbook-en/nostarch/chapter02.md +++ /dev/null @@ -1,1006 +0,0 @@ - - -[TOC] - -# Programming a Guessing Game - -Let’s jump into Rust by working through a hands-on project together! This -chapter introduces you to a few common Rust concepts by showing you how to use -them in a real program. You’ll learn about `let`, `match`, methods, associated -functions, external crates, and more! In the following chapters, we’ll explore -these ideas in more detail. In this chapter, you’ll just practice the -fundamentals. - -We’ll implement a classic beginner programming problem: a guessing game. Here’s -how it works: the program will generate a random integer between 1 and 100. It -will then prompt the player to enter a guess. After a guess is entered, the -program will indicate whether the guess is too low or too high. If the guess is -correct, the game will print a congratulatory message and exit. - -## Setting Up a New Project - -To set up a new project, go to the *projects* directory that you created in -Chapter 1 and make a new project using Cargo, like so: - -``` -$ cargo new guessing_game -$ cd guessing_game -``` - -The first command, `cargo new`, takes the name of the project (`guessing_game`) -as the first argument. The second command changes to the new project’s -directory. - -Look at the generated *Cargo.toml* file: - -Filename: Cargo.toml - -``` -[package] -name = "guessing_game" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at -https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -``` - -As you saw in Chapter 1, `cargo new` generates a “Hello, world!” program for -you. Check out the *src/main.rs* file: - -Filename: src/main.rs - -``` -fn main() { - println!("Hello, world!"); -} -``` - -Now let’s compile this “Hello, world!” program and run it in the same step -using the `cargo run` command: - -``` -$ 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! -``` - -The `run` command comes in handy when you need to rapidly iterate on a project, -as we’ll do in this game, quickly testing each iteration before moving on to -the next one. - -Reopen the *src/main.rs* file. You’ll be writing all the code in this file. - -## Processing a Guess - -The first part of the guessing game program will ask for user input, process -that input, and check that the input is in the expected form. To start, we’ll -allow the player to input a guess. Enter the code in Listing 2-1 into -*src/main.rs*. - -Filename: src/main.rs - -``` -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}"); -} -``` - -Listing 2-1: Code that gets a guess from the user and prints it - -This code contains a lot of information, so let’s go over it line by line. To -obtain user input and then print the result as output, we need to bring the -`io` input/output library into scope. The `io` library comes from the standard -library, known as `std`: - -``` -use std::io; -``` - -By default, Rust has a set of items defined in the standard library that it -brings into the scope of every program. This set is called the *prelude*, and -you can see everything in it at -*https://doc.rust-lang.org/std/prelude/index.html*. - -If a type you want to use isn’t in the prelude, you have to bring that type -into scope explicitly with a `use` statement. Using the `std::io` library -provides you with a number of useful features, including the ability to accept -user input. - -As you saw in Chapter 1, the `main` function is the entry point into the -program: - -``` -fn main() { -``` - -The `fn` syntax declares a new function; the parentheses, `()`, indicate there -are no parameters; and the curly bracket, `{`, starts the body of the function. - -As you also learned in Chapter 1, `println!` is a macro that prints a string to -the screen: - -``` -println!("Guess the number!"); - -println!("Please input your guess."); -``` - -This code is printing a prompt stating what the game is and requesting input -from the user. - -### Storing Values with Variables - -Next, we’ll create a *variable* to store the user input, like this: - -``` -let mut guess = String::new(); -``` - -Now the program is getting interesting! There’s a lot going on in this little -line. We use the `let` statement to create the variable. Here’s another example: - -``` -let apples = 5; -``` - -This line creates a new variable named `apples` and binds it to the value 5. In -Rust, variables are immutable by default, meaning once we give the variable a -value, the value won’t change. We’ll be discussing this concept in detail in -“Variables and Mutability” on page XX. To make a variable mutable, we add `mut` -before the variable name: - -``` -let apples = 5; // immutable -let mut bananas = 5; // mutable -``` - -> Note: The `//` syntax starts a comment that continues until the end of the -line. Rust ignores everything in comments. We’ll discuss comments in more -detail in Chapter 3. - -Returning to the guessing game program, you now know that `let mut guess` will -introduce a mutable variable named `guess`. The equal sign (`=`) tells Rust we -want to bind something to the variable now. On the right of the equal sign is -the value that `guess` is bound to, which is the result of calling -`String::new`, a function that returns a new instance of a `String`. `String` -is a string type provided by the standard library that is a growable, UTF-8 -encoded bit of text. - -The `::` syntax in the `::new` line indicates that `new` is an associated -function of the `String` type. An *associated function* is a function that’s -implemented on a type, in this case `String`. This `new` function creates a -new, empty string. You’ll find a `new` function on many types because it’s a -common name for a function that makes a new value of some kind. - -In full, the `let mut guess = String::new();` line has created a mutable -variable that is currently bound to a new, empty instance of a `String`. Whew! - -### Receiving User Input - -Recall that we included the input/output functionality from the standard -library with `use std::io;` on the first line of the program. Now we’ll call -the `stdin` function from the `io` module, which will allow us to handle user -input: - -``` -io::stdin() - .read_line(&mut guess) -``` - -If we hadn’t imported the `io` library with `use std::io;` at the beginning of -the program, we could still use the function by writing this function call as -`std::io::stdin`. The `stdin` function returns an instance of `std::io::Stdin`, -which is a type that represents a handle to the standard input for your -terminal. - -Next, the line `.read_line(&mut guess)` calls the `read_line` method on the -standard input handle to get input from the user. We’re also passing `&mut -guess` as the argument to `read_line` to tell it what string to store the user -input in. The full job of `read_line` is to take whatever the user types into -standard input and append that into a string (without overwriting its -contents), so we therefore pass that string as an argument. The string argument -needs to be mutable so the method can change the string’s content. - -The `&` indicates that this argument is a *reference*, which gives you a way to -let multiple parts of your code access one piece of data without needing to -copy that data into memory multiple times. References are a complex feature, -and one of Rust’s major advantages is how safe and easy it is to use -references. You don’t need to know a lot of those details to finish this -program. For now, all you need to know is that, like variables, references are -immutable by default. Hence, you need to write `&mut guess` rather than -`&guess` to make it mutable. (Chapter 4 will explain references more -thoroughly.) - -### Handling Potential Failure with Result - -We’re still working on this line of code. We’re now discussing a third line of -text, but note that it’s still part of a single logical line of code. The next -part is this method: - -``` -.expect("Failed to read line"); -``` - -We could have written this code as: - -``` -io::stdin().read_line(&mut guess).expect("Failed to read line"); -``` - -However, one long line is difficult to read, so it’s best to divide it. It’s -often wise to introduce a newline and other whitespace to help break up long -lines when you call a method with the `.method_name()` syntax. Now let’s -discuss what this line does. - -As mentioned earlier, `read_line` puts whatever the user enters into the string -we pass to it, but it also returns a `Result` value. `Result` is an -*enumeration*, often called an *enum*, which is a type that can be in one of -multiple possible states. We call each possible state a *variant*. - -Chapter 6 will cover enums in more detail. The purpose of these `Result` types -is to encode error-handling information. - -`Result`’s variants are `Ok` and `Err`. The `Ok` variant indicates the -operation was successful, and inside `Ok` is the successfully generated value. -The `Err` variant means the operation failed, and `Err` contains information -about how or why the operation failed. - -Values of the `Result` type, like values of any type, have methods defined on -them. An instance of `Result` has an `expect` method that you can call. If this -instance of `Result` is an `Err` value, `expect` will cause the program to -crash and display the message that you passed as an argument to `expect`. If -the `read_line` method returns an `Err`, it would likely be the result of an -error coming from the underlying operating system. If this instance of `Result` -is an `Ok` value, `expect` will take the return value that `Ok` is holding and -return just that value to you so you can use it. In this case, that value is -the number of bytes in the user’s input. - -If you don’t call `expect`, the program will compile, but you’ll get a warning: - -``` -$ cargo build - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) -warning: unused `Result` that must be used - --> src/main.rs:10:5 - | -10 | io::stdin().read_line(&mut guess); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_must_use)]` on by default - = note: this `Result` may be an `Err` variant, which should be handled - -warning: `guessing_game` (bin "guessing_game") generated 1 warning - Finished dev [unoptimized + debuginfo] target(s) in 0.59s -``` - -Rust warns that you haven’t used the `Result` value returned from `read_line`, -indicating that the program hasn’t handled a possible error. - -The right way to suppress the warning is to actually write error-handling code, -but in our case we just want to crash this program when a problem occurs, so we -can use `expect`. You’ll learn about recovering from errors in Chapter 9. - -### Printing Values with println! Placeholders - -Aside from the closing curly bracket, there’s only one more line to discuss in -the code so far: - -``` -println!("You guessed: {guess}"); -``` - -This line prints the string that now contains the user’s input. The `{}` set of -curly brackets is a placeholder: think of `{}` as little crab pincers that hold -a value in place. When printing the value of a variable, the variable name can -go inside the curly brackets. When printing the result of evaluating an -expression, place empty curly brackets in the format string, then follow the -format string with a comma-separated list of expressions to print in each empty -curly bracket placeholder in the same order. Printing a variable and the result -of an expression in one call to `println!` would look like this: - -``` -let x = 5; -let y = 10; - -println!("x = {x} and y + 2 = {}", y + 2); -``` - -This code would print `x = 5 and y = 12`. - -### Testing the First Part - -Let’s test the first part of the guessing game. Run it using `cargo run`: - -``` -$ cargo run - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 6.44s - Running `target/debug/guessing_game` -Guess the number! -Please input your guess. -6 -You guessed: 6 -``` - -At this point, the first part of the game is done: we’re getting input from the -keyboard and then printing it. - -## Generating a Secret Number - -Next, we need to generate a secret number that the user will try to guess. The -secret number should be different every time so the game is fun to play more -than once. We’ll use a random number between 1 and 100 so the game isn’t too -difficult. Rust doesn’t yet include random number functionality in its standard -library. However, the Rust team does provide a `rand` crate at -*https://crates.io/crates/rand* with said functionality. - -### Using a Crate to Get More Functionality - -Remember that a crate is a collection of Rust source code files. The project -we’ve been building is a *binary crate*, which is an executable. The `rand` -crate is a *library crate*, which contains code that is intended to be used in -other programs and can’t be executed on its own. - -Cargo’s coordination of external crates is where Cargo really shines. Before we -can write code that uses `rand`, we need to modify the *Cargo.toml* file to -include the `rand` crate as a dependency. Open that file now and add the -following line to the bottom, beneath the `[dependencies]` section header that -Cargo created for you. Be sure to specify `rand` exactly as we have here, with -this version number, or the code examples in this tutorial may not work: - -Filename: Cargo.toml - -``` -[dependencies] -rand = "0.8.5" -``` - -In the *Cargo.toml* file, everything that follows a header is part of that -section that continues until another section starts. In `[dependencies]` you -tell Cargo which external crates your project depends on and which versions of -those crates you require. In this case, we specify the `rand` crate with the -semantic version specifier `0.8.5`. Cargo understands Semantic Versioning -(sometimes called *SemVer*), which is a standard for writing version numbers. -The specifier `0.8.5` is actually shorthand for `^0.8.5`, which means any -version that is at least 0.8.5 but below 0.9.0. - -Cargo considers these versions to have public APIs compatible with version -0.8.5, and this specification ensures you’ll get the latest patch release that -will still compile with the code in this chapter. Any version 0.9.0 or greater -is not guaranteed to have the same API as what the following examples use. - -Now, without changing any of the code, let’s build the project, as shown in -Listing 2-2. - -``` -$ cargo build - Updating crates.io index - Downloaded rand v0.8.5 - Downloaded libc v0.2.127 - Downloaded getrandom v0.2.7 - Downloaded cfg-if v1.0.0 - Downloaded ppv-lite86 v0.2.16 - Downloaded rand_chacha v0.3.1 - Downloaded rand_core v0.6.3 - Compiling rand_core v0.6.3 - Compiling libc v0.2.127 - Compiling getrandom v0.2.7 - Compiling cfg-if v1.0.0 - Compiling ppv-lite86 v0.2.16 - Compiling rand_chacha v0.3.1 - Compiling rand v0.8.5 - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53s -``` - -Listing 2-2: The output from running `cargo build` after adding the `rand` -crate as a dependency - -You may see different version numbers (but they will all be compatible with the -code, thanks to SemVer!) and different lines (depending on the operating -system), and the lines may be in a different order. - -When we include an external dependency, Cargo fetches the latest versions of -everything that dependency needs from the *registry*, which is a copy of data -from Crates.io at *https://crates.io*. Crates.io is where people in the Rust -ecosystem post their open source Rust projects for others to use. - -After updating the registry, Cargo checks the `[dependencies]` section and -downloads any crates listed that aren’t already downloaded. In this case, -although we only listed `rand` as a dependency, Cargo also grabbed other crates -that `rand` depends on 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 -downloaded and compiled the dependencies, and you haven’t changed anything -about them in your *Cargo.toml* file. Cargo also knows that you haven’t changed -anything about your code, so it doesn’t recompile that either. With nothing to -do, it simply exits. - -If you open the *src/main.rs* file, make a trivial change, and then save it and -build again, you’ll only see two lines of output: - -``` -$ cargo build - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs -``` - -These lines show that Cargo only updates the build with your tiny change to the -*src/main.rs* file. Your dependencies haven’t changed, so Cargo knows it can -reuse what it has already downloaded and compiled for those. - -#### Ensuring Reproducible Builds with the Cargo.lock File - -Cargo has a mechanism that ensures you can rebuild the same artifact every time -you or anyone else builds your code: Cargo will use only the versions of the -dependencies you specified until you indicate otherwise. For example, say that -next week version 0.8.6 of the `rand` crate comes out, and that version -contains an important bug fix, but it also contains a regression that will -break your code. To handle this, Rust creates the *Cargo.lock* file the first -time you run `cargo build`, so we now have this in the *guessing_game* -directory. - -When you build a project for the first time, Cargo figures out all the versions -of the dependencies that fit the criteria and then writes them to the -*Cargo.lock* file. When you build your project in the future, Cargo will see -that the *Cargo.lock* file exists and will use the versions specified there -rather than doing all the work of figuring out versions again. This lets you -have a reproducible build automatically. In other words, your project will -remain at 0.8.5 until you explicitly upgrade, thanks to the *Cargo.lock* file. -Because the *Cargo.lock* file is important for reproducible builds, it’s often -checked into source control with the rest of the code in your project. - -#### Updating a Crate to Get a New Version - -When you *do* want to update a crate, Cargo provides the command `update`, -which will ignore the *Cargo.lock* file and figure out all the latest versions -that fit your specifications in *Cargo.toml*. Cargo will then write those -versions to the *Cargo.lock* file. Otherwise, by default, Cargo will only look -for versions greater than 0.8.5 and less than 0.9.0. If the `rand` crate has -released the two new versions 0.8.6 and 0.9.0, you would see the following if -you ran `cargo update`: - -``` -$ cargo update - Updating crates.io index - Updating rand v0.8.5 -> v0.8.6 -``` - -Cargo ignores the 0.9.0 release. At this point, you would also notice a change -in your *Cargo.lock* file noting that the version of the `rand` crate you are -now using is 0.8.6. To use `rand` version 0.9.0 or any version in the 0.9.*x* -series, you’d have to update the *Cargo.toml* file to look like this instead: - -``` -[dependencies] -rand = "0.9.0" -``` - -The next time you run `cargo build`, Cargo will update the registry of crates -available and reevaluate your `rand` requirements according to the new version -you have specified. - -There’s a lot more to say about Cargo and its ecosystem, which we’ll discuss in -Chapter 14, but for now, that’s all you need to know. Cargo makes it very easy -to reuse libraries, so Rustaceans are able to write smaller projects that are -assembled from a number of packages. - -### Generating a Random Number - -Let’s start using `rand` to generate a number to guess. The next step is to -update *src/main.rs*, as shown in Listing 2-3. - -Filename: src/main.rs - -``` -use std::io; -1 use rand::Rng; - -fn main() { - println!("Guess the number!"); - - 2 let secret_number = rand::thread_rng().gen_range(1..=100); - - 3 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}"); -} -``` - -Listing 2-3: Adding code to generate a random number - -First we add the line `use rand::Rng;` [1]. The `Rng` trait defines methods -that random number generators implement, and this trait must be in scope for us -to use those methods. Chapter 10 will cover traits in detail. - -Next, we’re adding two lines in the middle. In the first line [2], we call the -`rand::thread_rng` function that gives us the particular random number -generator we’re going to use: one that is local to the current thread of -execution and is seeded by the operating system. Then we call the `gen_range` -method on the random number generator. This method is defined by the `Rng` -trait that we brought into scope with the `use rand::Rng;` statement. The -`gen_range` method takes a range expression as an argument and generates a -random number in the range. The kind of range expression we’re using here takes -the form `start..=end` and is inclusive on the lower and upper bounds, so we -need to specify `1..=100` to request a number between 1 and 100. - -> Note: You won’t just know which traits to use and which methods and functions -to call from a crate, so each crate has documentation with instructions for -using it. Another neat feature of Cargo is that running the `cargo doc --open` -command will build documentation provided by all your dependencies locally and -open it in your browser. If you’re interested in other functionality in the -`rand` crate, for example, run `cargo doc --open` and click `rand` in the -sidebar on the left. - -The second new line [3] prints the secret number. This is useful while we’re -developing the program to be able to test it, but we’ll delete it from the -final version. It’s not much of a game if the program prints the answer as soon -as it starts! - -Try running the program a few times: - -``` -$ cargo run - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - 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 -Please input your guess. -5 -You guessed: 5 -``` - -You should get different random numbers, and they should all be numbers between -1 and 100. Great job! - -## Comparing the Guess to the Secret Number - -Now that we have user input and a random number, we can compare them. That step -is shown in Listing 2-4. Note that this code won’t compile just yet, as we will -explain. - -Filename: src/main.rs - -``` -use rand::Rng; -1 use std::cmp::Ordering; -use std::io; - -fn main() { - --snip-- - - println!("You guessed: {guess}"); - - 2 match guess.3 cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => println!("You win!"), - } -} -``` - -Listing 2-4: Handling the possible return values of comparing two numbers - -First we add another `use` statement [1], bringing a type called -`std::cmp::Ordering` into scope from the standard library. The `Ordering` type -is another enum and has the variants `Less`, `Greater`, and `Equal`. These are -the three outcomes that are possible when you compare two values. - -Then we add five new lines at the bottom that use the `Ordering` type. The -`cmp` method [3] compares two values and can be called on anything that can be -compared. It takes a reference to whatever you want to compare with: here it’s -comparing `guess` to `secret_number`. Then it returns a variant of the -`Ordering` enum we brought into scope with the `use` statement. We use a -`match` expression [2] to decide what to do next based on which variant of -`Ordering` was returned from the call to `cmp` with the values in `guess` and -`secret_number`. - -A `match` expression is made up of *arms*. An arm consists of a *pattern* to -match against, and the code that should be run if the value given to `match` -fits that arm’s pattern. Rust takes the value given to `match` and looks -through each arm’s pattern in turn. Patterns and the `match` construct are -powerful Rust features: they let you express a variety of situations your code -might encounter and they make sure you handle them all. These features will be -covered in detail in Chapter 6 and Chapter 18, respectively. - -Let’s walk through an example with the `match` expression we use here. Say that -the user has guessed 50 and the randomly generated secret number this time is -38. - -When the code compares 50 to 38, the `cmp` method will return -`Ordering::Greater` because 50 is greater than 38. The `match` expression gets -the `Ordering::Greater` value and starts checking each arm’s pattern. It looks -at the first arm’s pattern, `Ordering::Less`, and sees that the value -`Ordering::Greater` does not match `Ordering::Less`, so it ignores the code in -that arm and moves to the next arm. The next arm’s pattern is -`Ordering::Greater`, which *does* match `Ordering::Greater`! The associated -code in that arm will execute and print `Too big!` to the screen. The `match` -expression ends after the first successful match, so it won’t look at the last -arm in this scenario. - -However, the code in Listing 2-4 won’t compile yet. Let’s try it: - -``` -$ cargo build - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) -error[E0308]: mismatched types - --> src/main.rs:22:21 - | -22 | match guess.cmp(&secret_number) { - | ^^^^^^^^^^^^^^ expected struct `String`, found integer - | - = note: expected reference `&String` - found reference `&{integer}` -``` - -The core of the error states that there are *mismatched types*. Rust has a -strong, static type system. However, it also has type inference. When we wrote -`let mut guess = String::new()`, Rust was able to infer that `guess` should be -a `String` and didn’t make us write the type. The `secret_number`, on the other -hand, is a number type. A few of Rust’s number types can have a value between 1 -and 100: `i32`, a 32-bit number; `u32`, an unsigned 32-bit number; `i64`, a -64-bit number; as well as others. Unless otherwise specified, Rust defaults to -an `i32`, which is the type of `secret_number` unless you add type information -elsewhere that would cause Rust to infer a different numerical type. The reason -for the error is that Rust cannot compare a string and a number type. - -Ultimately, we want to convert the `String` the program reads as input into a -real number type so we can compare it numerically to the secret number. We do -so by adding this line to the `main` function body: - -Filename: src/main.rs - -``` ---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!"), -} -``` - -We create a variable named `guess`. But wait, doesn’t the program already have -a variable named `guess`? It does, but helpfully Rust allows us to shadow the -previous value of `guess` with a new one. *Shadowing* lets us reuse the `guess` -variable name rather than forcing us to create two unique variables, such as -`guess_str` and `guess`, for example. We’ll cover this in more detail in -Chapter 3, but for now, know that this feature is often used when you want to -convert a value from one type to another type. - -We bind this new variable to the expression `guess.trim().parse()`. The `guess` -in the expression refers to the original `guess` variable that contained the -input as a string. The `trim` method on a `String` instance will eliminate any -whitespace at the beginning and end, which we must do to be able to compare the -string to the `u32`, which can only contain numerical data. The user must press -enter to satisfy `read_line` and input their guess, which adds a newline -character to the string. For example, if the user types `5` and presses enter, -`guess` looks like this: `5\n`. The `\n` represents “newline.” (On Windows, -pressing enter results in a carriage return and a newline, `\r\n`.) The `trim` -method eliminates `\n` or `\r\n`, resulting in just `5`. - -The `parse` method on strings converts a string to another type. Here, we use -it to convert from a string to a number. We need to tell Rust the exact number -type we want by using `let guess: u32`. The colon (`:`) after `guess` tells -Rust we’ll annotate the variable’s type. Rust has a few built-in number types; -the `u32` seen here is an unsigned, 32-bit integer. It’s a good default choice -for a small positive number. You’ll learn about other number types in Chapter 3. - -Additionally, the `u32` annotation in this example program and the comparison -with `secret_number` means Rust will infer that `secret_number` should be a -`u32` as well. So now the comparison will be between two values of the same -type! - -The `parse` method will only work on characters that can logically be converted -into numbers and so can easily cause errors. If, for example, the string -contained `A`👍`%`, there would be no way to convert that to a number. Because -it might fail, the `parse` method returns a `Result` type, much as the -`read_line` method does (discussed earlier in “Handling Potential Failure with -Result” on page XX). We’ll treat this `Result` the same way by using the -`expect` method again. If `parse` returns an `Err` `Result` variant because it -couldn’t create a number from the string, the `expect` call will crash the game -and print the message we give it. If `parse` can successfully convert the -string to a number, it will return the `Ok` variant of `Result`, and `expect` -will return the number that we want from the `Ok` value. - -Let’s run the program now: - -``` -$ cargo run - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 0.43s - Running `target/debug/guessing_game` -Guess the number! -The secret number is: 58 -Please input your guess. - 76 -You guessed: 76 -Too big! -``` - -Nice! Even though spaces were added before the guess, the program still figured -out that the user guessed 76. Run the program a few times to verify the -different behavior with different kinds of input: guess the number correctly, -guess a number that is too high, and guess a number that is too low. - -We have most of the game working now, but the user can make only one guess. -Let’s change that by adding a loop! - -## Allowing Multiple Guesses with Looping - -The `loop` keyword creates an infinite loop. We’ll add a loop to give users -more chances at guessing the number: - -Filename: src/main.rs - -``` ---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!"), - } -} -``` - -As you can see, we’ve moved everything from the guess input prompt onward into -a loop. Be sure to indent the lines inside the loop another four spaces each -and run the program again. The program will now ask for another guess forever, -which actually introduces a new problem. It doesn’t seem like the user can quit! - -The user could always interrupt the program by using the keyboard shortcut -ctrl-C. But there’s another way to escape this insatiable monster, as mentioned -in the `parse` discussion in “Comparing the Guess to the Secret Number” on page -XX: if the user enters a non-number answer, the program will crash. We can take -advantage of that to allow the user to quit, as shown here: - -``` -$ 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` -Guess the number! -The secret number is: 59 -Please input your guess. -45 -You guessed: 45 -Too small! -Please input your guess. -60 -You guessed: 60 -Too big! -Please input your guess. -59 -You guessed: 59 -You win! -Please input your guess. -quit -thread 'main' panicked at 'Please type a number!: ParseIntError -{ kind: InvalidDigit }', src/main.rs:28:47 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -``` - -Typing `quit` will quit the game, but as you’ll notice, so will entering any -other non-number input. This is suboptimal, to say the least; we want the game -to also stop when the correct number is guessed. - -### Quitting After a Correct Guess - -Let’s program the game to quit when the user wins by adding a `break` statement: - -Filename: src/main.rs - -``` ---snip-- - -match guess.cmp(&secret_number) { - Ordering::Less => println!("Too small!"), - Ordering::Greater => println!("Too big!"), - Ordering::Equal => { - println!("You win!"); - break; - } -} -``` - -Adding the `break` line after `You win!` makes the program exit the loop when -the user guesses the secret number correctly. Exiting the loop also means -exiting the program, because the loop is the last part of `main`. - -### Handling Invalid Input - -To further refine the game’s behavior, rather than crashing the program when -the user inputs a non-number, let’s make the game ignore a non-number so the -user can continue guessing. We can do that by altering the line where `guess` -is converted from a `String` to a `u32`, as shown in Listing 2-5. - -Filename: src/main.rs - -``` ---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-- -``` - -Listing 2-5: Ignoring a non-number guess and asking for another guess instead -of crashing the program - -We switch from an `expect` call to a `match` expression to move from crashing -on an error to handling the error. Remember that `parse` returns a `Result` -type and `Result` is an enum that has the variants `Ok` and `Err`. We’re using -a `match` expression here, as we did with the `Ordering` result of the `cmp` -method. - -If `parse` is able to successfully turn the string into a number, it will -return an `Ok` value that contains the resultant number. That `Ok` value will -match the first arm’s pattern, and the `match` expression will just return the -`num` value that `parse` produced and put inside the `Ok` value. That number -will end up right where we want it in the new `guess` variable we’re creating. - -If `parse` is *not* able to turn the string into a number, it will return an -`Err` value that contains more information about the error. The `Err` value -does not match the `Ok(num)` pattern in the first `match` arm, but it does -match the `Err(_)` pattern in the second arm. The underscore, `_`, is a -catchall value; in this example, we’re saying we want to match all `Err` -values, no matter what information they have inside them. So the program will -execute the second arm’s code, `continue`, which tells the program to go to the -next iteration of the `loop` and ask for another guess. So, effectively, the -program ignores all errors that `parse` might encounter! - -Now everything in the program should work as expected. Let’s try it: - -``` -$ cargo run - Compiling guessing_game v0.1.0 (file:///projects/guessing_game) - Finished dev [unoptimized + debuginfo] target(s) in 4.45s - Running `target/debug/guessing_game` -Guess the number! -The secret number is: 61 -Please input your guess. -10 -You guessed: 10 -Too small! -Please input your guess. -99 -You guessed: 99 -Too big! -Please input your guess. -foo -Please input your guess. -61 -You guessed: 61 -You win! -``` - -Awesome! With one tiny final tweak, we will finish the guessing game. Recall -that the program is still printing the secret number. That worked well for -testing, but it ruins the game. Let’s delete the `println!` that outputs the -secret number. Listing 2-6 shows the final code. - -Filename: src/main.rs - -``` -use rand::Rng; -use std::cmp::Ordering; -use std::io; - -fn main() { - println!("Guess the number!"); - - let secret_number = rand::thread_rng().gen_range(1..=100); - - 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; - } - } - } -} -``` - -Listing 2-6: Complete guessing game code - -At this point, you’ve successfully built the guessing game. Congratulations! - -## Summary - -This project was a hands-on way to introduce you to many new Rust concepts: -`let`, `match`, functions, the use of external crates, and more. In the next -few chapters, you’ll learn about these concepts in more detail. Chapter 3 -covers concepts that most programming languages have, such as variables, data -types, and functions, and shows how to use them in Rust. Chapter 4 explores -ownership, a feature that makes Rust different from other languages. Chapter 5 -discusses structs and method syntax, and Chapter 6 explains how enums work. - diff --git a/rustbook-en/nostarch/chapter04.md b/rustbook-en/nostarch/chapter04.md deleted file mode 100644 index 11f7f4944..000000000 --- a/rustbook-en/nostarch/chapter04.md +++ /dev/null @@ -1,1284 +0,0 @@ - - -[TOC] - -# Understanding Ownership - -Ownership is Rust’s most unique feature and has deep implications for the rest -of the language. It enables Rust to make memory safety guarantees without -needing a garbage collector, so it’s important to understand how ownership -works. In this chapter, we’ll talk about ownership as well as several related -features: borrowing, slices, and how Rust lays data out in memory. - -## What Is Ownership? - -*Ownership* is a set of rules that govern how a Rust program manages memory. -All programs have to manage the way they use a computer’s memory while running. -Some languages have garbage collection that regularly looks for no-longer-used -memory as the program runs; in other languages, the programmer must explicitly -allocate and free the memory. Rust uses a third approach: memory is managed -through a system of ownership with a set of rules that the compiler checks. If -any of the rules are violated, the program won’t compile. None of the features -of ownership will slow down your program while it’s running. - -Because ownership is a new concept for many programmers, it does take some time -to get used to. The good news is that the more experienced you become with Rust -and the rules of the ownership system, the easier you’ll find it to naturally -develop code that is safe and efficient. Keep at it! - -When you understand ownership, you’ll have a solid foundation for understanding -the features that make Rust unique. In this chapter, you’ll learn ownership by -working through some examples that focus on a very common data structure: -strings. - -> ### The Stack and the Heap -> -> Many programming languages don’t require you to think about the stack and the -heap very often. But in a systems programming language like Rust, whether a -value is on the stack or the heap affects how the language behaves and why you -have to make certain decisions. Parts of ownership will 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 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 the heap instead. -> -> The heap is less organized: when you put data on the heap, you request a -certain amount of space. The memory allocator finds an empty spot in the heap -that is big enough, marks it as being in use, and returns a *pointer*, which is -the address of that location. This process is called *allocating on the heap* -and is sometimes abbreviated as just *allocating* (pushing values onto the -stack is not considered allocating). Because the pointer to the heap is a -known, fixed size, you can store the pointer on the stack, but when you want -the actual data, you must follow the pointer. Think of being seated at a -restaurant. When you enter, you state the number of people in your group, and -the host finds an empty table that fits everyone and leads you there. If -someone in your group comes late, they can ask where you’ve been seated to find -you. -> -> Pushing to the stack is faster than allocating on the heap because the -allocator never has to search for a place to store new data; that location is -always at the top of the stack. Comparatively, allocating space on the heap -requires more work because the allocator must first find a big enough space to -hold the data and then perform bookkeeping to prepare for the next allocation. -> -> Accessing data in the heap is slower than accessing data on the stack because -you have to follow a pointer to get there. Contemporary processors are faster -if they jump around less in memory. Continuing the analogy, consider a server -at a restaurant taking orders from many tables. It’s most efficient to get all -the orders at one table before moving on to the next table. Taking an order -from table A, then an order from table B, then one from A again, and then one -from B again would be a much slower process. By the same token, a processor can -do its job better if it works on data that’s close to other data (as it is on -the stack) rather than farther away (as it can be on the heap). -> -> When your code calls a function, the values passed into the function -(including, potentially, pointers to data on the heap) and the function’s local -variables get pushed onto the stack. When the function is over, those values -get popped off the stack. -> -> Keeping track of what parts of code are using what data on the heap, -minimizing the amount of duplicate data on the heap, and cleaning up unused -data on the heap so you don’t run out of space are all problems that ownership -addresses. Once you understand ownership, you won’t need to think about the -stack and the heap very often, but knowing that the main purpose of ownership -is to manage heap data can help explain why it works the way it does. - -### Ownership Rules - -First, let’s take a look at the ownership rules. Keep these rules in mind as we -work through the examples that illustrate them: - -* Each value in Rust has an *owner*. -* There can only be one owner at a time. -* When the owner goes out of scope, the value will be dropped. - -### Variable Scope - -Now that we’re past basic Rust syntax, we won’t include all the `fn main() {` -code in examples, so if you’re following along, make sure to put the following -examples inside a `main` function manually. As a result, our examples will be a -bit more concise, letting us focus on the actual details rather than -boilerplate code. - -As a first example of ownership, we’ll look at the *scope* of some variables. A -scope is the range within a program for which an item is valid. Take the -following variable: - -``` -let s = "hello"; -``` - -The variable `s` refers to a string literal, where the value of the string is -hardcoded into the text of our program. The variable is valid from the point at -which it’s declared until the end of the current *scope*. Listing 4-1 shows a -program with comments annotating where the variable `s` would be valid. - -``` -{ // s is not valid here, since 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 -``` - -Listing 4-1: A variable and the scope in which it is valid - -In other words, there are two important points in time here: - -* When `s` comes *into* scope, it is valid. -* It remains valid until it goes *out of* scope. - -At this point, the relationship between scopes and when variables are valid is -similar to that in other programming languages. Now we’ll build on top of this -understanding by introducing the `String` type. - -### The String Type - -To illustrate the rules of ownership, we need a data type that is more complex -than those we covered in “Data Types” on page XX. The types covered previously -are of a known size, can be stored on the stack and popped off the stack when -their scope is over, and can be quickly and trivially copied to make a new, -independent instance if another part of code needs to use the same value in a -different scope. But we want to look at data that is stored on the heap and -explore how Rust knows when to clean up that data, and the `String` type is a -great example. - -We’ll 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 discuss `String` in more depth in -Chapter 8. - -We’ve already seen string literals, where a string value is hardcoded into our -program. String literals are convenient, but they aren’t suitable for every -situation in which we may want to use text. One reason is that they’re -immutable. Another is that not every string value can be known when we write -our code: for example, what if we want to take user input and store it? For -these situations, Rust has a second string type, `String`. This type manages -data allocated on the heap and as such is able to store an amount of text that -is unknown to us at compile time. You can create a `String` from a string -literal using the `from` function, like so: - -``` -let s = String::from("hello"); -``` - -The double colon `::` operator allows us to namespace this particular `from` -function under the `String` type rather than using some sort of name like -`string_from`. We’ll discuss this syntax more in “Method Syntax” on page XX, -and when we talk about namespacing with modules in “Paths for Referring to an -Item in the Module Tree” on page XX. - -This kind of string *can* be mutated: - -``` -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!` -``` - -So, what’s the difference here? Why can `String` be mutated but literals -cannot? The difference is in how these two types deal with memory. - -### Memory and Allocation - -In the case of a string literal, we know the contents at compile time, so the -text is hardcoded directly into the final executable. This is why string -literals are fast and efficient. But these properties only come from the string -literal’s immutability. Unfortunately, we can’t put a blob of memory into the -binary for each piece of text whose size is unknown at compile time and whose -size might change while running the program. - -With the `String` type, in order to support a mutable, growable piece of text, -we need to allocate an amount of memory on the heap, unknown at compile time, -to hold the contents. This means: - -* The memory must be requested from the memory allocator at runtime. -* We need a way of returning this memory to the allocator when we’re done with -our `String`. - -That first part is done by us: when we call `String::from`, its implementation -requests the memory it needs. This is pretty much universal in programming -languages. - -However, the second part is different. In languages with a *garbage collector -(GC)*, the GC keeps track of and cleans up memory that isn’t being used -anymore, and we don’t need to think about it. In most languages without a GC, -it’s our responsibility to identify when memory is no longer being used and to -call code to explicitly free it, just as we did to request it. Doing this -correctly has historically been a difficult programming problem. If we forget, -we’ll waste memory. If we do it too early, we’ll have an invalid variable. If -we do it twice, that’s a bug too. We need to pair exactly one `allocate` with -exactly one `free`. - -Rust takes a different path: the memory is automatically returned once the -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: - -``` -{ - 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 -``` - -There is a natural point at which we can return the memory our `String` needs -to the allocator: when `s` goes out of scope. When a variable goes out of -scope, Rust calls a special function for us. This function is called `drop`, -and it’s where the author of `String` can put the code to return the memory. -Rust calls `drop` automatically at the closing curly bracket. - -> Note: In C++, this pattern of deallocating resources at the end of an item’s -lifetime is sometimes called *Resource Acquisition Is Initialization* *(RAII)*. -The `drop` function in Rust will be familiar to you if you’ve used RAII -patterns. - -This pattern has a profound impact on the way Rust code is written. It may seem -simple right now, but the behavior of code can be unexpected in more -complicated situations when we want to have multiple variables use the data -we’ve allocated on the heap. Let’s explore some of those situations now. - -#### Variables and Data Interacting with Move - -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. - -``` -let x = 5; -let y = x; -``` - -Listing 4-2: Assigning the integer value of variable `x` to `y` - -We can probably guess what this is doing: “bind the value `5` to `x`; then make -a copy of the value in `x` and bind it to `y`.” We now have two variables, `x` -and `y`, and both equal `5`. This is indeed what is happening, because integers -are simple values with a known, fixed size, and these two `5` values are pushed -onto the stack. - -Now let’s look at the `String` version: - -``` -let s1 = String::from("hello"); -let s2 = s1; -``` - -This looks very similar, so we might assume that the way it works would be the -same: that is, the second line would make a copy of the value in `s1` and bind -it to `s2`. But this isn’t quite what happens. - -Take a look at Figure 4-1 to see what is happening to `String` under the -covers. A `String` is made up of three parts, shown on the left: a pointer to -the memory that holds the contents of the string, a length, and a capacity. -This group of data is stored on the stack. On the right is the memory on the -heap that holds the contents. - -Figure 4-1: Representation in memory of a `String` holding the value `"hello"` -bound to `s1` - -The length is how much memory, in bytes, the contents of the `String` are -currently using. The capacity is the total amount of memory, in bytes, that the -`String` has received from the allocator. The difference between length and -capacity matters, but not in this context, so for now, it’s fine to ignore the -capacity. - -When we assign `s1` to `s2`, the `String` data is copied, meaning we copy the -pointer, the length, and the capacity that are on the stack. We do not copy the -data on the heap that the pointer refers to. In other words, the data -representation in memory looks like Figure 4-2. - -Figure 4-2: Representation in memory of the variable `s2` that has a copy of -the pointer, length, and capacity of `s1` - -The representation does *not* look like Figure 4-3, which is what memory would -look like if Rust instead copied the heap data as well. If Rust did this, the -operation `s2 = s1` could be very expensive in terms of runtime performance if -the data on the heap were large. - -Figure 4-3: Another possibility for what `s2 = s1` might do if Rust copied the -heap data as well - -Earlier, we said that when a variable goes out of scope, Rust automatically -calls the `drop` function and cleans up the heap memory for that variable. But -Figure 4-2 shows both data pointers pointing to the same location. This is a -problem: when `s2` and `s1` go out of scope, they will both try to free the -same memory. This is known as a *double free* error and is one of the memory -safety bugs we mentioned previously. Freeing memory twice can lead to memory -corruption, which can potentially lead to security vulnerabilities. - -To ensure memory safety, after the line `let s2 = s1;`, Rust considers `s1` as -no longer valid. Therefore, Rust doesn’t need to free 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: - -``` -let s1 = String::from("hello"); -let s2 = s1; - -println!("{s1}, world!"); -``` - -You’ll get an error like this because Rust prevents you from using the -invalidated reference: - -``` -error[E0382]: borrow of moved value: `s1` - --> src/main.rs:5:28 - | -2 | let s1 = String::from("hello"); - | -- move occurs because `s1` has type `String`, which - does not implement the `Copy` trait -3 | let s2 = s1; - | -- value moved here -4 | -5 | println!("{s1}, world!"); - | ^^ value borrowed here after move -``` - -If you’ve heard the terms *shallow copy* and *deep copy* while working with -other languages, the concept of copying the pointer, length, and capacity -without copying the data probably sounds like making a shallow copy. But -because Rust also invalidates the first variable, instead of being called a -shallow copy, it’s known as a *move*. In this example, we would say that `s1` -was *moved* into `s2`. So, what actually happens is shown in Figure 4-4. - -Figure 4-4: Representation in memory after `s1` has been invalidated - -That solves our problem! With only `s2` valid, when it goes out of scope it -alone will free the memory, and we’re done. - -In addition, there’s a design choice that’s implied by this: Rust will never -automatically create “deep” copies of your data. Therefore, any *automatic* -copying can be assumed to be inexpensive in terms of runtime performance. - -#### Variables and Data Interacting with Clone - -If we *do* want to deeply copy the heap data of the `String`, not just the -stack data, we can use a common method called `clone`. We’ll discuss method -syntax in Chapter 5, but because methods are a common feature in many -programming languages, you’ve probably seen them before. - -Here’s an example of the `clone` method in action: - -``` -let s1 = String::from("hello"); -let s2 = s1.clone(); - -println!("s1 = {s1}, s2 = {s2}"); -``` - -This works just fine and explicitly produces the behavior shown in Figure 4-3, -where the heap data *does* get copied. - -When you see a call to `clone`, you know that some arbitrary code is being -executed and that code may be expensive. It’s a visual indicator that something -different is going on. - -#### Stack-Only Data: Copy - -There’s another wrinkle we haven’t talked about yet. This code using -integers—part of which was shown in Listing 4-2—works and is valid: - -``` -let x = 5; -let y = x; - -println!("x = {x}, y = {y}"); -``` - -But this code seems to contradict what we just learned: we don’t have a call to -`clone`, but `x` is still valid and wasn’t moved into `y`. - -The reason is that types such as integers that have a known size at compile -time are stored entirely on the stack, so copies of the actual values are quick -to make. That means there’s no reason we would want to prevent `x` from being -valid after we create the variable `y`. In other words, there’s no difference -between deep and shallow copying here, so calling `clone` wouldn’t do anything -different from the usual shallow copying, and we can leave it out. - -Rust has a special annotation called the `Copy` trait that we can place on -types that are stored on the stack, as integers are (we’ll talk more about -traits in Chapter 10). If a type implements the `Copy` trait, variables that -use it do not move, but rather are trivially copied, making them still valid -after assignment to another variable. - -Rust won’t let us annotate a type with `Copy` if the type, or any of its parts, -has implemented the `Drop` trait. If the type needs something special to happen -when the value goes out of scope and we add the `Copy` annotation to that type, -we’ll get a compile-time error. To learn about how to add the `Copy` annotation -to your type to implement the trait, see “Derivable Traits” on page XX. - -So, what types implement the `Copy` trait? You can check the documentation for -the given type to be sure, but as a general rule, any group of simple scalar -values can implement `Copy`, and nothing that requires allocation or is some -form of resource can implement `Copy`. Here are some of the types that -implement `Copy`: - -* All the integer types, such as `u32`. -* The Boolean type, `bool`, with values `true` and `false`. -* All the floating-point types, such as `f64`. -* The character type, `char`. -* Tuples, if they only contain types that also implement `Copy`. For example, -`(i32, i32)` implements `Copy`, but `(i32, String)` does not. - -### Ownership and Functions - -The mechanics of passing a value to a function are similar to those when -assigning a value to a variable. Passing a variable to a function will move or -copy, just as assignment does. Listing 4-3 has an example with some annotations -showing where variables go into and out of scope. - -``` -// src/main.rs -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. However, 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 -``` - -Listing 4-3: Functions with ownership and scope annotated - -If we tried to use `s` after the call to `takes_ownership`, Rust would throw a -compile-time error. These static checks protect us from mistakes. Try adding -code to `main` that uses `s` and `x` to see where you can use them and where -the ownership rules prevent you from doing so. - -### Return Values and Scope - -Returning values can also transfer ownership. Listing 4-4 shows an example of a -function that returns some value, with similar annotations as those in Listing -4-3. - -``` -// src/main.rs -fn main() { - let s1 = gives_ownership(); // gives_ownership moves its return - // value into s1 - - let s2 = String::from("hello"); // s2 comes into scope - - let s3 = takes_and_gives_back(s2); // s2 is moved into - // takes_and_gives_back, which also - // moves its return value into s3 -} // Here, s3 goes out of scope and is dropped. s2 was moved, so nothing - // happens. s1 goes out of scope and is dropped - -fn gives_ownership() -> String { // gives_ownership will move its - // return value into the function - // that calls it - - let some_string = String::from("yours"); // some_string comes into scope - - some_string // some_string is returned and - // moves out to the calling - // function -} - -// This function takes a String and returns a String -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 -} -``` - -Listing 4-4: Transferring ownership of return values - -The ownership of a variable follows the same pattern every time: assigning a -value to another variable moves it. When a variable that includes data on the -heap goes out of scope, the value will be cleaned up by `drop` unless ownership -of the data has been moved to another variable. - -While this works, taking ownership and then returning ownership with every -function is a bit tedious. What if we want to let a function use a value but -not take ownership? It’s quite annoying that anything we pass in also needs to -be passed back if we want to use it again, in addition to any data resulting -from the body of the function that we might want to return as well. - -Rust does let us return multiple values using a tuple, as shown in Listing 4-5. - -Filename: src/main.rs - -``` -fn main() { - let s1 = String::from("hello"); - - let (s2, len) = calculate_length(s1); - - println!("The length of '{s2}' is {len}."); -} - -fn calculate_length(s: String) -> (String, usize) { - let length = s.len(); // len() returns the length of a String - - (s, length) -} -``` - -Listing 4-5: Returning ownership of parameters - -But this is too much ceremony and a lot of work for a concept that should be -common. Luckily for us, Rust has a feature for using a value without -transferring ownership, called *references*. - -## References and Borrowing - -The issue with the tuple code in Listing 4-5 is that we have to return the -`String` to the calling function so we can still use the `String` after the -call to `calculate_length`, because the `String` was moved into -`calculate_length`. Instead, we can provide a reference to the `String` value. -A *reference* is like a pointer in that it’s an address we can follow to access -the data stored at that address; that data is owned by some other variable. -Unlike a pointer, a reference is guaranteed to point to a valid value of a -particular type for the life of that reference. - -Here is how you would define and use a `calculate_length` function that has a -reference to an object as a parameter instead of taking ownership of the value: - -Filename: src/main.rs - -``` -fn main() { - let s1 = String::from("hello"); - - let len = calculate_length(&s1); - - println!("The length of '{s1}' is {len}."); -} - -fn calculate_length(s: &String) -> usize { - s.len() -} -``` - -First, notice that all the tuple code in the variable declaration and the -function return value is gone. Second, note that we pass `&s1` into -`calculate_length` and, in its definition, we take `&String` rather than -`String`. These ampersands represent *references*, and they allow you to refer -to some value without taking ownership of it. Figure 4-5 depicts this concept. - -Figure 4-5: A diagram of `&String s` pointing at `String s1` - -> Note: The opposite of referencing by using `&` is *dereferencing*, which is -accomplished with the dereference operator, `*`. We’ll see some uses of the -dereference operator in Chapter 8 and discuss details of dereferencing in -Chapter 15. - -Let’s take a closer look at the function call here: - -``` -let s1 = String::from("hello"); - -let len = calculate_length(&s1); -``` - -The `&s1` syntax lets us create a reference that *refers* to the value of `s1` -but does not own it. Because it does not own it, the value it points to will -not be dropped when the reference stops being used. - -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: - -``` -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, the String is not dropped -``` - -The scope in which the variable `s` is valid is the same as any function -parameter’s scope, but the value pointed to by the reference is not dropped -when `s` stops being used, because `s` doesn’t have ownership. When functions -have references as parameters instead of the actual values, we won’t need to -return the values in order to give back ownership, because we never had -ownership. - -We call the action of creating a reference *borrowing*. As in real life, if a -person owns something, you can borrow it from them. When you’re done, you have -to give it back. You don’t own it. - -So, what happens if we try to modify something we’re borrowing? Try the code in -Listing 4-6. Spoiler alert: it doesn’t work! - -Filename: src/main.rs - -``` -fn main() { - let s = String::from("hello"); - - change(&s); -} - -fn change(some_string: &String) { - some_string.push_str(", world"); -} -``` - -Listing 4-6: Attempting to modify a borrowed value - -Here’s the error: - -``` -error[E0596]: cannot borrow `*some_string` as mutable, as it is behind a `&` -reference - --> src/main.rs:8:5 - | -7 | fn change(some_string: &String) { - | ------- help: consider changing this to be a mutable -reference: `&mut String` -8 | some_string.push_str(", world"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `some_string` is a `&` reference, so -the data it refers to cannot be borrowed as mutable -``` - -Just as variables are immutable by default, so are references. We’re not -allowed to modify something we have a reference to. - -### Mutable References - -We can fix the code from Listing 4-6 to allow us to modify a borrowed value -with just a few small tweaks that use, instead, a *mutable reference*: - -Filename: src/main.rs - -``` -fn main() { - let mut s = String::from("hello"); - - change(&mut s); -} - -fn change(some_string: &mut String) { - some_string.push_str(", world"); -} -``` - -First we change `s` to be `mut`. Then we create a mutable reference with `&mut -s` where we call the `change` function, and update the function signature to -accept a mutable reference with `some_string: &mut String`. This makes it very -clear that the `change` function will mutate the value it borrows. - -Mutable references have one big restriction: if you have a mutable reference to -a value, you can have no other references to that value. This code that -attempts to create two mutable references to `s` will fail: - -Filename: src/main.rs - -``` -let mut s = String::from("hello"); - -let r1 = &mut s; -let r2 = &mut s; - -println!("{r1}, {r2}"); -``` - -Here’s the error: - -``` -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 -``` - -This error says that this code is invalid because we cannot borrow `s` as -mutable more than once at a time. The first mutable borrow is in `r1` and must -last until it’s used in the `println!`, but between the creation of that -mutable reference and its usage, we tried to create another mutable reference -in `r2` that borrows the same data as `r1`. - -The restriction preventing multiple mutable references to the same data at the -same time allows for mutation but in a very controlled fashion. It’s something -that new Rustaceans struggle with because most languages let you mutate -whenever you’d like. The benefit of having this restriction is that Rust can -prevent data races at compile time. A *data race* is similar to a race -condition and happens when these three behaviors occur: - -* Two or more pointers access the same data at the same time. -* At least one of the pointers is being used to write to the data. -* There’s no mechanism being used to synchronize access to the data. - -Data races cause undefined behavior and can be difficult to diagnose and fix -when you’re trying to track them down at runtime; Rust prevents this problem by -refusing to compile code with data races! - -As always, we can use curly brackets to create a new scope, allowing for -multiple mutable references, just not *simultaneous* ones: - -``` -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; -``` - -Rust enforces a similar rule for combining mutable and immutable references. -This code results in an error: - -``` -let mut s = String::from("hello"); - -let r1 = &s; // no problem -let r2 = &s; // no problem -let r3 = &mut s; // BIG PROBLEM - -println!("{r1}, {r2}, and {r3}"); -``` - -Here’s the error: - -``` -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!("{r1}, {r2}, and {r3}"); - | -- immutable borrow later used here -``` - -Whew! We *also* cannot have a mutable reference while we have an immutable one -to the same value. - -Users of an immutable reference don’t expect the value to suddenly change out -from under them! However, multiple immutable references are allowed because no -one who is just reading the data has the ability to affect anyone else’s -reading of the data. - -Note that a reference’s scope starts from where it is introduced and continues -through the last time that reference is used. For instance, this code will -compile because the last usage of the immutable references, the `println!`, -occurs before the mutable reference is introduced: - -``` -let mut s = String::from("hello"); - -let r1 = &s; // no problem -let r2 = &s; // no problem -println!("{r1} and {r2}"); -// variables r1 and r2 will not be used after this point - -let r3 = &mut s; // no problem -println!("{r3}"); -``` - -The scopes of the immutable references `r1` and `r2` end after the `println!` -where they are last used, which is before the mutable reference `r3` is -created. These scopes don’t overlap, so this code is allowed: the compiler can -tell that the reference is no longer being used at a point before the end of -the scope. - -Even though borrowing errors may be frustrating at times, remember that it’s -the Rust compiler pointing out a potential bug early (at compile time rather -than at runtime) and showing you exactly where the problem is. Then you don’t -have to track down why your data isn’t what you thought it was. - -### Dangling References - -In languages with pointers, it’s easy to erroneously create a *dangling -pointer*—a pointer that references a location in memory that may have been -given to someone else—by freeing some memory while preserving a pointer to that -memory. In Rust, by contrast, the compiler guarantees that references will -never be dangling references: if you have a reference to some data, the -compiler will ensure that the data will not go out of scope before the -reference to the data does. - -Let’s try to create a dangling reference to see how Rust prevents them with a -compile-time error: - -Filename: src/main.rs - -``` -fn main() { - let reference_to_nothing = dangle(); -} - -fn dangle() -> &String { - let s = String::from("hello"); - - &s -} -``` - -Here’s the error: - -``` -error[E0106]: missing lifetime specifier - --> src/main.rs:5:16 - | -5 | fn dangle() -> &String { - | ^ expected named lifetime parameter - | - = help: this function's return type contains a borrowed value, -but there is no value for it to be borrowed from -help: consider using the `'static` lifetime - | -5 | fn dangle() -> &'static String { - | ~~~~~~~~ -``` - -This error message refers to a feature we haven’t covered yet: lifetimes. We’ll -discuss lifetimes in detail in Chapter 10. But, if you disregard the parts -about lifetimes, the message does contain the key to why this code is a problem: - -``` -this function's return type contains a borrowed value, but there -is no value for it to be borrowed from -``` - -Let’s take a closer look at exactly what’s happening at each stage of our -`dangle` code: - -``` -// src/main.rs -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, so its memory goes away - // Danger! -``` - -Because `s` is created inside `dangle`, when the code of `dangle` is finished, -`s` will be deallocated. But we tried to return a reference to it. That means -this reference would be pointing to an invalid `String`. That’s no good! Rust -won’t let us do this. - -The solution here is to return the `String` directly: - -``` -fn no_dangle() -> String { - let s = String::from("hello"); - - s -} -``` - -This works without any problems. Ownership is moved out, and nothing is -deallocated. - -### The Rules of References - -Let’s recap what we’ve discussed about references: - -* At any given time, you can have *either* one mutable reference *or* any -number of immutable references. -* References must always be valid. - -Next, we’ll look at a different kind of reference: slices. - -## The Slice Type - -*Slices* let you reference a contiguous sequence of elements in a collection -rather than the whole collection. A slice is a kind of reference, so it does -not have ownership. - -Here’s a small programming problem: write a function that takes a string of -words separated by spaces and returns the first word it finds in that string. -If the function doesn’t find a space in the string, the whole string must be -one word, so the entire string should be returned. - -Let’s work through how we’d write the signature of this function without using -slices, to understand the problem that slices will solve: - -``` -fn first_word(s: &String) -> ? -``` - -The `first_word` function has a `&String` as a parameter. We don’t want -ownership, so this is fine. But what should we return? We don’t really have a -way to talk about *part* of a string. However, we could return the index of the -end of the word, indicated by a space. Let’s try that, as shown in Listing 4-7. - -Filename: src/main.rs - -``` -fn first_word(s: &String) -> usize { - 1 let bytes = s.as_bytes(); - - for (2 i, &item) in 3 bytes.iter().enumerate() { - 4 if item == b' ' { - return i; - } - } - - 5 s.len() -} -``` - -Listing 4-7: The `first_word` function that returns a byte index value into the -`String` parameter - -Because we need to go through the `String` element by element and check whether -a value is a space, we’ll convert our `String` to an array of bytes using the -`as_bytes` method [1]. - -Next, we create an iterator over the array of bytes using the `iter` method -[3]. We’ll discuss iterators in more detail in Chapter 13. For now, know that -`iter` is a method that returns each element in a collection and that -`enumerate` wraps the result of `iter` and returns each element as part of a -tuple instead. The first element of the tuple returned from `enumerate` is the -index, and the second element is a reference to the element. This is a bit more -convenient than calculating the index ourselves. - -Because the `enumerate` method returns a tuple, we can use patterns to -destructure that tuple. We’ll be discussing patterns more in Chapter 6. In the -`for` loop, we specify a pattern that has `i` for the index in the tuple and -`&item` for the single byte in the tuple [2]. Because we get a reference to the -element from `.iter().enumerate()`, we use `&` in the pattern. - -Inside the `for` loop, we search for the byte that represents the space by -using the byte literal syntax [4]. If we find a space, we return the position. -Otherwise, we return the length of the string by using `s.len()` [5]. - -We now have a way to find out the index of the end of the first word in the -string, but there’s a problem. We’re returning a `usize` on its own, but it’s -only a meaningful number in the context of the `&String`. In other words, -because it’s a separate value from the `String`, there’s no guarantee that it -will still be valid in the future. Consider the program in Listing 4-8 that -uses the `first_word` function from Listing 4-7. - -``` -// src/main.rs -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! -} -``` - -Listing 4-8: Storing the result from calling the `first_word` function and then -changing the `String` contents - -This program compiles without any errors and would also do so if we used `word` -after calling `s.clear()`. Because `word` isn’t connected to the state of `s` -at all, `word` still contains the value `5`. We could use that value `5` with -the variable `s` to try to extract the first word out, but this would be a bug -because the contents of `s` have changed since we saved `5` in `word`. - -Having to worry about the index in `word` getting out of sync with the data in -`s` is tedious and error prone! Managing these indices is even more brittle if -we write a `second_word` function. Its signature would have to look like this: - -``` -fn second_word(s: &String) -> (usize, usize) { -``` - -Now we’re tracking a starting *and* an ending index, and we have even more -values that were calculated from data in a particular state but aren’t tied to -that state at all. We have three unrelated variables floating around that need -to be kept in sync. - -Luckily, Rust has a solution to this problem: string slices. - -### String Slices - -A *string slice* is a reference to part of a `String`, and it looks like this: - -``` -let s = String::from("hello world"); - -let hello = &s[0..5]; -let world = &s[6..11]; -``` - -Rather than a reference to the entire `String`, `hello` is a reference to a -portion of the `String`, specified in the extra `[0..5]` bit. We create slices -using a range within brackets by specifying `[starting_index..ending_index]`, -where `starting_index` is the first position in the slice and `ending_index` is -one more than the last position in the slice. Internally, the slice data -structure stores the starting position and the length of the slice, which -corresponds to `ending_index` minus `starting_index`. So, in the case of `let -world = &s[6..11];`, `world` would be a slice that contains a pointer to the -byte at index 6 of `s` with a length value of `5`. - -Figure 4-6 shows this in a diagram. - -Figure 4-6: String slice referring to part of a `String` - -With Rust’s `..` range syntax, if you want to start at index 0, you can drop -the value before the two periods. In other words, these are equal: - -``` -let s = String::from("hello"); - -let slice = &s[0..2]; -let slice = &s[..2]; -``` - -By the same token, if your slice includes the last byte of the `String`, you -can drop the trailing number. That means these are equal: - -``` -let s = String::from("hello"); - -let len = s.len(); - -let slice = &s[3..len]; -let slice = &s[3..]; -``` - -You can also drop both values to take a slice of the entire string. So these -are equal: - -``` -let s = String::from("hello"); - -let len = s.len(); - -let slice = &s[0..len]; -let slice = &s[..]; -``` - -> Note: String slice range indices must occur at valid UTF-8 character -boundaries. If you attempt to create a string slice in the middle of a -multibyte character, your program will exit with an error. For the purposes of -introducing string slices, we are assuming ASCII only in this section; a more -thorough discussion of UTF-8 handling is in “Storing UTF-8 Encoded Text with -Strings” on page XX. - -With all this information in mind, let’s rewrite `first_word` to return a -slice. The type that signifies “string slice” is written as `&str`: - -Filename: src/main.rs - -``` -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[..] -} -``` - -We get the index for the end of the word the same way we did in Listing 4-7, by -looking for the first occurrence of a space. When we find a space, we return a -string slice using the start of the string and the index of the space as the -starting and ending indices. - -Now when we call `first_word`, we get back a single value that is tied to the -underlying data. The value is made up of a reference to the starting point of -the slice and the number of elements in the slice. - -Returning a slice would also work for a `second_word` function: - -``` -fn second_word(s: &String) -> &str { -``` - -We now have a straightforward API that’s much harder to mess up because the -compiler will ensure the references into the `String` remain valid. Remember -the bug in the program in Listing 4-8, when we got the index to the end of the -first word but then cleared the string so our index was invalid? That code was -logically incorrect but didn’t show any immediate errors. The problems would -show up later if we kept trying to use the first word index with an emptied -string. Slices make this bug impossible and let us know we have a problem with -our code much sooner. Using the slice version of `first_word` will throw a -compile-time error: - -Filename: src/main.rs - -``` -fn main() { - let mut s = String::from("hello world"); - - let word = first_word(&s); - - s.clear(); // error! - - println!("the first word is: {word}"); -} -``` - -Here’s the compiler error: - -``` -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 -``` - -Recall from the borrowing rules that if we have an immutable reference to -something, we cannot also take a mutable reference. Because `clear` needs to -truncate the `String`, it needs to get a mutable reference. The `println!` -after the call to `clear` uses the reference in `word`, so the immutable -reference must still be active at that point. Rust disallows the mutable -reference in `clear` and the immutable reference in `word` from existing at the -same time, and compilation fails. Not only has Rust made our API easier to use, -but it has also eliminated an entire class of errors at compile time! - -#### String Literals as Slices - -Recall that we talked about string literals being stored inside the binary. Now -that we know about slices, we can properly understand string literals: - -``` -let s = "Hello, world!"; -``` - -The type of `s` here is `&str`: it’s a slice pointing to that specific point of -the binary. This is also why string literals are immutable; `&str` is an -immutable reference. - -#### String Slices as Parameters - -Knowing that you can take slices of literals and `String` values leads us to -one more improvement on `first_word`, and that’s its signature: - -``` -fn first_word(s: &String) -> &str { -``` - -A more experienced Rustacean would write the signature shown in Listing 4-9 -instead because it allows us to use the same function on both `&String` values -and `&str` values. - -``` -fn first_word(s: &str) -> &str { -``` - -Listing 4-9: Improving the `first_word` function by using a string slice for -the type of the `s` parameter - -If we have a string slice, we can pass that directly. If we have a `String`, we -can pass a slice of the `String` or a reference to the `String`. This -flexibility takes advantage of *deref coercions*, a feature we will cover in -“Implicit Deref Coercions with Functions and Methods” on page XX. - -Defining a function to take a string slice instead of a reference to a `String` -makes our API more general and useful without losing any functionality: - -Filename: src/main.rs - -``` -fn main() { - let my_string = String::from("hello world"); - - // `first_word` works on slices of `String`s, whether partial - // or whole - let word = first_word(&my_string[0..6]); - let word = first_word(&my_string[..]); - // `first_word` also works on references to `String`s, which - // are equivalent to whole slices of `String`s - let word = first_word(&my_string); - - let my_string_literal = "hello world"; - - // `first_word` works on slices of string literals, - // whether partial or whole - let word = first_word(&my_string_literal[0..6]); - let word = first_word(&my_string_literal[..]); - - // Because string literals *are* string slices already, - // this works too, without the slice syntax! - let word = first_word(my_string_literal); -} -``` - -### Other Slices - -String slices, as you might imagine, are specific to strings. But there’s a -more general slice type too. Consider this array: - -``` -let a = [1, 2, 3, 4, 5]; -``` - -Just as we might want to refer to part of a string, we might want to refer to -part of an array. We’d do so like this: - -``` -let a = [1, 2, 3, 4, 5]; - -let slice = &a[1..3]; - -assert_eq!(slice, &[2, 3]); -``` - -This slice has the type `&[i32]`. It works the same way as string slices do, by -storing a reference to the first element and a length. You’ll use this kind of -slice for all sorts of other collections. We’ll discuss these collections in -detail when we talk about vectors in Chapter 8. - -## Summary - -The concepts of ownership, borrowing, and slices ensure memory safety in Rust -programs at compile time. The Rust language gives you control over your memory -usage in the same way as other systems programming languages, but having the -owner of data automatically clean up that data when the owner goes out of scope -means you don’t have to write and debug extra code to get this control. - -Ownership affects how lots of other parts of Rust work, so we’ll talk about -these concepts further throughout the rest of the book. Let’s move on to -Chapter 5 and look at grouping pieces of data together in a `struct`. - diff --git a/rustbook-en/nostarch/chapter05.md b/rustbook-en/nostarch/chapter05.md deleted file mode 100644 index 9881a3b74..000000000 --- a/rustbook-en/nostarch/chapter05.md +++ /dev/null @@ -1,995 +0,0 @@ - - -[TOC] - -# Using Structs to Structure Related Data - -A *struct*, or *structure*, is a custom data type that lets you package -together and name multiple related values that make up a meaningful group. If -you’re familiar with an object-oriented language, a *struct* is like an -object’s data attributes. In this chapter, we’ll compare and contrast tuples -with structs to build on what you already know and demonstrate when structs are -a better way to group data. - -We’ll demonstrate how to define and instantiate structs. We’ll discuss how to -define associated functions, especially the kind of associated functions called -*methods*, to specify behavior associated with a struct type. Structs and enums -(discussed in Chapter 6) are the building blocks for creating new types in your -program’s domain to take full advantage of Rust’s compile-time type checking. - -## Defining and Instantiating Structs - -Structs are similar to tuples, discussed in “The Tuple Type” on page XX, in -that both hold multiple related values. Like tuples, the pieces of a struct can -be different types. Unlike with tuples, in a struct you’ll name each piece of -data so it’s clear what the values mean. Adding these names means that structs -are more flexible than tuples: you don’t have to rely on the order of the data -to specify or access the values of an instance. - -To define a struct, we enter the keyword `struct` and name the entire struct. A -struct’s name should describe the significance of the pieces of data being -grouped together. Then, inside curly brackets, we define the names and types of -the pieces of data, which we call *fields*. For example, Listing 5-1 shows a -struct that stores information about a user account. - -Filename: src/main.rs - -``` -struct User { - active: bool, - username: String, - email: String, - sign_in_count: u64, -} -``` - -Listing 5-1: A `User` struct definition - -To use a struct after we’ve defined it, we create an *instance* of that struct -by specifying concrete values for each of the fields. We create an instance by -stating the name of the struct and then add curly brackets containing key: -value pairs, where the keys are the names of the fields and the values are the -data we want to store in those fields. We don’t have to specify the fields in -the same order in which we declared them in the struct. In other words, the -struct definition is like a general template for the type, and instances fill -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. - -Filename: src/main.rs - -``` -fn main() { - let user1 = User { - active: true, - username: String::from("someusername123"), - email: String::from("someone@example.com"), - sign_in_count: 1, - }; -} -``` - -Listing 5-2: Creating an instance of the `User` struct - -To get a specific value from a struct, we use dot notation. For example, to -access this user’s email address, we use `user1.email`. If the instance is -mutable, we can change a value by using 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. - -Filename: src/main.rs - -``` -fn main() { - let mut user1 = User { - active: true, - username: String::from("someusername123"), - email: String::from("someone@example.com"), - sign_in_count: 1, - }; - - user1.email = String::from("anotheremail@example.com"); -} -``` - -Listing 5-3: Changing the value in the `email` field of a `User` instance - -Note that the entire instance must be mutable; Rust doesn’t allow us to mark -only certain fields as mutable. As with any expression, we can construct a new -instance of the struct as the last expression in the function body to -implicitly return that new instance. - -Listing 5-4 shows a `build_user` function that returns a `User` instance with -the given email and username. The `active` field gets the value of `true`, and -the `sign_in_count` gets a value of `1`. - -``` -fn build_user(email: String, username: String) -> User { - User { - active: true, - username: username, - email: email, - sign_in_count: 1, - } -} -``` - -Listing 5-4: A `build_user` function that takes an email and username and -returns a `User` instance - -It makes sense to name the function parameters with the same name as the struct -fields, but having to repeat the `email` and `username` field names and -variables is a bit tedious. If the struct had more fields, repeating each name -would get even more annoying. Luckily, there’s a convenient shorthand! - -### Using the Field Init Shorthand - -Because the parameter names and the struct field names are exactly the same in -Listing 5-4, we can use the *field init shorthand* syntax to rewrite -`build_user` so it behaves exactly the same but doesn’t have the repetition of -`username` and `email`, as shown in Listing 5-5. - -``` -fn build_user(email: String, username: String) -> User { - User { - active: true, - username, - email, - sign_in_count: 1, - } -} -``` - -Listing 5-5: A `build_user` function that uses field init shorthand because the -`username` and `email` parameters have the same name as struct fields - -Here, we’re creating a new instance of the `User` struct, which has a field -named `email`. We want to set the `email` field’s value to the value in the -`email` parameter of the `build_user` function. Because the `email` field and -the `email` parameter have the same name, we only need to write `email` rather -than `email: email`. - -### Creating Instances from Other Instances with Struct Update Syntax - -It’s often useful to create a new instance of a struct that includes most of -the values from another instance, but changes some. You can do this using -*struct update syntax*. - -First, in Listing 5-6 we show how to create a new `User` instance in `user2` -regularly, without the update syntax. We set a new value for `email` but -otherwise use the same values from `user1` that we created in Listing 5-2. - -Filename: src/main.rs - -``` -fn main() { - --snip-- - - let user2 = User { - active: user1.active, - username: user1.username, - email: String::from("another@example.com"), - sign_in_count: user1.sign_in_count, - }; -} -``` - -Listing 5-6: Creating a new `User` instance using one of the values from `user1` - -Using struct update syntax, we can achieve the same effect with less code, as -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. - -Filename: src/main.rs - -``` -fn main() { - --snip-- - - - let user2 = User { - email: String::from("another@example.com"), - ..user1 - }; -} -``` - -Listing 5-7: Using struct update syntax to set a new `email` value for a `User` -instance but to use the rest of the values from `user1` - -The code in Listing 5-7 also creates an instance in `user2` that has a -different value for `email` but has the same values for the `username`, -`active`, and `sign_in_count` fields from `user1`. The `..user1` must come last -to specify that any remaining fields should get their values from the -corresponding fields in `user1`, but we can choose to specify values for as -many fields as we want in any order, regardless of the order of the fields in -the struct’s definition. - -Note that the struct update syntax uses `=` like an assignment; this is because -it moves the data, just as we saw in “Variables and Data Interacting with Move” -on page XX. In this example, we can no longer use `user1` after creating -`user2` because the `String` in the `username` field of `user1` was moved into -`user2`. If we had given `user2` new `String` values for both `email` and -`username`, and thus only used the `active` and `sign_in_count` values from -`user1`, then `user1` would still be valid after creating `user2`. Both -`active` and `sign_in_count` are types that implement the `Copy` trait, so the -behavior we discussed in “Stack-Only Data: Copy” on page XX would apply. - -### Using Tuple Structs Without Named Fields to Create Different Types - -Rust also supports structs that look similar to tuples, called *tuple structs*. -Tuple structs have the added meaning the struct name provides but don’t have -names associated with their fields; rather, they just have the types of the -fields. Tuple structs are useful when you want to give the whole tuple a name -and make the tuple a different type from other tuples, and when naming each -field as in a regular struct would be verbose or redundant. - -To define a tuple struct, start with the `struct` keyword and the struct name -followed by the types in the tuple. For example, here we define and use two -tuple structs named `Color` and `Point`: - -Filename: src/main.rs - -``` -struct Color(i32, i32, i32); -struct Point(i32, i32, i32); - -fn main() { - let black = Color(0, 0, 0); - let origin = Point(0, 0, 0); -} -``` - -Note that the `black` and `origin` values are different types because they’re -instances of different tuple structs. Each struct you define is its own type, -even though the fields within the struct might have the same types. For -example, a function that takes a parameter of type `Color` cannot take a -`Point` as an argument, even though both types are made up of three `i32` -values. Otherwise, tuple struct instances are similar to tuples in that you can -destructure them into their individual pieces, and you can use a `.` followed -by the index to access an individual value. - -### Unit-Like Structs Without Any Fields - -You can also define structs that don’t have any fields! These are called -*unit-like structs* because they behave similarly to `()`, the unit type that -we mentioned in “The Tuple Type” on page XX. Unit-like structs can be useful -when you need to implement a trait on some type but don’t have any data that -you want to store in the type itself. We’ll discuss traits in Chapter 10. -Here’s an example of declaring and instantiating a unit struct named -`AlwaysEqual`: - -Filename: src/main.rs - -``` -struct AlwaysEqual; - -fn main() { - let subject = AlwaysEqual; -} -``` - -To define `AlwaysEqual`, we use the `struct` keyword, the name we want, and -then a semicolon. No need for curly brackets or parentheses! Then we can get an -instance of `AlwaysEqual` in the `subject` variable in a similar way: using the -name we defined, without any curly brackets or parentheses. Imagine that later -we’ll implement behavior for this type such that every instance of -`AlwaysEqual` is always equal to every instance of any other type, perhaps to -have a known result for testing purposes. We wouldn’t need any data to -implement that behavior! You’ll see in Chapter 10 how to define traits and -implement them on any type, including unit-like structs. - -> ### Ownership of Struct Data -> -> In the `User` struct definition in Listing 5-1, we used the owned `String` -type rather than the `&str` string slice type. This is a deliberate choice -because we want each instance of this struct to own all of its data and for -that data to be valid for as long as the entire struct is valid. -> -> It’s also possible for structs to store references to data owned by something -else, but to do so requires the use of *lifetimes*, a Rust feature that we’ll -discuss in Chapter 10. Lifetimes ensure that the data referenced by a struct is -valid for as long as the struct is. Let’s say you try to store a reference in a -struct without specifying lifetimes, like the following in *src/main.rs*; this -won’t work: -> -> ``` -> struct User { -> active: bool, -> username: &str, -> email: &str, -> sign_in_count: u64, -> } -> -> fn main() { -> let user1 = User { -> active: true, -> username: "someusername123", -> email: "someone@example.com", -> sign_in_count: 1, -> }; -> } -> ``` -> -> The compiler will complain that it needs lifetime specifiers: -> -> ``` -> $ `cargo run` -> Compiling structs v0.1.0 (file:///projects/structs) -> error[E0106]: missing lifetime specifier -> --> src/main.rs:3:15 -> | -> 3 | username: &str, -> | ^ expected named lifetime parameter -> | -> help: consider introducing a named lifetime parameter -> | -> 1 ~ struct User<'a> { -> 2 | active: bool, -> 3 ~ username: &'a str, -> | -> -> error[E0106]: missing lifetime specifier -> --> src/main.rs:4:12 -> | -> 4 | email: &str, -> | ^ expected named lifetime parameter -> | -> help: consider introducing a named lifetime parameter -> | -> 1 ~ struct User<'a> { -> 2 | active: bool, -> 3 | username: &str, -> 4 ~ email: &'a str, -> | -> ``` -> -> 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`. - -## An Example Program Using Structs - -To understand when we might want to use structs, let’s write a program that -calculates the area of a rectangle. We’ll start by using single variables, and -then refactor the program until we’re using structs instead. - -Let’s make a new binary project with Cargo called *rectangles* that will take -the width and height of a rectangle specified in pixels and calculate the area -of the rectangle. Listing 5-8 shows a short program with one way of doing -exactly that in our project’s *src/main.rs*. - -Filename: src/main.rs - -``` -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 -} -``` - -Listing 5-8: Calculating the area of a rectangle specified by separate width -and height variables - -Now, run this program using `cargo run`: - -``` -The area of the rectangle is 1500 square pixels. -``` - -This code succeeds in figuring out the area of the rectangle by calling the -`area` function with each dimension, but we can do more to make this code clear -and readable. - -The issue with this code is evident in the signature of `area`: - -``` -fn area(width: u32, height: u32) -> u32 { -``` - -The `area` function is supposed to calculate the area of one rectangle, but the -function we wrote has two parameters, and it’s not clear anywhere in our -program that the parameters are related. It would be more readable and more -manageable to group width and height together. We’ve already discussed one way -we might do that in “The Tuple Type” on page XX: by using tuples. - -### Refactoring with Tuples - -Listing 5-9 shows another version of our program that uses tuples. - -Filename: src/main.rs - -``` -fn main() { - let rect1 = (30, 50); - - println!( - "The area of the rectangle is {} square pixels.", - 1 area(rect1) - ); -} - -fn area(dimensions: (u32, u32)) -> u32 { - 2 dimensions.0 * dimensions.1 -} -``` - -Listing 5-9: Specifying the width and height of the rectangle with a tuple - -In one way, this program is better. Tuples let us add a bit of structure, and -we’re now passing just one argument [1]. But in another way, this version is -less clear: tuples don’t name their elements, so we have to index into the -parts of the tuple [2], making our calculation less obvious. - -Mixing up the width and height wouldn’t matter for the area calculation, but if -we want to draw the rectangle on the screen, it would matter! We would have to -keep in mind that `width` is the tuple index `0` and `height` is the tuple -index `1`. This would be even harder for someone else to figure out and keep in -mind if they were to use our code. Because we haven’t conveyed the meaning of -our data in our code, it’s now easier to introduce errors. - -### Refactoring with Structs: Adding More Meaning - -We use structs to add meaning by labeling the data. We can transform the tuple -we’re using into a struct with a name for the whole as well as names for the -parts, as shown in Listing 5-10. - -Filename: src/main.rs - -``` -1 struct Rectangle { - 2 width: u32, - height: u32, -} - -fn main() { - 3 let rect1 = Rectangle { - width: 30, - height: 50, - }; - - println!( - "The area of the rectangle is {} square pixels.", - area(&rect1) - ); -} - -4 fn area(rectangle: &Rectangle) -> u32 { - 5 rectangle.width * rectangle.height -} -``` - -Listing 5-10: Defining a `Rectangle` struct - -Here, we’ve defined a struct and named it `Rectangle` [1]. Inside the curly -brackets, we defined the fields as `width` and `height`, both of which have -type `u32` [2]. Then, in `main`, we created a particular instance of -`Rectangle` that has a width of `30` and a height of `50` [3]. - -Our `area` function is now defined with one parameter, which we’ve named -`rectangle`, whose type is an immutable borrow of a struct `Rectangle` instance -[4]. As mentioned in Chapter 4, we want to borrow the struct rather than take -ownership of it. This way, `main` retains its ownership and can continue using -`rect1`, which is the reason we use the `&` in the function signature and where -we call the function. - -The `area` function accesses the `width` and `height` fields of the `Rectangle` -instance [5] (note that accessing fields of a borrowed struct instance does not -move the field values, which is why you often see borrows of structs). Our -function signature for `area` now says exactly what we mean: calculate the area -of `Rectangle`, using its `width` and `height` fields. This conveys that the -width and height are related to each other, and it gives descriptive names to -the values rather than using the tuple index values of `0` and `1`. This is a -win for clarity. - -### Adding Useful Functionality with Derived Traits - -It’d be useful to be able to print an instance of `Rectangle` while we’re -debugging our program and see the values for all its fields. Listing 5-11 tries -using the `println!` macro as we have used in previous chapters. This won’t -work, however. - -Filename: src/main.rs - -``` -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - println!("rect1 is {}", rect1); -} -``` - -Listing 5-11: Attempting to print a `Rectangle` instance - -When we compile this code, we get an error with this core message: - -``` -error[E0277]: `Rectangle` doesn't implement `std::fmt::Display` -``` - -The `println!` macro can do many kinds of formatting, and by default, the curly -brackets tell `println!` to use formatting known as `Display`: output intended -for direct end user consumption. The primitive types we’ve seen so far -implement `Display` by default because there’s only one way you’d want to show -a `1` or any other primitive type to a user. But with structs, the way -`println!` should format the output is less clear because there are more -display possibilities: Do you want commas or not? Do you want to print the -curly brackets? Should all the fields be shown? Due to this ambiguity, Rust -doesn’t try to guess what we want, and structs don’t have a provided -implementation of `Display` to use with `println!` and the `{}` placeholder. - -If we continue reading the errors, we’ll find this helpful note: - -``` -= 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 -``` - -Let’s try it! The `println!` macro call will now look like `println!("rect1 is -{:?}", rect1);`. Putting the specifier `:?` inside the curly brackets tells -`println!` we want to use an output format called `Debug`. The `Debug` trait -enables us to print our struct in a way that is useful for developers so we can -see its value while we’re debugging our code. - -Compile the code with this change. Drat! We still get an error: - -``` -error[E0277]: `Rectangle` doesn't implement `Debug` -``` - -But again, the compiler gives us a helpful note: - -``` -= help: the trait `Debug` is not implemented for `Rectangle` -= note: add `#[derive(Debug)]` or manually implement `Debug` -``` - -Rust *does* include functionality to print out debugging information, but we -have to explicitly opt in to make that functionality available for our struct. -To do that, we add the outer attribute `#[derive(Debug)]` just before the -struct definition, as shown in Listing 5-12. - -Filename: src/main.rs - -``` -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - println!("rect1 is {:?}", rect1); -} -``` - -Listing 5-12: Adding the attribute to derive the `Debug` trait and printing the -`Rectangle` instance using debug formatting - -Now when we run the program, we won’t get any errors, and we’ll see the -following output: - -``` -rect1 is Rectangle { width: 30, height: 50 } -``` - -Nice! It’s not the prettiest output, but it shows the values of all the fields -for this instance, which would definitely help during debugging. When we have -larger structs, it’s useful to have output that’s a bit easier to read; in -those cases, we can use `{:#?}` instead of `{:?}` in the `println!` string. In -this example, using the `{:#?}` style will output the following: - -``` -rect1 is Rectangle { - width: 30, - height: 50, -} -``` - -Another way to print out a value using the `Debug` format is to use the `dbg!` -macro, which takes ownership of an expression (as opposed to `println!`, which -takes a reference), prints the file and line number of where that `dbg!` macro -call occurs in your code along with the resultant value of that expression, and -returns ownership of the value. - -> Note: Calling the `dbg!` macro prints to the standard error console stream -(`stderr`), as opposed to `println!`, which prints to the standard output -console stream (`stdout`). We’ll talk more about `stderr` and `stdout` in -“Writing Error Messages to Standard Error Instead of Standard Output” on page -XX. - -Here’s an example where we’re interested in the value that gets assigned to the -`width` field, as well as the value of the whole struct in `rect1`: - -Filename: src/main.rs - -``` -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let scale = 2; - let rect1 = Rectangle { - 1 width: dbg!(30 * scale), - height: 50, - }; - - 2 dbg!(&rect1); -} -``` - -We can put `dbg!` around the expression `30 * scale` [1] and, because `dbg!` -returns ownership of the expression’s value, the `width` field will get the -same value as if we didn’t have the `dbg!` call there. We don’t want `dbg!` to -take ownership of `rect1`, so we use a reference to `rect1` in the next call -[2]. Here’s what the output of this example looks like: - -``` -[src/main.rs:10] 30 * scale = 60 -[src/main.rs:14] &rect1 = Rectangle { - width: 60, - height: 50, -} -``` - -We can see the first bit of output came from [1] where we’re debugging the -expression `30 * scale`, and its resultant value is `60` (the `Debug` -formatting implemented for integers is to print only their value). The `dbg!` -call at [2] outputs the value of `&rect1`, which is the `Rectangle` struct. -This output uses the pretty `Debug` formatting of the `Rectangle` type. The -`dbg!` macro can be really helpful when you’re trying to figure out what your -code is doing! - -In addition to the `Debug` trait, Rust has provided a number of traits for us -to use with the `derive` attribute that can add useful behavior to our custom -types. Those traits and their behaviors are listed in Appendix C. We’ll cover -how to implement these traits with custom behavior as well as how to create -your own traits in Chapter 10. There are also many attributes other than -`derive`; for more information, see the “Attributes” section of the Rust -Reference at *https://doc.rust-lang.org/reference/attributes.html*. - -Our `area` function is very specific: it only computes the area of rectangles. -It would be helpful to tie this behavior more closely to our `Rectangle` struct -because it won’t work with any other type. Let’s look at how we can continue to -refactor this code by turning the `area` function into an `area` *method* -defined on our `Rectangle` type. - -## Method Syntax - -*Methods* are similar to functions: we declare them with the `fn` keyword and a -name, they can have parameters and a return value, and they contain some code -that’s run when the method is called from somewhere else. Unlike functions, -methods are defined within the context of a struct (or an enum or a trait -object, which we cover in Chapter 6 and Chapter 17, respectively), and their -first parameter is always `self`, which represents the instance of the struct -the method is being called on. - -### Defining Methods - -Let’s change the `area` function that has a `Rectangle` instance as a parameter -and instead make an `area` method defined on the `Rectangle` struct, as shown -in Listing 5-13. - -Filename: src/main.rs - -``` -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -1 impl Rectangle { - 2 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.", - 3 rect1.area() - ); -} -``` - -Listing 5-13: Defining an `area` method on the `Rectangle` struct - -To define the function within the context of `Rectangle`, we start an `impl` -(implementation) block for `Rectangle` [1]. Everything within this `impl` block -will be associated with the `Rectangle` type. Then we move the `area` function -within the `impl` curly brackets [2] and change the first (and in this case, -only) parameter to be `self` in the signature and everywhere within the body. -In `main`, where we called the `area` function and passed `rect1` as an -argument, we can instead use *method syntax* to call the `area` method on our -`Rectangle` instance [3]. The method syntax goes after an instance: we add a -dot followed by the method name, parentheses, and any arguments. - -In the signature for `area`, we use `&self` instead of `rectangle: &Rectangle`. -The `&self` is actually short for `self: &Self`. Within an `impl` block, the -type `Self` is an alias for the type that the `impl` block is for. Methods must -have a parameter named `self` of type `Self` for their first parameter, so Rust -lets you abbreviate this with only the name `self` in the first parameter spot. -Note that we still need to use the `&` in front of the `self` shorthand to -indicate that this method borrows the `Self` instance, just as we did in -`rectangle: &Rectangle`. Methods can take ownership of `self`, borrow `self` -immutably, as we’ve done here, or borrow `self` mutably, just as they can any -other parameter. - -We chose `&self` here for the same reason we used `&Rectangle` in the function -version: we don’t want to take ownership, and we just want to read the data in -the struct, not write to it. If we wanted to change the instance that we’ve -called the method on as part of what the method does, we’d use `&mut self` as -the first parameter. Having a method that takes ownership of the instance by -using just `self` as the first parameter is rare; this technique is usually -used when the method transforms `self` into something else and you want to -prevent the caller from using the original instance after the transformation. - -The main reason for using methods instead of functions, in addition to -providing method syntax and not having to repeat the type of `self` in every -method’s signature, is for organization. We’ve put all the things we can do -with an instance of a type in one `impl` block rather than making future users -of our code search for capabilities of `Rectangle` in various places in the -library we provide. - -Note that we can choose to give a method the same name as one of the struct’s -fields. For example, we can define a method on `Rectangle` that is also named -`width`: - -Filename: src/main.rs - -``` -impl Rectangle { - fn width(&self) -> bool { - self.width > 0 - } -} - -fn main() { - let rect1 = Rectangle { - width: 30, - height: 50, - }; - - if rect1.width() { - println!( - "The rectangle has a nonzero width; it is {}", - rect1.width - ); - } -} -``` - -Here, we’re choosing to make the `width` method return `true` if the value in -the instance’s `width` field is greater than `0` and `false` if the value is -`0`: we can use a field within a method of the same name for any purpose. In -`main`, when we follow `rect1.width` with parentheses, Rust knows we mean the -method `width`. When we don’t use parentheses, Rust knows we mean the field -`width`. - -Often, but not always, when we give methods with the same name as a field we -want it to only return the value in the field and do nothing else. Methods like -this are called *getters*, and Rust does not implement them automatically for -struct fields as some other languages do. Getters are useful because you can -make the field private but the method public, and thus enable read-only access -to that field as part of the type’s public API. We will discuss what public and -private are and how to designate a field or method as public or private in -Chapter 7. - -> ### Where’s the -> Operator? -> -> In C and C++, two different operators are used for calling methods: you use -`.` if you’re calling a method on the object directly and `->` if you’re -calling the method on a pointer to the object and need to dereference the -pointer first. In other words, if `object` is a pointer, -`object->`something`()` is similar to `(*object).`something`()`. -> -> Rust doesn’t have an equivalent to the `->` operator; instead, Rust has a -feature called *automatic referencing and dereferencing*. Calling methods is -one of the few places in Rust that has this behavior. -> -> Here’s how it works: when you call a method with `object.`something`()`, Rust -automatically adds in `&`, `&mut`, or `*` so `object` matches the signature of -the method. In other words, the following are the same: -> -> ``` -> p1.distance(&p2); -> (&p1).distance(&p2); -> ``` -> -> The first one looks much cleaner. This automatic referencing behavior works -because methods have a clear receiver—the type of `self`. Given the receiver -and name of a method, Rust can figure out definitively whether the method is -reading (`&self`), mutating (`&mut self`), or consuming (`self`). The fact that -Rust makes borrowing implicit for method receivers is a big part of making -ownership ergonomic in practice. - -### Methods with More Parameters - -Let’s practice using methods by implementing a second method on the `Rectangle` -struct. This time we want an instance of `Rectangle` to take another instance -of `Rectangle` and return `true` if the second `Rectangle` can fit completely -within `self` (the first `Rectangle`); otherwise, it should return `false`. -That is, once we’ve defined the `can_hold` method, we want to be able to write -the program shown in Listing 5-14. - -Filename: src/main.rs - -``` -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)); -} -``` - -Listing 5-14: Using the as-yet-unwritten `can_hold` method - -The expected output would look like the following because both dimensions of -`rect2` are smaller than the dimensions of `rect1`, but `rect3` is wider than -`rect1`: - -``` -Can rect1 hold rect2? true -Can rect1 hold rect3? false -``` - -We know we want to define a method, so it will be within the `impl Rectangle` -block. The method name will be `can_hold`, and it will take an immutable borrow -of another `Rectangle` as a parameter. We can tell what the type of the -parameter will be by looking at the code that calls the method: -`rect1.can_hold(&rect2)` passes in `&rect2`, which is an immutable borrow to -`rect2`, an instance of `Rectangle`. This makes sense because we only need to -read `rect2` (rather than write, which would mean we’d need a mutable borrow), -and we want `main` to retain ownership of `rect2` so we can use it again after -calling the `can_hold` method. The return value of `can_hold` will be a -Boolean, and the implementation will check whether the width and height of -`self` are greater than the width and height of the other `Rectangle`, -respectively. Let’s add the new `can_hold` method to the `impl` block from -Listing 5-13, shown in Listing 5-15. - -Filename: src/main.rs - -``` -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 - } -} -``` - -Listing 5-15: Implementing the `can_hold` method on `Rectangle` that takes -another `Rectangle` instance as a parameter - -When we run this code with the `main` function in Listing 5-14, we’ll get our -desired output. Methods can take multiple parameters that we add to the -signature after the `self` parameter, and those parameters work just like -parameters in functions. - -### Associated Functions - -All functions defined within an `impl` block are called *associated functions* -because they’re associated with the type named after the `impl`. We can define -associated functions that don’t have `self` as their first parameter (and thus -are not methods) because they don’t need an instance of the type to work with. -We’ve already used one function like this: the `String::from` function that’s -defined on the `String` type. - -Associated functions that aren’t methods are often used for constructors that -will return a new instance of the struct. These are often called `new`, but -`new` isn’t a special name and isn’t built into the language. For example, we -could choose to provide an associated function named `square` that would have -one dimension parameter and use that as both width and height, thus making it -easier to create a square `Rectangle` rather than having to specify the same -value twice: - -Filename: src/main.rs - -``` -impl Rectangle { - fn square(size: u32) -> 1 Self { - 2 Self { - width: size, - height: size, - } - } -} -``` - -The `Self` keywords in the return type [1] and in the body of the function [2] -are aliases for the type that appears after the `impl` keyword, which in this -case is `Rectangle`. - -To call this associated function, we use the `::` syntax with the struct name; -`let sq = Rectangle::square(3);` is an example. This function is namespaced by -the struct: the `::` syntax is used for both associated functions and -namespaces created by modules. We’ll discuss modules in Chapter 7. - -### Multiple impl Blocks - -Each struct is allowed to have multiple `impl` blocks. For example, Listing -5-15 is equivalent to the code shown in Listing 5-16, which has each method in -its own `impl` block. - -``` -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 - } -} -``` - -Listing 5-16: Rewriting Listing 5-15 using multiple `impl` blocks - -There’s no reason to separate these methods into multiple `impl` blocks here, -but this is valid syntax. We’ll see a case in which multiple `impl` blocks are -useful in Chapter 10, where we discuss generic types and traits. - -## Summary - -Structs let you create custom types that are meaningful for your domain. By -using structs, you can keep associated pieces of data connected to each other -and name each piece to make your code clear. In `impl` blocks, you can define -functions that are associated with your type, and methods are a kind of -associated function that let you specify the behavior that instances of your -structs have. - -But structs aren’t the only way you can create custom types: let’s turn to -Rust’s enum feature to add another tool to your toolbox. - diff --git a/rustbook-en/nostarch/chapter06.md b/rustbook-en/nostarch/chapter06.md deleted file mode 100644 index ea4328bea..000000000 --- a/rustbook-en/nostarch/chapter06.md +++ /dev/null @@ -1,845 +0,0 @@ - - -[TOC] - -# Enums and Pattern Matching - -In this chapter, we’ll look at *enumerations*, also referred to as *enums*. -Enums allow you to define a type by enumerating its possible *variants*. First -we’ll define and use an enum to show how an enum can encode meaning along with -data. Next, we’ll explore a particularly useful enum, called `Option`, which -expresses that a value can be either something or nothing. Then we’ll look at -how pattern matching in the `match` expression makes it easy to run different -code for different values of an enum. Finally, we’ll cover how the `if let` -construct is another convenient and concise idiom available to handle enums in -your code. - -## Defining an Enum - -Where structs give you a way of grouping together related fields and data, like -a `Rectangle` with its `width` and `height`, enums give you a way of saying a -value is one of a possible set of values. For example, we may want to say that -`Rectangle` is one of a set of possible shapes that also includes `Circle` and -`Triangle`. To do this, Rust allows us to encode these possibilities as an enum. - -Let’s look at a situation we might want to express in code and see why enums -are useful and more appropriate than structs in this case. Say we need to work -with IP addresses. Currently, two major standards are used for IP addresses: -version four and version six. Because these are the only possibilities for an -IP address that our program will come across, we can *enumerate* all possible -variants, which is where enumeration gets its name. - -Any IP address can be either a version four or a version six address, but not -both at the same time. That property of IP addresses makes the enum data -structure appropriate because an enum value can only be one of its variants. -Both version four and version six addresses are still fundamentally IP -addresses, so they should be treated as the same type when the code is handling -situations that apply to any kind of IP address. - -We can express this concept in code by defining an `IpAddrKind` enumeration and -listing the possible kinds an IP address can be, `V4` and `V6`. These are the -variants of the enum: - -``` -enum IpAddrKind { - V4, - V6, -} -``` - -`IpAddrKind` is now a custom data type that we can use elsewhere in our code. - -### Enum Values - -We can create instances of each of the two variants of `IpAddrKind` like this: - -``` -let four = IpAddrKind::V4; -let six = IpAddrKind::V6; -``` - -Note that the variants of the enum are namespaced under its identifier, and we -use a double colon to separate the two. This is useful because now both values -`IpAddrKind::V4` and `IpAddrKind::V6` are of the same type: `IpAddrKind`. We -can then, for instance, define a function that takes any `IpAddrKind`: - -``` -fn route(ip_kind: IpAddrKind) {} -``` - -And we can call this function with either variant: - -``` -route(IpAddrKind::V4); -route(IpAddrKind::V6); -``` - -Using enums has even more advantages. Thinking more about our IP address type, -at the moment we don’t have a way to store the actual IP address *data*; we -only know what *kind* it is. Given that you just learned about structs in -Chapter 5, you might be tempted to tackle this problem with structs as shown in -Listing 6-1. - -``` -1 enum IpAddrKind { - V4, - V6, -} - -2 struct IpAddr { - 3 kind: IpAddrKind, - 4 address: String, -} - -5 let home = IpAddr { - kind: IpAddrKind::V4, - address: String::from("127.0.0.1"), -}; - -6 let loopback = IpAddr { - kind: IpAddrKind::V6, - address: String::from("::1"), -}; -``` - -Listing 6-1: Storing the data and `IpAddrKind` variant of an IP address using a -`struct` - -Here, we’ve defined a struct `IpAddr` [2] that has two fields: a `kind` field -[3] that is of type `IpAddrKind` (the enum we defined previously [1]) and an -`address` field [4] of type `String`. We have two instances of this struct. The -first is `home` [5], and it has the value `IpAddrKind::V4` as its `kind` with -associated address data of `127.0.0.1`. The second instance is `loopback` [6]. -It has the other variant of `IpAddrKind` as its `kind` value, `V6`, and has -address `::1` associated with it. We’ve used a struct to bundle the `kind` and -`address` values together, so now the variant is associated with the value. - -However, representing the same concept using just an enum is more concise: -rather than an enum inside a struct, we can put data directly into each enum -variant. This new definition of the `IpAddr` enum says that both `V4` and `V6` -variants will have associated `String` values: - -``` -enum IpAddr { - V4(String), - V6(String), -} - -let home = IpAddr::V4(String::from("127.0.0.1")); - -let loopback = IpAddr::V6(String::from("::1")); -``` - -We attach data to each variant of the enum directly, so there is no need for an -extra struct. Here, it’s also easier to see another detail of how enums work: -the name of each enum variant that we define also becomes a function that -constructs an instance of the enum. That is, `IpAddr::V4()` is a function call -that takes a `String` argument and returns an instance of the `IpAddr` type. We -automatically get this constructor function defined as a result of defining the -enum. - -There’s another advantage to using an enum rather than a struct: each variant -can have different types and amounts of associated data. Version four IP -addresses will always have four numeric components that will have values -between 0 and 255. If we wanted to store `V4` addresses as four `u8` values but -still express `V6` addresses as one `String` value, we wouldn’t be able to with -a struct. Enums handle this case with ease: - -``` -enum IpAddr { - V4(u8, u8, u8, u8), - V6(String), -} - -let home = IpAddr::V4(127, 0, 0, 1); - -let loopback = IpAddr::V6(String::from("::1")); -``` - -We’ve shown several different ways to define data structures to store version -four and version six IP addresses. However, as it turns out, wanting to store -IP addresses and encode which kind they are is so common that the standard -library has a definition we can use! Let’s look at how the standard library -defines `IpAddr`: it has the exact enum and variants that we’ve defined and -used, but it embeds the address data inside the variants in the form of two -different structs, which are defined differently for each variant: - -``` -struct Ipv4Addr { - --snip-- -} - -struct Ipv6Addr { - --snip-- -} - -enum IpAddr { - V4(Ipv4Addr), - V6(Ipv6Addr), -} -``` - -This code illustrates that you can put any kind of data inside an enum variant: -strings, numeric types, or structs, for example. You can even include another -enum! Also, standard library types are often not much more complicated than -what you might come up with. - -Note that even though the standard library contains a definition for `IpAddr`, -we can still create and use our own definition without conflict because we -haven’t brought the standard library’s definition into our scope. We’ll talk -more about bringing types into scope in Chapter 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. - -``` -enum Message { - Quit, - Move { x: i32, y: i32 }, - Write(String), - ChangeColor(i32, i32, i32), -} -``` - -Listing 6-2: A `Message` enum whose variants each store different amounts and -types of values - -This enum has four variants with different types: - -* `Quit` has no data associated with it at all. -* `Move` has named fields, like a struct does. -* `Write` includes a single `String`. -* `ChangeColor` includes three `i32` values. - -Defining an enum with variants such as the ones in Listing 6-2 is similar to -defining different kinds of struct definitions, except the enum doesn’t use the -`struct` keyword and all the variants are grouped together under the `Message` -type. The following structs could hold the same data that the preceding enum -variants hold: - -``` -struct QuitMessage; // unit struct -struct MoveMessage { - x: i32, - y: i32, -} -struct WriteMessage(String); // tuple struct -struct ChangeColorMessage(i32, i32, i32); // tuple struct -``` - -But if we used the different structs, each of which has its own type, we -couldn’t as easily define a function to take any of these kinds of messages as -we could with the `Message` enum defined in Listing 6-2, which is a single type. - -There is one more similarity between enums and structs: just as we’re able to -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: - -``` -impl Message { - fn call(&self) { - 1 // method body would be defined here - } -} - -2 let m = Message::Write(String::from("hello")); -m.call(); -``` - -The body of the method would use `self` to get the value that we called the -method on. In this example, we’ve created a variable `m` [2] that has the value -`Message::Write(String::from("hello"))`, and that is what `self` will be in the -body of the `call` method [1] when `m.call()` runs. - -Let’s look at another enum in the standard library that is very common and -useful: `Option`. - -### The Option Enum and Its Advantages Over Null Values - -This section explores a case study of `Option`, which is another enum defined -by the standard library. The `Option` type encodes the very common scenario in -which a value could be something or it could be nothing. - -For example, if you request the first item in a list containing multiple items, -you would get a value. If you request the first item in an empty list, you -would get nothing. Expressing this concept in terms of the type system means -the compiler can check whether you’ve handled all the cases you should be -handling; this functionality can prevent bugs that are extremely common in -other programming languages. - -Programming language design is often thought of in terms of which features you -include, but the features you exclude are important too. Rust doesn’t have the -null feature that many other languages have. *Null* is a value that means there -is no value there. In languages with null, variables can always be in one of -two states: null or not-null. - -In his 2009 presentation “Null References: The Billion Dollar Mistake,” Tony -Hoare, the inventor of null, has this to say: - -> I call it my billion-dollar mistake. At that time, I was designing the first -comprehensive type system for references in an object-oriented language. My -goal was to ensure that all use of references should be absolutely safe, with -checking performed automatically by the compiler. But I couldn’t resist the -temptation to put in a null reference, simply because it was so easy to -implement. This has led to innumerable errors, vulnerabilities, and system -crashes, which have probably caused a billion dollars of pain and damage in the -last forty years.The problem with null values is that if you try to use a null -value as a not-null value, you’ll get an error of some kind. Because this null -or not-null property is pervasive, it’s extremely easy to make this kind of -error. - -However, the concept that null is trying to express is still a useful one: a -null is a value that is currently invalid or absent for some reason. - -The problem isn’t really with the concept but with the particular -implementation. As such, Rust does not have nulls, but it does have an enum -that can encode the concept of a value being present or absent. This enum is -`Option`, and it is defined by the standard library as follows: - -``` -enum Option { - None, - Some(T), -} -``` - -The `Option` enum is so useful that it’s even included in the prelude; you -don’t need to bring it into scope explicitly. Its variants are also included in -the prelude: you can use `Some` and `None` directly without the `Option::` -prefix. The `Option` enum is still just a regular enum, and `Some(T)` and -`None` are still variants of type `Option`. - -The `` syntax is a feature of Rust we haven’t talked about yet. It’s a -generic type parameter, and we’ll cover generics in more detail in Chapter 10. -For now, all you need to know is that `` means that the `Some` variant of -the `Option` enum can hold one piece of data of any type, and that each -concrete type that gets used in place of `T` makes the overall `Option` type -a different type. Here are some examples of using `Option` values to hold -number types and string types: - -``` -let some_number = Some(5); -let some_char = Some('e'); - -let absent_number: Option = None; -``` - -The type of `some_number` is `Option`. The type of `some_char` is -`Option`, which is a different type. Rust can infer these types because -we’ve specified a value inside the `Some` variant. For `absent_number`, Rust -requires us to annotate the overall `Option` type: the compiler can’t infer the -type that the corresponding `Some` variant will hold by looking only at a -`None` value. Here, we tell Rust that we mean for `absent_number` to be of type -`Option`. - -When we have a `Some` value, we know that a value is present and the value is -held within the `Some`. When we have a `None` value, in some sense it means the -same thing as null: we don’t have a valid value. So why is having `Option` -any better than having null? - -In short, because `Option` and `T` (where `T` can be any type) are different -types, the compiler won’t let us use an `Option` value as if it were -definitely a valid value. For example, this code won’t compile, because it’s -trying to add an `i8` to an `Option`: - -``` -let x: i8 = 5; -let y: Option = Some(5); - -let sum = x + y; -``` - -If we run this code, we get an error message like this one: - -``` -error[E0277]: cannot add `Option` to `i8` - --> src/main.rs:5:17 - | -5 | let sum = x + y; - | ^ no implementation for `i8 + Option` - | - = help: the trait `Add>` is not implemented for `i8` -``` - -Intense! In effect, this error message means that Rust doesn’t understand how -to add an `i8` and an `Option`, because they’re different types. When we -have a value of a type like `i8` in Rust, the compiler will ensure that we -always have a valid value. We can proceed confidently without having to check -for null before using that value. Only when we have an `Option` (or -whatever type of value we’re working with) do we have to worry about possibly -not having a value, and the compiler will make sure we handle that case before -using the value. - -In other words, you have to convert an `Option` to a `T` before you can -perform `T` operations with it. Generally, this helps catch one of the most -common issues with null: assuming that something isn’t null when it actually is. - -Eliminating the risk of incorrectly assuming a not-null value helps you to be -more confident in your code. In order to have a value that can possibly be -null, you must explicitly opt in by making the type of that value `Option`. -Then, when you use that value, you are required to explicitly handle the case -when the value is null. Everywhere that a value has a type that isn’t an -`Option`, you *can* safely assume that the value isn’t null. This was a -deliberate design decision for Rust to limit null’s pervasiveness and increase -the safety of Rust code. - -So how do you get the `T` value out of a `Some` variant when you have a value -of type `Option` so that you can use that value? The `Option` enum has a -large number of methods that are useful in a variety of situations; you can -check them out in its documentation. Becoming familiar with the methods on -`Option` will be extremely useful in your journey with Rust. - -In general, in order to use an `Option` value, you want to have code that -will handle each variant. You want some code that will run only when you have a -`Some(T)` value, and this code is allowed to use the inner `T`. You want some -other code to run only if you have a `None` value, and that code doesn’t have a -`T` value available. The `match` expression is a control flow construct that -does just this when used with enums: it will run different code depending on -which variant of the enum it has, and that code can use the data inside the -matching value. - -## The match Control Flow Construct - -Rust has an extremely powerful control flow construct called `match` that -allows you to compare a value against a series of patterns and then execute -code based on which pattern matches. Patterns can be made up of literal values, -variable names, wildcards, and many other things; Chapter 18 covers all the -different kinds of patterns and what they do. The power of `match` comes from -the expressiveness of the patterns and the fact that the compiler confirms that -all possible cases are handled. - -Think of a `match` expression as being like a coin-sorting machine: coins slide -down a track with variously sized holes along it, and each coin falls through -the first hole it encounters that it fits into. In the same way, values go -through each pattern in a `match`, and at the first pattern the value “fits,” -the value falls into the associated code block to be used during execution. - -Speaking of coins, let’s use them as an example using `match`! We can write a -function that takes an unknown US coin and, in a similar way as the counting -machine, determines which coin it is and returns its value in cents, as shown -in Listing 6-3. - -``` -1 enum Coin { - Penny, - Nickel, - Dime, - Quarter, -} - -fn value_in_cents(coin: Coin) -> u8 { - 2 match coin { - 3 Coin::Penny => 1, - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter => 25, - } -} -``` - -Listing 6-3: An enum and a `match` expression that has the variants of the enum -as its patterns - -Let’s break down the `match` in the `value_in_cents` function. First we list -the `match` keyword followed by an expression, which in this case is the value -`coin` [2]. This seems very similar to an expression used with `if`, but -there’s a big difference: with `if`, the expression needs to return a Boolean -value, but here it can return any type. The type of `coin` in this example is -the `Coin` enum that we defined at [1]. - -Next are the `match` arms. An arm has two parts: a pattern and some code. The -first arm here has a pattern that is the value `Coin::Penny` and then the `=>` -operator that separates the pattern and the code to run [3]. The code in this -case is just the value `1`. Each arm is separated from the next with a comma. - -When the `match` expression executes, it compares the resultant value against -the pattern of each arm, in order. If a pattern matches the value, the code -associated with that pattern is executed. If that pattern doesn’t match the -value, execution continues to the next arm, much as in a coin-sorting machine. -We can have as many arms as we need: in Listing 6-3, our `match` has four arms. - -The code associated with each arm is an expression, and the resultant value of -the expression in the matching arm is the value that gets returned for the -entire `match` expression. - -We don’t typically use curly brackets if the match arm code is short, as it is -in Listing 6-3 where each arm just returns a value. If you want to run multiple -lines of code in a match arm, you must use curly brackets, and the comma -following the arm is then optional. For example, the following code prints -“Lucky penny!” every time the method is called with a `Coin::Penny`, but still -returns the last value of the block, `1`: - -``` -fn value_in_cents(coin: Coin) -> u8 { - match coin { - Coin::Penny => { - println!("Lucky penny!"); - 1 - } - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter => 25, - } -} -``` - -### Patterns That Bind to Values - -Another useful feature of match arms is that they can bind to the parts of the -values that match the pattern. This is how we can extract values out of enum -variants. - -As an example, let’s change one of our enum variants to hold data inside it. -From 1999 through 2008, the United States minted quarters with different -designs for each of the 50 states on one side. No other coins got state -designs, so only quarters have this extra value. We can add this information to -our `enum` by changing the `Quarter` variant to include a `UsState` value -stored inside it, which we’ve done in Listing 6-4. - -``` -#[derive(Debug)] // so we can inspect the state in a minute -enum UsState { - Alabama, - Alaska, - --snip-- -} - -enum Coin { - Penny, - Nickel, - Dime, - Quarter(UsState), -} -``` - -Listing 6-4: A `Coin` enum in which the `Quarter` variant also holds a -`UsState` value - -Let’s imagine that a friend is trying to collect all 50 state quarters. While -we sort our loose change by coin type, we’ll also call out the name of the -state associated with each quarter so that if it’s one our friend doesn’t have, -they can add it to their collection. - -In the match expression for this code, we add a variable called `state` to the -pattern that matches values of the variant `Coin::Quarter`. When a -`Coin::Quarter` matches, the `state` variable will bind to the value of that -quarter’s state. Then we can use `state` in the code for that arm, like so: - -``` -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 - } - } -} -``` - -If we were to call `value_in_cents(Coin::Quarter(UsState::Alaska))`, `coin` -would be `Coin::Quarter(UsState::Alaska)`. When we compare that value with each -of the match arms, none of them match until we reach `Coin::Quarter(state)`. At -that point, the binding for `state` will be the value `UsState::Alaska`. We can -then use that binding in the `println!` expression, thus getting the inner -state value out of the `Coin` enum variant for `Quarter`. - -### Matching with Option - -In the previous section, we wanted to get the inner `T` value out of the `Some` -case when using `Option`; we can also handle `Option` using `match`, as -we did with the `Coin` enum! Instead of comparing coins, we’ll compare the -variants of `Option`, but the way the `match` expression works remains the -same. - -Let’s say we want to write a function that takes an `Option` and, if -there’s a value inside, adds 1 to that value. If there isn’t a value inside, -the function should return the `None` value and not attempt to perform any -operations. - -This function is very easy to write, thanks to `match`, and will look like -Listing 6-5. - -``` -fn plus_one(x: Option) -> Option { - match x { - 1 None => None, - 2 Some(i) => Some(i + 1), - } -} - -let five = Some(5); -let six = plus_one(five); 3 -let none = plus_one(None); 4 -``` - -Listing 6-5: A function that uses a `match` expression on an `Option` - -Let’s examine the first execution of `plus_one` in more detail. When we call -`plus_one(five)` [3], the variable `x` in the body of `plus_one` will have the -value `Some(5)`. We then compare that against each match arm: - -``` -None => None, -``` - -The `Some(5)` value doesn’t match the pattern `None` [1], so we continue to the -next arm: - -``` -Some(i) => Some(i + 1), -``` - -Does `Some(5)` match `Some(i)` [2]? Why yes, it does! We have the same variant. -The `i` binds to the value contained in `Some`, so `i` takes the value `5`. The -code in the match arm is then executed, so we add 1 to the value of `i` and -create a new `Some` value with our total `6` inside. - -Now let’s consider the second call of `plus_one` in Listing 6-5, where `x` is -`None` [4]. We enter the `match` and compare to the first arm [1]. - -It matches! There’s no value to add to, so the program stops and returns the -`None` value on the right side of `=>`. Because the first arm matched, no other -arms are compared. - -Combining `match` and enums is useful in many situations. You’ll see this -pattern a lot in Rust code: `match` against an enum, bind a variable to the -data inside, and then execute code based on it. It’s a bit tricky at first, but -once you get used to it, you’ll wish you had it in all languages. It’s -consistently a user favorite. - -### Matches Are Exhaustive - -There’s one other aspect of `match` we need to discuss: the arms’ patterns must -cover all possibilities. Consider this version of our `plus_one` function, -which has a bug and won’t compile: - -``` -fn plus_one(x: Option) -> Option { - match x { - Some(i) => Some(i + 1), - } -} -``` - -We didn’t handle the `None` case, so this code will cause a bug. Luckily, it’s -a bug Rust knows how to catch. If we try to compile this code, we’ll get this -error: - -``` -error[E0004]: non-exhaustive patterns: `None` not covered - --> src/main.rs:3:15 - | -3 | match x { - | ^ pattern `None` not covered - | - note: `Option` defined here - = note: the matched value is of type `Option` -help: ensure that all possible cases are being handled by adding -a match arm with a wildcard pattern or an explicit pattern as -shown - | -4 ~ Some(i) => Some(i + 1), -5 ~ None => todo!(), - | -``` - -Rust knows that we didn’t cover every possible case, and even knows which -pattern we forgot! Matches in Rust are *exhaustive*: we must exhaust every last -possibility in order for the code to be valid. Especially in the case of -`Option`, when Rust prevents us from forgetting to explicitly handle the -`None` case, it protects us from assuming that we have a value when we might -have null, thus making the billion-dollar mistake discussed earlier impossible. - -### Catch-all Patterns and the _ Placeholder - -Using enums, we can also take special actions for a few particular values, but -for all other values take one default action. Imagine we’re implementing a game -where, if you roll a 3 on a dice roll, your player doesn’t move, but instead -gets a new fancy hat. If you roll a 7, your player loses a fancy hat. For all -other values, your player moves that number of spaces on the game board. Here’s -a `match` that implements that logic, with the result of the dice roll -hardcoded rather than a random value, and all other logic represented by -functions without bodies because actually implementing them is out of scope for -this example: - -``` -let dice_roll = 9; -match dice_roll { - 3 => add_fancy_hat(), - 7 => remove_fancy_hat(), - 1 other => move_player(other), -} - -fn add_fancy_hat() {} -fn remove_fancy_hat() {} -fn move_player(num_spaces: u8) {} -``` - -For the first two arms, the patterns are the literal values `3` and `7`. For -the last arm that covers every other possible value, the pattern is the -variable we’ve chosen to name `other` [1]. The code that runs for the `other` -arm uses the variable by passing it to the `move_player` function. - -This code compiles, even though we haven’t listed all the possible values a -`u8` can have, because the last pattern will match all values not specifically -listed. This catch-all pattern meets the requirement that `match` must be -exhaustive. Note that we have to put the catch-all arm last because the -patterns are evaluated in order. If we put the catch-all arm earlier, the other -arms would never run, so Rust will warn us if we add arms after a catch-all! - -Rust also has a pattern we can use when we want a catch-all but don’t want to -*use* the value in the catch-all pattern: `_` is a special pattern that matches -any value and does not bind to that value. This tells Rust we aren’t going to -use the value, so Rust won’t warn us about an unused variable. - -Let’s change the rules of the game: now, if you roll anything other than a 3 or -a 7, you must roll again. We no longer need to use the catch-all value, so we -can change our code to use `_` instead of the variable named `other`: - -``` -let dice_roll = 9; -match dice_roll { - 3 => add_fancy_hat(), - 7 => remove_fancy_hat(), - _ => reroll(), -} - -fn add_fancy_hat() {} -fn remove_fancy_hat() {} -fn reroll() {} -``` - -This example also meets the exhaustiveness requirement because we’re explicitly -ignoring all other values in the last arm; we haven’t forgotten anything. - -Finally, we’ll change the rules of the game one more time so that nothing else -happens on your turn if you roll anything other than a 3 or a 7. We can express -that by using the unit value (the empty tuple type we mentioned in “The Tuple -Type” on page XX) as the code that goes with the `_` arm: - -``` -let dice_roll = 9; -match dice_roll { - 3 => add_fancy_hat(), - 7 => remove_fancy_hat(), - _ => (), -} - -fn add_fancy_hat() {} -fn remove_fancy_hat() {} -``` - -Here, we’re telling Rust explicitly that we aren’t going to use any other value -that doesn’t match a pattern in an earlier arm, and we don’t want to run any -code in this case. - -There’s more about patterns and matching that we’ll cover in Chapter 18. For -now, we’re going to move on to the `if let` syntax, which can be useful in -situations where the `match` expression is a bit wordy. - -## Concise Control Flow with if let - -The `if let` syntax lets you combine `if` and `let` into a less verbose way to -handle values that match one pattern while ignoring the rest. Consider the -program in Listing 6-6 that matches on an `Option` value in the -`config_max` variable but only wants to execute code if the value is the `Some` -variant. - -``` -let config_max = Some(3u8); -match config_max { - Some(max) => println!("The maximum is configured to be {max}"), - _ => (), -} -``` - -Listing 6-6: A `match` that only cares about executing code when the value is -`Some` - -If the value is `Some`, we print out the value in the `Some` variant by binding -the value to the variable `max` in the pattern. We don’t want to do anything -with the `None` value. To satisfy the `match` expression, we have to add `_ => -()` after processing just one variant, which is annoying boilerplate code to -add. - -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: - -``` -let config_max = Some(3u8); -if let Some(max) = config_max { - println!("The maximum is configured to be {max}"); -} -``` - -The syntax `if let` takes a pattern and an expression separated by an equal -sign. It works the same way as a `match`, where the expression is given to the -`match` and the pattern is its first arm. In this case, the pattern is -`Some(max)`, and the `max` binds to the value inside the `Some`. We can then -use `max` in the body of the `if let` block in the same way we used `max` in -the corresponding `match` arm. The code in the `if let` block isn’t run if the -value doesn’t match the pattern. - -Using `if let` means less typing, less indentation, and less boilerplate code. -However, you lose the exhaustive checking that `match` enforces. Choosing -between `match` and `if let` depends on what you’re doing in your particular -situation and whether gaining conciseness is an appropriate trade-off for -losing exhaustive checking. - -In other words, you can think of `if let` as syntax sugar for a `match` that -runs code when the value matches one pattern and then ignores all other values. - -We can include an `else` with an `if let`. The block of code that goes with the -`else` is the same as the block of code that would go with the `_` case in the -`match` expression that is equivalent to the `if let` and `else`. Recall the -`Coin` enum definition in Listing 6-4, where the `Quarter` variant also held a -`UsState` value. If we wanted to count all non-quarter coins we see while also -announcing the state of the quarters, we could do that with a `match` -expression, like this: - -``` -let mut count = 0; -match coin { - Coin::Quarter(state) => println!("State quarter from {:?}!", state), - _ => count += 1, -} -``` - -Or we could use an `if let` and `else` expression, like this: - -``` -let mut count = 0; -if let Coin::Quarter(state) = coin { - println!("State quarter from {:?}!", state); -} else { - count += 1; -} -``` - -If you have a situation in which your program has logic that is too verbose to -express using a `match`, remember that `if let` is in your Rust toolbox as well. - -## Summary - -We’ve now covered how to use enums to create custom types that can be one of a -set of enumerated values. We’ve shown how the standard library’s `Option` -type helps you use the type system to prevent errors. When enum values have -data inside them, you can use `match` or `if let` to extract and use those -values, depending on how many cases you need to handle. - -Your Rust programs can now express concepts in your domain using structs and -enums. Creating custom types to use in your API ensures type safety: the -compiler will make certain your functions only get values of the type each -function expects. - -In order to provide a well-organized API to your users that is straightforward -to use and only exposes exactly what your users will need, let’s now turn to -Rust’s modules. - diff --git a/rustbook-en/nostarch/chapter13.md b/rustbook-en/nostarch/chapter13.md deleted file mode 100644 index 52c1f5f97..000000000 --- a/rustbook-en/nostarch/chapter13.md +++ /dev/null @@ -1,1273 +0,0 @@ - - -[TOC] - -# Functional Language Features: Iterators and Closures - -Rust’s design has taken inspiration from many existing languages and -techniques, and one significant influence is *functional programming*. -Programming in a functional style often includes using functions as values by -passing them in arguments, returning them from other functions, assigning them -to variables for later execution, and so forth. - -In this chapter, we won’t debate the issue of what functional programming is or -isn’t but will instead discuss some features of Rust that are similar to -features in many languages often referred to as functional. - -More specifically, we’ll cover: - -* *Closures*, a function-like construct you can store in a variable -* *Iterators*, a way of processing a series of elements -* How to use closures and iterators to improve the I/O project in Chapter 12 -* The performance of closures and iterators (spoiler alert: they’re faster than -you might think!) - -We’ve already covered some other Rust features, such as pattern matching and -enums, that are also influenced by the functional style. Because mastering -closures and iterators is an important part of writing idiomatic, fast Rust -code, we’ll devote this entire chapter to them. - -## Closures: Anonymous Functions That Capture Their Environment - -Rust’s closures are anonymous functions you can save in a variable or pass as -arguments to other functions. You can create the closure in one place and then -call the closure elsewhere to evaluate it in a different context. Unlike -functions, closures can capture values from the scope in which they’re defined. -We’ll demonstrate how these closure features allow for code reuse and behavior -customization. - -### Capturing the Environment with Closures - -We’ll first examine how we can use closures to capture values from the -environment they’re defined in for later use. Here’s the scenario: every so -often, our T-shirt company gives away an exclusive, limited-edition shirt to -someone on our mailing list as a promotion. People on the mailing list can -optionally add their favorite color to their profile. If the person chosen for -a free shirt has their favorite color set, they get that color shirt. If the -person hasn’t specified a favorite color, they get whatever color the company -currently has the most of. - -There are many ways to implement this. For this example, we’re going to use an -enum called `ShirtColor` that has the variants `Red` and `Blue` (limiting the -number of colors available for simplicity). We represent the company’s -inventory with an `Inventory` struct that has a field named `shirts` that -contains a `Vec` representing the shirt colors currently in stock. -The method `giveaway` defined on `Inventory` gets the optional shirt color -preference of the free-shirt winner, and returns the shirt color the person -will get. This setup is shown in Listing 13-1. - -Filename: src/main.rs - -``` -#[derive(Debug, PartialEq, Copy, Clone)] -enum ShirtColor { - Red, - Blue, -} - -struct Inventory { - shirts: Vec, -} - -impl Inventory { - fn giveaway( - &self, - user_preference: Option, - ) -> ShirtColor { - 1 user_preference.unwrap_or_else(|| self.most_stocked()) - } - - fn most_stocked(&self) -> ShirtColor { - let mut num_red = 0; - let mut num_blue = 0; - - for color in &self.shirts { - match color { - ShirtColor::Red => num_red += 1, - ShirtColor::Blue => num_blue += 1, - } - } - if num_red > num_blue { - ShirtColor::Red - } else { - ShirtColor::Blue - } - } -} - -fn main() { - let store = Inventory { - 2 shirts: vec![ - ShirtColor::Blue, - ShirtColor::Red, - ShirtColor::Blue, - ], - }; - - let user_pref1 = Some(ShirtColor::Red); - 3 let giveaway1 = store.giveaway(user_pref1); - println!( - "The user with preference {:?} gets {:?}", - user_pref1, giveaway1 - ); - - let user_pref2 = None; - 4 let giveaway2 = store.giveaway(user_pref2); - println!( - "The user with preference {:?} gets {:?}", - user_pref2, giveaway2 - ); -} -``` - -Listing 13-1: Shirt company giveaway situation - -The `store` defined in `main` has two blue shirts and one red shirt remaining -to distribute for this limited-edition promotion [2]. We call the `giveaway` -method for a user with a preference for a red shirt [3] and a user without any -preference [4]. - -Again, this code could be implemented in many ways, and here, to focus on -closures, we’ve stuck to concepts you’ve already learned, except for the body -of the `giveaway` method that uses a closure. In the `giveaway` method, we get -the user preference as a parameter of type `Option` and call the -`unwrap_or_else` method on `user_preference` [1]. The `unwrap_or_else` method -on `Option` is defined by the standard library. It takes one argument: a -closure without any arguments that returns a value `T` (the same type stored in -the `Some` variant of the `Option`, in this case `ShirtColor`). If the -`Option` is the `Some` variant, `unwrap_or_else` returns the value from -within the `Some`. If the `Option` is the `None` variant, `unwrap_or_else` -calls the closure and returns the value returned by the closure. - -We specify the closure expression `|| self.most_stocked()` as the argument to -`unwrap_or_else`. This is a closure that takes no parameters itself (if the -closure had parameters, they would appear between the two vertical pipes). The -body of the closure calls `self.most_stocked()`. We’re defining the closure -here, and the implementation of `unwrap_or_else` will evaluate the closure -later if the result is needed. - -Running this code prints the following: - -``` -The user with preference Some(Red) gets Red -The user with preference None gets Blue -``` - -One interesting aspect here is that we’ve passed a closure that calls -`self.most_stocked()` on the current `Inventory` instance. The standard library -didn’t need to know anything about the `Inventory` or `ShirtColor` types we -defined, or the logic we want to use in this scenario. The closure captures an -immutable reference to the `self` `Inventory` instance and passes it with the -code we specify to the `unwrap_or_else` method. Functions, on the other hand, -are not able to capture their environment in this way. - -### Closure Type Inference and Annotation - -There are more differences between functions and closures. Closures don’t -usually require you to annotate the types of the parameters or the return value -like `fn` functions do. Type annotations are required on functions because the -types are part of an explicit interface exposed to your users. Defining this -interface rigidly is important for ensuring that everyone agrees on what types -of values a function uses and returns. Closures, on the other hand, aren’t used -in an exposed interface like this: they’re stored in variables and used without -naming them and exposing them to users of our library. - -Closures are typically short and relevant only within a narrow context rather -than in any arbitrary scenario. Within these limited contexts, the compiler can -infer the types of the parameters and the return type, similar to how it’s able -to infer the types of most variables (there are rare cases where the compiler -needs closure type annotations too). - -As with variables, we can add type annotations if we want to increase -explicitness and clarity at the cost of being more verbose than is strictly -necessary. Annotating the types for a closure would look like the definition -shown in Listing 13-2. In this example, we’re defining a closure and storing it -in a variable rather than defining the closure in the spot we pass it as an -argument, as we did in Listing 13-1. - -Filename: src/main.rs - -``` -let expensive_closure = |num: u32| -> u32 { - println!("calculating slowly..."); - thread::sleep(Duration::from_secs(2)); - num -}; -``` - -Listing 13-2: Adding optional type annotations of the parameter and return -value types in the closure - -With type annotations added, the syntax of closures looks more similar to the -syntax of functions. Here, we define a function that adds 1 to its parameter -and a closure that has the same behavior, for comparison. We’ve added some -spaces to line up the relevant parts. This illustrates how closure syntax is -similar to function syntax except for the use of pipes and the amount of syntax -that is optional: - -``` -fn add_one_v1 (x: u32) -> u32 { x + 1 } -let add_one_v2 = |x: u32| -> u32 { x + 1 }; -let add_one_v3 = |x| { x + 1 }; -let add_one_v4 = |x| x + 1 ; -``` - -The first line shows a function definition and the second line shows a fully -annotated closure definition. In the third line, we remove the type annotations -from the closure definition. In the fourth line, we remove the curly brackets, -which are optional because the closure body has only one expression. These are -all valid definitions that will produce the same behavior when they’re called. -The `add_one_v3` and `add_one_v4` lines require the closures to be evaluated to -be able to compile because the types will be inferred from their usage. This is -similar to `let v = Vec::new();` needing either type annotations or values of -some type to be inserted into the `Vec` for Rust to be able to infer the type. - -For closure definitions, the compiler will infer one concrete type for each of -their parameters and for their return value. For instance, Listing 13-3 shows -the definition of a short closure that just returns the value it receives as a -parameter. This closure isn’t very useful except for the purposes of this -example. Note that we haven’t added any type annotations to the definition. -Because there are no type annotations, we can call the closure with any type, -which we’ve done here with `String` the first time. If we then try to call -`example_closure` with an integer, we’ll get an error. - -Filename: src/main.rs - -``` -let example_closure = |x| x; - -let s = example_closure(String::from("hello")); -let n = example_closure(5); -``` - -Listing 13-3: Attempting to call a closure whose types are inferred with two -different types - -The compiler gives us this error: - -``` -error[E0308]: mismatched types - --> src/main.rs:5:29 - | -5 | let n = example_closure(5); - | ^- help: try using a conversion method: -`.to_string()` - | | - | expected struct `String`, found integer -``` - -The first time we call `example_closure` with the `String` value, the compiler -infers the type of `x` and the return type of the closure to be `String`. Those -types are then locked into the closure in `example_closure`, and we get a type -error when we next try to use a different type with the same closure. - -### Capturing References or Moving Ownership - -Closures can capture values from their environment in three ways, which -directly map to the three ways a function can take a parameter: borrowing -immutably, borrowing mutably, and taking ownership. The closure will decide -which of these to use based on what the body of the function does with the -captured values. - -In Listing 13-4, we define a closure that captures an immutable reference to -the vector named `list` because it only needs an immutable reference to print -the value. - -Filename: src/main.rs - -``` -fn main() { - let list = vec![1, 2, 3]; - println!("Before defining closure: {:?}", list); - - 1 let only_borrows = || println!("From closure: {:?}", list); - - println!("Before calling closure: {:?}", list); - 2 only_borrows(); - println!("After calling closure: {:?}", list); -} -``` - -Listing 13-4: Defining and calling a closure that captures an immutable -reference - -This example also illustrates that a variable can bind to a closure definition -[1], and we can later call the closure by using the variable name and -parentheses as if the variable name were a function name [2]. - -Because we can have multiple immutable references to `list` at the same time, -`list` is still accessible from the code before the closure definition, after -the closure definition but before the closure is called, and after the closure -is called. This code compiles, runs, and prints: - -``` -Before defining closure: [1, 2, 3] -Before calling closure: [1, 2, 3] -From closure: [1, 2, 3] -After calling closure: [1, 2, 3] -``` - -Next, in Listing 13-5, we change the closure body so that it adds an element to -the `list` vector. The closure now captures a mutable reference. - -Filename: src/main.rs - -``` -fn main() { - let mut list = vec![1, 2, 3]; - println!("Before defining closure: {:?}", list); - - let mut borrows_mutably = || list.push(7); - - borrows_mutably(); - println!("After calling closure: {:?}", list); -} -``` - -Listing 13-5: Defining and calling a closure that captures a mutable reference - -This code compiles, runs, and prints: - -``` -Before defining closure: [1, 2, 3] -After calling closure: [1, 2, 3, 7] -``` - -Note that there’s no longer a `println!` between the definition and the call of -the `borrows_mutably` closure: when `borrows_mutably` is defined, it captures a -mutable reference to `list`. We don’t use the closure again after the closure -is called, so the mutable borrow ends. Between the closure definition and the -closure call, an immutable borrow to print isn’t allowed because no other -borrows are allowed when there’s a mutable borrow. Try adding a `println!` -there to see what error message you get! - -If you want to force the closure to take ownership of the values it uses in the -environment even though the body of the closure doesn’t strictly need -ownership, you can use the `move` keyword before the parameter list. - -This technique is mostly useful when passing a closure to a new thread to move -the data so that it’s owned by the new thread. We’ll discuss threads and why -you would want to use them in detail in Chapter 16 when we talk about -concurrency, but for now, let’s briefly explore spawning a new thread using a -closure that needs the `move` keyword. Listing 13-6 shows Listing 13-4 modified -to print the vector in a new thread rather than in the main thread. - -Filename: src/main.rs - -``` -use std::thread; - -fn main() { - let list = vec![1, 2, 3]; - println!("Before defining closure: {:?}", list); - - 1 thread::spawn(move || { - 2 println!("From thread: {:?}", list) - }).join().unwrap(); -} -``` - -Listing 13-6: Using `move` to force the closure for the thread to take -ownership of `list` - -We spawn a new thread, giving the thread a closure to run as an argument. The -closure body prints out the list. In Listing 13-4, the closure only captured -`list` using an immutable reference because that’s the least amount of access -to `list` needed to print it. In this example, even though the closure body -still only needs an immutable reference [2], we need to specify that `list` -should be moved into the closure by putting the `move` keyword [1] at the -beginning of the closure definition. The new thread might finish before the -rest of the main thread finishes, or the main thread might finish first. If the -main thread maintains ownership of `list` but ends before the new thread and -drops `list`, the immutable reference in the thread would be invalid. -Therefore, the compiler requires that `list` be moved into the closure given to -the new thread so the reference will be valid. Try removing the `move` keyword -or using `list` in the main thread after the closure is defined to see what -compiler errors you get! - -### Moving Captured Values Out of Closures and the Fn Traits - -Once a closure has captured a reference or captured ownership of a value from -the environment where the closure is defined (thus affecting what, if anything, -is moved *into* the closure), the code in the body of the closure defines what -happens to the references or values when the closure is evaluated later (thus -affecting what, if anything, is moved *out of* the closure). - -A closure body can do any of the following: move a captured value out of the -closure, mutate the captured value, neither move nor mutate the value, or -capture nothing from the environment to begin with. - -The way a closure captures and handles values from the environment affects -which traits the closure implements, and traits are how functions and structs -can specify what kinds of closures they can use. Closures will automatically -implement one, two, or all three of these `Fn` traits, in an additive fashion, -depending on how the closure’s body handles the values: - -* `FnOnce` applies to closures that can be called once. All closures implement -at least this trait because all closures can be called. A closure that moves -captured values out of its body will only implement `FnOnce` and none of the -other `Fn` traits because it can only be called once. -* `FnMut` applies to closures that don’t move captured values out of their -body, but that might mutate the captured values. These closures can be called -more than once. -* `Fn` applies to closures that don’t move captured values out of their body -and that don’t mutate captured values, as well as closures that capture nothing -from their environment. These closures can be called more than once without -mutating their environment, which is important in cases such as calling a -closure multiple times concurrently. - -Let’s look at the definition of the `unwrap_or_else` method on `Option` that -we used in Listing 13-1: - -``` -impl Option { - pub fn unwrap_or_else(self, f: F) -> T - where - F: FnOnce() -> T - { - match self { - Some(x) => x, - None => f(), - } - } -} -``` - -Recall that `T` is the generic type representing the type of the value in the -`Some` variant of an `Option`. That type `T` is also the return type of the -`unwrap_or_else` function: code that calls `unwrap_or_else` on an -`Option`, for example, will get a `String`. - -Next, notice that the `unwrap_or_else` function has the additional generic type -parameter `F`. The `F` type is the type of the parameter named `f`, which is -the closure we provide when calling `unwrap_or_else`. - -The trait bound specified on the generic type `F` is `FnOnce() -> T`, which -means `F` must be able to be called once, take no arguments, and return a `T`. -Using `FnOnce` in the trait bound expresses the constraint that -`unwrap_or_else` is only going to call `f` one time, at most. In the body of -`unwrap_or_else`, we can see that if the `Option` is `Some`, `f` won’t be -called. If the `Option` is `None`, `f` will be called once. Because all -closures implement `FnOnce`, `unwrap_or_else` accepts the largest variety of -closures and is as flexible as it can be. - -> Note: Functions can implement all three of the `Fn` traits too. If what we -want to do doesn’t require capturing a value from the environment, we can use -the name of a function rather than a closure where we need something that -implements one of the `Fn` traits. For example, on an `Option>` value, -we could call `unwrap_or_else(Vec::new)` to get a new, empty vector if the -value is `None`. - -Now let’s look at the standard library method `sort_by_key`, defined on slices, -to see how that differs from `unwrap_or_else` and why `sort_by_key` uses -`FnMut` instead of `FnOnce` for the trait bound. The closure gets one argument -in the form of a reference to the current item in the slice being considered, -and returns a value of type `K` that can be ordered. This function is useful -when you want to sort a slice by a particular attribute of each item. In -Listing 13-7, we have a list of `Rectangle` instances and we use `sort_by_key` -to order them by their `width` attribute from low to high. - -Filename: src/main.rs - -``` -#[derive(Debug)] -struct Rectangle { - width: u32, - height: u32, -} - -fn main() { - let mut list = [ - Rectangle { width: 10, height: 1 }, - Rectangle { width: 3, height: 5 }, - Rectangle { width: 7, height: 12 }, - ]; - - list.sort_by_key(|r| r.width); - println!("{:#?}", list); -} -``` - -Listing 13-7: Using `sort_by_key` to order rectangles by width - -This code prints: - -``` -[ - Rectangle { - width: 3, - height: 5, - }, - Rectangle { - width: 7, - height: 12, - }, - Rectangle { - width: 10, - height: 1, - }, -] -``` - -The reason `sort_by_key` is defined to take an `FnMut` closure is that it calls -the closure multiple times: once for each item in the slice. The closure `|r| -r.width` doesn’t capture, mutate, or move anything out from its environment, so -it meets the trait bound requirements. - -In contrast, Listing 13-8 shows an example of a closure that implements just -the `FnOnce` trait, because it moves a value out of the environment. The -compiler won’t let us use this closure with `sort_by_key`. - -Filename: src/main.rs - -``` ---snip-- - -fn main() { - let mut list = [ - Rectangle { width: 10, height: 1 }, - Rectangle { width: 3, height: 5 }, - Rectangle { width: 7, height: 12 }, - ]; - - let mut sort_operations = vec![]; - let value = String::from("by key called"); - - list.sort_by_key(|r| { - sort_operations.push(value); - r.width - }); - println!("{:#?}", list); -} -``` - -Listing 13-8: Attempting to use an `FnOnce` closure with `sort_by_key` - -This is a contrived, convoluted way (that doesn’t work) to try and count the -number of times `sort_by_key` gets called when sorting `list`. This code -attempts to do this counting by pushing `value`—a `String` from the closure’s -environment—into the `sort_operations` vector. The closure captures `value` and -then moves `value` out of the closure by transferring ownership of `value` to -the `sort_operations` vector. This closure can be called once; trying to call -it a second time wouldn’t work because `value` would no longer be in the -environment to be pushed into `sort_operations` again! Therefore, this closure -only implements `FnOnce`. When we try to compile this code, we get this error -that `value` can’t be moved out of the closure because the closure must -implement `FnMut`: - -``` -error[E0507]: cannot move out of `value`, a captured variable in an `FnMut` -closure - --> src/main.rs:18:30 - | -15 | let value = String::from("by key called"); - | ----- captured outer variable -16 | -17 | list.sort_by_key(|r| { - | ______________________- -18 | | sort_operations.push(value); - | | ^^^^^ move occurs because `value` has -type `String`, which does not implement the `Copy` trait -19 | | r.width -20 | | }); - | |_____- captured by this `FnMut` closure -``` - -The error points to the line in the closure body that moves `value` out of the -environment. To fix this, we need to change the closure body so that it doesn’t -move values out of the environment. Keeping a counter in the environment and -incrementing its value in the closure body is a more straightforward way to -count the number of times `sort_by_key` is called. The closure in Listing 13-9 -works with `sort_by_key` because it is only capturing a mutable reference to -the `num_sort_operations` counter and can therefore be called more than once. - -Filename: src/main.rs - -``` ---snip-- - -fn main() { - --snip-- - - let mut num_sort_operations = 0; - list.sort_by_key(|r| { - num_sort_operations += 1; - r.width - }); - println!( - "{:#?}, sorted in {num_sort_operations} operations", - list - ); -} -``` - -Listing 13-9: Using an `FnMut` closure with `sort_by_key` is allowed. - -The `Fn` traits are important when defining or using functions or types that -make use of closures. In the next section, we’ll discuss iterators. Many -iterator methods take closure arguments, so keep these closure details in mind -as we continue! - -## Processing a Series of Items with Iterators - -The iterator pattern allows you to perform some task on a sequence of items in -turn. An iterator is responsible for the logic of iterating over each item and -determining when the sequence has finished. When you use iterators, you don’t -have to reimplement that logic yourself. - -In Rust, iterators are *lazy*, meaning they have no effect until you call -methods that consume the iterator to use it up. For example, the code in -Listing 13-10 creates an iterator over the items in the vector `v1` by calling -the `iter` method defined on `Vec`. This code by itself doesn’t do anything -useful. - -``` -let v1 = vec![1, 2, 3]; - -let v1_iter = v1.iter(); -``` - -Listing 13-10: Creating an iterator - -The iterator is stored in the `v1_iter` variable. Once we’ve created an -iterator, we can use it in a variety of ways. In Listing 3-5, we iterated over -an array using a `for` loop to execute some code on each of its items. Under -the hood, this implicitly created and then consumed an iterator, but we glossed -over how exactly that works until now. - -In the example in Listing 13-11, we separate the creation of the iterator from -the use of the iterator in the `for` loop. When the `for` loop is 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. - -``` -let v1 = vec![1, 2, 3]; - -let v1_iter = v1.iter(); - -for val in v1_iter { - println!("Got: {val}"); -} -``` - -Listing 13-11: Using an iterator in a `for` loop - -In languages that don’t have iterators provided by their standard libraries, -you would likely write this same functionality by starting a variable at index -0, using that variable to index into the vector to get a value, and -incrementing the variable value in a loop until it reached the total number of -items in the vector. - -Iterators handle all of that logic for you, cutting down on repetitive code you -could potentially mess up. Iterators give you more flexibility to use the same -logic with many different kinds of sequences, not just data structures you can -index into, like vectors. Let’s examine how iterators do that. - -### The Iterator Trait and the next Method - -All iterators implement a trait named `Iterator` that is defined in the -standard library. The definition of the trait looks like this: - -``` -pub trait Iterator { - type Item; - - fn next(&mut self) -> Option; - - // methods with default implementations elided -} -``` - -Notice that this definition uses some new syntax: `type Item` and `Self::Item`, -which are defining an *associated type* with this trait. We’ll talk about -associated types in depth in Chapter 19. For now, all you need to know is that -this code says implementing the `Iterator` trait requires that you also define -an `Item` type, and this `Item` type is used in the return type of the `next` -method. In other words, the `Item` type will be the type returned from the -iterator. - -The `Iterator` trait only requires implementors to define one method: the -`next` method, which returns one item of the iterator at a time, wrapped in -`Some`, and, when iteration is over, returns `None`. - -We can call the `next` method on iterators directly; Listing 13-12 demonstrates -what values are returned from repeated calls to `next` on the iterator created -from the vector. - -Filename: src/lib.rs - -``` -#[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); -} -``` - -Listing 13-12: Calling the `next` method on an iterator - -Note that we needed to make `v1_iter` mutable: calling the `next` method on an -iterator changes internal state that the iterator uses to keep track of where -it is in the sequence. In other words, this code *consumes*, or uses up, the -iterator. Each call to `next` eats up an item from the iterator. We didn’t need -to make `v1_iter` mutable when we used a `for` loop because the loop took -ownership of `v1_iter` and made it mutable behind the scenes. - -Also note that the values we get from the calls to `next` are immutable -references to the values in the vector. The `iter` method produces an iterator -over immutable references. If we want to create an iterator that takes -ownership of `v1` and returns owned values, we can call `into_iter` instead of -`iter`. Similarly, if we want to iterate over mutable references, we can call -`iter_mut` instead of `iter`. - -### Methods That Consume the Iterator - -The `Iterator` trait has a number of different methods with default -implementations provided by the standard library; you can find out about these -methods by looking in the standard library API documentation for the `Iterator` -trait. Some of these methods call the `next` method in their definition, which -is why you’re required to implement the `next` method when implementing the -`Iterator` trait. - -Methods that call `next` are called *consuming adapters* because calling them -uses up the iterator. One example is the `sum` method, which takes ownership of -the iterator and iterates through the items by repeatedly calling `next`, thus -consuming the iterator. As it iterates through, it adds each item to a running -total and returns the total when iteration is complete. Listing 13-13 has a -test illustrating a use of the `sum` method. - -Filename: src/lib.rs - -``` -#[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); -} -``` - -Listing 13-13: Calling the `sum` method to get the total of all items in the -iterator - -We aren’t allowed to use `v1_iter` after the call to `sum` because `sum` takes -ownership of the iterator we call it on. - -### Methods That Produce Other Iterators - -*Iterator adapters* are methods defined on the `Iterator` trait that don’t -consume the iterator. Instead, they produce different iterators by changing -some aspect of the original iterator. - -Listing 13-14 shows an example of calling the iterator adapter method `map`, -which takes a closure to call on each item as the items are iterated through. -The `map` method returns a new iterator that produces the modified items. The -closure here creates a new iterator in which each item from the vector will be -incremented by 1. - -Filename: src/main.rs - -``` -let v1: Vec = vec![1, 2, 3]; - -v1.iter().map(|x| x + 1); -``` - -Listing 13-14: Calling the iterator adapter `map` to create a new iterator - -However, this code produces a warning: - -``` -warning: unused `Map` that must be used - --> src/main.rs:4:5 - | -4 | v1.iter().map(|x| x + 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(unused_must_use)]` on by default - = note: iterators are lazy and do nothing unless consumed -``` - -The code in Listing 13-14 doesn’t do anything; the closure we’ve specified -never gets called. The warning reminds us why: iterator adapters are lazy, and -we need to consume the iterator here. - -To fix this warning and consume the iterator, we’ll use the `collect` method, -which we used with `env::args` in Listing 12-1. This method consumes the -iterator and collects the resultant values into a collection data type. - -In Listing 13-15, we collect into a vector the results of iterating over the -iterator that’s returned from the call to `map`. This vector will end up -containing each item from the original vector, incremented by 1. - -Filename: src/main.rs - -``` -let v1: Vec = vec![1, 2, 3]; - -let v2: Vec<_> = v1.iter().map(|x| x + 1).collect(); - -assert_eq!(v2, vec![2, 3, 4]); -``` - -Listing 13-15: Calling the `map` method to create a new iterator, and then -calling the `collect` method to consume the new iterator and create a vector - -Because `map` takes a closure, we can specify any operation we want to perform -on each item. This is a great example of how closures let you customize some -behavior while reusing the iteration behavior that the `Iterator` trait -provides. - -You can chain multiple calls to iterator adapters to perform complex actions in -a readable way. But because all iterators are lazy, you have to call one of the -consuming adapter methods to get results from calls to iterator adapters. - -### Using Closures That Capture Their Environment - -Many iterator adapters take closures as arguments, and commonly the closures -we’ll specify as arguments to iterator adapters will be closures that capture -their environment. - -For this example, we’ll use the `filter` method that takes a closure. The -closure gets an item from the iterator and returns a `bool`. If the closure -returns `true`, the value will be included in the iteration produced by -`filter`. If the closure returns `false`, the value won’t be included. - -In Listing 13-16, we use `filter` with a closure that captures the `shoe_size` -variable from its environment to iterate over a collection of `Shoe` struct -instances. It will return only shoes that are the specified size. - -Filename: src/lib.rs - -``` -#[derive(PartialEq, Debug)] -struct Shoe { - size: u32, - style: String, -} - -fn shoes_in_size(shoes: Vec, shoe_size: u32) -> Vec { - shoes.into_iter().filter(|s| s.size == shoe_size).collect() -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn filters_by_size() { - let shoes = vec![ - Shoe { - size: 10, - style: String::from("sneaker"), - }, - Shoe { - size: 13, - style: String::from("sandal"), - }, - Shoe { - size: 10, - style: String::from("boot"), - }, - ]; - - let in_my_size = shoes_in_size(shoes, 10); - - assert_eq!( - in_my_size, - vec![ - Shoe { - size: 10, - style: String::from("sneaker") - }, - Shoe { - size: 10, - style: String::from("boot") - }, - ] - ); - } -} -``` - -Listing 13-16: Using the `filter` method with a closure that captures -`shoe_size` - -The `shoes_in_size` function takes ownership of a vector of shoes and a shoe -size as parameters. It returns a vector containing only shoes of the specified -size. - -In the body of `shoes_in_size`, we call `into_iter` to create an iterator that -takes ownership of the vector. Then we call `filter` to adapt that iterator -into a new iterator that only contains elements for which the closure returns -`true`. - -The closure captures the `shoe_size` parameter from the environment and -compares the value with each shoe’s size, keeping only shoes of the size -specified. Finally, calling `collect` gathers the values returned by the -adapted iterator into a vector that’s returned by the function. - -The test shows that when we call `shoes_in_size`, we get back only shoes that -have the same size as the value we specified. - -## Improving Our I/O Project - -With this new knowledge about iterators, we can improve the I/O project in -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::build` 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 -an instance of the `Config` struct by indexing into the slice and cloning the -values, allowing the `Config` struct to own those values. In Listing 13-17, -we’ve reproduced the implementation of the `Config::build` function as it was -in Listing 12-23. - -Filename: src/lib.rs - -``` -impl Config { - pub fn build( - args: &[String] - ) -> Result { - if args.len() < 3 { - return Err("not enough arguments"); - } - - let query = args[1].clone(); - let file_path = args[2].clone(); - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} -``` - -Listing 13-17: Reproduction of the `Config::build` function from Listing 12-23 - -At the time, we said not to worry about the inefficient `clone` calls because -we would remove them in the future. Well, that time is now! - -We needed `clone` here because we have a slice with `String` elements in the -parameter `args`, but the `build` function doesn’t own `args`. To return -ownership of a `Config` instance, we had to clone the values from the `query` -and `filename` fields of `Config` so the `Config` instance can own its values. - -With our new knowledge about iterators, we can change the `build` function to -take ownership of an iterator as its argument instead of borrowing a slice. -We’ll use the iterator functionality instead of the code that checks the length -of the slice and indexes into specific locations. This will clarify what the -`Config::build` function is doing because the iterator will access the values. - -Once `Config::build` takes ownership of the iterator and stops using indexing -operations that borrow, we can move the `String` values from the iterator into -`Config` rather than calling `clone` and making a new allocation. - -#### Using the Returned Iterator Directly - -Open your I/O project’s *src/main.rs* file, which should look like this: - -Filename: src/main.rs - -``` -fn main() { - let args: Vec = env::args().collect(); - - let config = Config::build(&args).unwrap_or_else(|err| { - eprintln!("Problem parsing arguments: {err}"); - process::exit(1); - }); - - --snip-- -} -``` - -We’ll first change the start of the `main` function that we had in Listing -12-24 to the code in Listing 13-18, which this time uses an iterator. This -won’t compile until we update `Config::build` as well. - -Filename: src/main.rs - -``` -fn main() { - let config = - Config::build(env::args()).unwrap_or_else(|err| { - eprintln!("Problem parsing arguments: {err}"); - process::exit(1); - }); - - --snip-- -} -``` - -Listing 13-18: Passing the return value of `env::args` to `Config::build` - -The `env::args` function returns an iterator! Rather than collecting the -iterator values into a vector and then passing a slice to `Config::build`, now -we’re passing ownership of the iterator returned from `env::args` to -`Config::build` directly. - -Next, we need to update the definition of `Config::build`. In your I/O -project’s *src/lib.rs* file, let’s change the signature of `Config::build` to -look like Listing 13-19. This still won’t compile, because we need to update -the function body. - -Filename: src/lib.rs - -``` -impl Config { - pub fn build( - mut args: impl Iterator, - ) -> Result { - --snip-- -``` - -Listing 13-19: Updating the signature of `Config::build` to expect an iterator - -The standard library documentation for the `env::args` function shows that the -type of the iterator it returns is `std::env::Args`, and that type implements -the `Iterator` trait and returns `String` values. - -We’ve updated the signature of the `Config::build` function so the parameter -`args` has a generic type with the trait bounds `impl Iterator` -instead of `&[String]`. This usage of the `impl Trait` syntax we discussed in -“Traits as Parameters” on page XX means that `args` can be any type that -implements the `Iterator` type and returns `String` items. - -Because we’re taking ownership of `args` and we’ll be mutating `args` by -iterating over it, we can add the `mut` keyword into the specification of the -`args` parameter to make it mutable. - -#### Using Iterator Trait Methods Instead of Indexing - -Next, we’ll fix the body of `Config::build`. Because `args` implements the -`Iterator` trait, we know we can call the `next` method on it! Listing 13-20 -updates the code from Listing 12-23 to use the `next` method. - -Filename: src/lib.rs - -``` -impl Config { - pub fn build( - mut args: impl Iterator, - ) -> Result { - args.next(); - - let query = match args.next() { - Some(arg) => arg, - None => return Err("Didn't get a query string"), - }; - - let file_path = match args.next() { - Some(arg) => arg, - None => return Err("Didn't get a file path"), - }; - - let ignore_case = env::var("IGNORE_CASE").is_ok(); - - Ok(Config { - query, - file_path, - ignore_case, - }) - } -} -``` - -Listing 13-20: Changing the body of `Config::build` to use iterator methods - -Remember that the first value in the return value of `env::args` is the name of -the program. We want to ignore that and get to the next value, so first we call -`next` and do nothing with the return value. Then we call `next` to get the -value we want to put in the `query` field of `Config`. If `next` returns -`Some`, we use a `match` to extract the value. If it returns `None`, it means -not enough arguments were given and we return early with an `Err` value. We do -the same thing for the `filename` value. - -### Making Code Clearer with Iterator Adapters - -We can also take advantage of iterators in the `search` function in our I/O -project, which is reproduced here in Listing 13-21 as it was in Listing 12-19. - -Filename: src/lib.rs - -``` -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 -} -``` - -Listing 13-21: The implementation of the `search` function from Listing 12-19 - -We can write this code in a more concise way using iterator adapter methods. -Doing so also lets us avoid having a mutable intermediate `results` vector. The -functional programming style prefers to minimize the amount of mutable state to -make code clearer. Removing the mutable state might enable a future enhancement -to make searching happen in parallel because we wouldn’t have to manage -concurrent access to the `results` vector. Listing 13-22 shows this change. - -Filename: src/lib.rs - -``` -pub fn search<'a>( - query: &str, - contents: &'a str, -) -> Vec<&'a str> { - contents - .lines() - .filter(|line| line.contains(query)) - .collect() -} -``` - -Listing 13-22: Using iterator adapter methods in the implementation of the -`search` function - -Recall that the purpose of the `search` function is to return all lines in -`contents` that contain the `query`. Similar to the `filter` example in Listing -13-16, this code uses the `filter` adapter to keep only the lines for which -`line.contains(query)` returns `true`. We then collect the matching lines into -another vector with `collect`. Much simpler! Feel free to make the same change -to use iterator methods in the `search_case_insensitive` function as well. - -### Choosing Between Loops and Iterators - -The next logical question is which style you should choose in your own code and -why: the original implementation in Listing 13-21 or the version using -iterators in Listing 13-22. Most Rust programmers prefer to use the iterator -style. It’s a bit tougher to get the hang of at first, but once you get a feel -for the various iterator adapters and what they do, iterators can be easier to -understand. Instead of fiddling with the various bits of looping and building -new vectors, the code focuses on the high-level objective of the loop. This -abstracts away some of the commonplace code so it’s easier to see the concepts -that are unique to this code, such as the filtering condition each element in -the iterator must pass. - -But are the two implementations truly equivalent? The intuitive assumption -might be that the lower-level loop will be faster. Let’s talk about performance. - -## Comparing Performance: Loops vs. Iterators - -To determine whether to use loops or iterators, you need to know which -implementation is faster: the version of the `search` function with an explicit -`for` loop or the version with iterators. - -We ran a benchmark by loading the entire contents of *The Adventures of -Sherlock Holmes* by Sir Arthur Conan Doyle into a `String` and looking for the -word *the* in the contents. Here are the results of the benchmark on the -version of `search` using the `for` loop and the version using iterators: - -``` -test bench_search_for ... bench: 19,620,300 ns/iter (+/- 915,700) -test bench_search_iter ... bench: 19,234,900 ns/iter (+/- 657,200) -``` - -The iterator version was slightly faster! We won’t explain the benchmark code -here because the point is not to prove that the two versions are equivalent but -to get a general sense of how these two implementations compare -performance-wise. - -For a more comprehensive benchmark, you should check using various texts of -various sizes as the `contents`, different words and words of different lengths -as the `query`, and all kinds of other variations. The point is this: -iterators, although a high-level abstraction, get compiled down to roughly the -same code as if you’d written the lower-level code yourself. Iterators are one -of Rust’s *zero-cost abstractions*, by which we mean that using the abstraction -imposes no additional runtime overhead. This is analogous to how Bjarne -Stroustrup, the original designer and implementor of C++, defines -*zero-overhead* in “Foundations of C++” (2012): - -> In general, C++ implementations obey the zero-overhead principle: What you -don’t use, you don’t pay for. And further: What you do use, you couldn’t hand -code any better.As another example, the following code is taken from an audio -decoder. The decoding algorithm uses the linear prediction mathematical -operation to estimate future values based on a linear function of the previous -samples. This code uses an iterator chain to do some math on three variables in -scope: a `buffer` slice of data, an array of 12 `coefficients`, and an amount -by which to shift data in `qlp_shift`. We’ve declared the variables within this -example but not given them any values; although this code doesn’t have much -meaning outside of its context, it’s still a concise, real-world example of how -Rust translates high-level ideas to low-level code. - -``` -let buffer: &mut [i32]; -let coefficients: [i64; 12]; -let qlp_shift: i16; - -for i in 12..buffer.len() { - let prediction = coefficients.iter() - .zip(&buffer[i - 12..i]) - .map(|(&c, &s)| c * s as i64) - .sum::() >> qlp_shift; - let delta = buffer[i]; - buffer[i] = prediction as i32 + delta; -} -``` - -To calculate the value of `prediction`, this code iterates through each of the -12 values in `coefficients` and uses the `zip` method to pair the coefficient -values with the previous 12 values in `buffer`. Then, for each pair, it -multiplies the values together, sums all the results, and shifts the bits in -the sum `qlp_shift` bits to the right. - -Calculations in applications like audio decoders often prioritize performance -most highly. Here, we’re creating an iterator, using two adapters, and then -consuming the value. What assembly code would this Rust code compile to? Well, -as of this writing, it compiles down to the same assembly you’d write by hand. -There’s no loop at all corresponding to the iteration over the values in -`coefficients`: Rust knows that there are 12 iterations, so it “unrolls” the -loop. *Unrolling* is an optimization that removes the overhead of the loop -controlling code and instead generates repetitive code for each iteration of -the loop. - -All of the coefficients get stored in registers, which means accessing the -values is very fast. There are no bounds checks on the array access at runtime. -All of these optimizations that Rust is able to apply make the resultant code -extremely efficient. Now that you know this, you can use iterators and closures -without fear! They make code seem like it’s higher level but don’t impose a -runtime performance penalty for doing so. - -## Summary - -Closures and iterators are Rust features inspired by functional programming -language ideas. They contribute to Rust’s capability to clearly express -high-level ideas at low-level performance. The implementations of closures and -iterators are such that runtime performance is not affected. This is part of -Rust’s goal to strive to provide zero-cost abstractions. - -Now that we’ve improved the expressiveness of our I/O project, let’s look at -some more features of `cargo` that will help us share the project with the -world. - diff --git a/rustbook-en/nostarch/chapter14.md b/rustbook-en/nostarch/chapter14.md deleted file mode 100644 index f5f2be719..000000000 --- a/rustbook-en/nostarch/chapter14.md +++ /dev/null @@ -1,999 +0,0 @@ - - -[TOC] - -# More About Cargo and Crates.io - -So far, we’ve used only the most basic features of Cargo to build, run, and -test our code, but it can do a lot more. In this chapter, we’ll discuss some of -its other, more advanced features to show you how to do the following: - -* Customize your build through release profiles. -* Publish libraries on *https://crates.i**o*. -* Organize large projects with workspaces. -* Install binaries from *https://crates.io*. -* Extend Cargo using custom commands. - -Cargo can do even more than the functionality we cover in this chapter, so for -a full explanation of all its features, see its documentation at -*https://doc.rust-lang.org/cargo*. - -## Customizing Builds with Release Profiles - -In Rust, *release profiles* are predefined and customizable profiles with -different configurations that allow a programmer to have more control over -various options for compiling code. Each profile is configured independently of -the others. - -Cargo has two main profiles: the `dev` profile Cargo uses when you run `cargo -build`, and the `release` profile Cargo uses when you run `cargo build ---release`. The `dev` profile is defined with good defaults for development, -and the `release` profile has good defaults for release builds. - -These profile names might be familiar from the output of your builds: - -``` -$ cargo build - Finished dev [unoptimized + debuginfo] target(s) in 0.0s -$ cargo build --release - Finished release [optimized] target(s) in 0.0s -``` - -The `dev` and `release` are these different profiles used by the compiler. - -Cargo has default settings for each of the profiles that apply when you haven’t -explicitly added any `[profile.*]` sections in the project’s *Cargo.toml* file. -By adding `[profile.*]` sections for any profile you want to customize, you -override any subset of the default settings. For example, here are the default -values for the `opt-level` setting for the `dev` and `release` profiles: - -Filename: Cargo.toml - -``` -[profile.dev] -opt-level = 0 - -[profile.release] -opt-level = 3 -``` - -The `opt-level` setting controls the number of optimizations Rust will apply to -your code, with a range of 0 to 3. Applying more optimizations extends -compiling time, so if you’re in development and compiling your code often, -you’ll want fewer optimizations to compile faster even if the resultant code -runs slower. The default `opt-level` for `dev` is therefore `0`. When you’re -ready to release your code, it’s best to spend more time compiling. You’ll only -compile in release mode once, but you’ll run the compiled program many times, -so release mode trades longer compile time for code that runs faster. That is -why the default `opt-level` for the `release` profile is `3`. - -You can override a default setting by adding a different value for it in -*Cargo.toml*. For example, if we want to use optimization level 1 in the -development profile, we can add these two lines to our project’s *Cargo.toml* -file: - -Filename: Cargo.toml - -``` -[profile.dev] -opt-level = 1 -``` - -This code overrides the default setting of `0`. Now when we run `cargo build`, -Cargo will use the defaults for the `dev` profile plus our customization to -`opt-level`. Because we set `opt-level` to `1`, Cargo will apply more -optimizations than the default, but not as many as in a release build. - -For the full list of configuration options and defaults for each profile, see -Cargo’s documentation at -*https://doc.rust-lang.org/cargo/reference/profiles.html*. - -## Publishing a Crate to Crates.io - -We’ve used packages from *https://crates.io* as dependencies of our project, -but you can also share your code with other people by publishing your own -packages. The crate registry at *https://crates.io* distributes the source code -of your packages, so it primarily hosts code that is open source. - -Rust and Cargo have features that make your published package easier for people -to find and use. We’ll talk about some of these features next and then explain -how to publish a package. - -### Making Useful Documentation Comments - -Accurately documenting your packages will help other users know how and when to -use them, so it’s worth investing the time to write documentation. In Chapter -3, we discussed how to comment Rust code using two slashes, `//`. Rust also has -a particular kind of comment for documentation, known conveniently as a -*documentation comment*, that will generate HTML documentation. The HTML -displays the contents of documentation comments for public API items intended -for programmers interested in knowing how to *use* your crate as opposed to how -your crate is *implemented*. - -Documentation comments use three slashes, `///`, instead of two and support -Markdown notation for formatting the text. Place documentation comments just -before the item they’re documenting. Listing 14-1 shows documentation comments -for an `add_one` function in a crate named `my_crate`. - -Filename: src/lib.rs - -``` -/// 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 -} -``` - -Listing 14-1: A documentation comment for a function - -Here, we give a description of what the `add_one` function does, start a -section with the heading `Examples`, and then provide code that demonstrates -how to use the `add_one` function. We can generate the HTML documentation from -this documentation comment by running `cargo doc`. This command runs the -`rustdoc` tool distributed with Rust and puts the generated HTML documentation -in the *target/doc* directory. - -For convenience, running `cargo doc --open` will build the HTML for your -current crate’s documentation (as well as the documentation for all of your -crate’s dependencies) and open the result in a web browser. Navigate to the -`add_one` function and you’ll see how the text in the documentation comments is -rendered, as shown in Figure 14-1. - -Figure 14-1: HTML documentation for the `add_one` function - -#### Commonly Used Sections - -We used the `# Examples` Markdown heading in Listing 14-1 to create a section -in the HTML with the title “Examples.” Here are some other sections that crate -authors commonly use in their documentation: - -* **Panics**: The scenarios in which the function being documented could panic. -Callers of the function who don’t want their programs to panic should make sure -they don’t call the function in these situations. -* **Errors**: If the function returns a `Result`, describing the kinds of -errors that might occur and what conditions might cause those errors to be -returned can be helpful to callers so they can write code to handle the -different kinds of errors in different ways. -* **Safety**: If the function is `unsafe` to call (we discuss unsafety in -Chapter 19), there should be a section explaining why the function is unsafe -and covering the invariants that the function expects callers to uphold. - -Most documentation comments don’t need all of these sections, but this is a -good checklist to remind you of the aspects of your code users will be -interested in knowing about. - -#### Documentation Comments as Tests - -Adding example code blocks in your documentation comments can help demonstrate -how to use your library, and doing so has an additional bonus: running `cargo -test` will run the code examples in your documentation as tests! Nothing is -better than documentation with examples. But nothing is worse than examples -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 that -looks like this: - -``` - Doc-tests my_crate - -running 1 test -test src/lib.rs - add_one (line 5) ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 -filtered out; finished in 0.27s -``` - -Now, if we change either the function or the example so the `assert_eq!` in the -example panics and run `cargo test` again, we’ll see that the doc tests catch -that the example and the code are out of sync with each other! - -#### Commenting Contained Items - -The doc comment `//!` adds documentation to the item that *contains* the -comments rather than to the items *following* the comments. We typically use -these doc comments inside the crate root file (*src/lib.rs* by convention) or -inside a module to document the crate or the module as a whole. - -For example, to add documentation that describes the purpose of the `my_crate` -crate that contains the `add_one` function, we add documentation comments that -start with `//!` to the beginning of the *src/lib.rs* file, as shown in Listing -14-2. - -Filename: src/lib.rs - -``` -//! # My Crate -//! -//! `my_crate` is a collection of utilities to make performing -//! certain calculations more convenient. - -/// Adds one to the number given. ---snip-- -``` - -Listing 14-2: Documentation for the `my_crate` crate as a whole - -Notice there isn’t any code after the last line that begins with `//!`. Because -we started the comments with `//!` instead of `///`, we’re documenting the item -that contains this comment rather than an item that follows this comment. In -this case, that item is the *src/lib.rs* file, which is the crate root. These -comments describe the entire crate. - -When we run `cargo doc --open`, these comments will display on the front page -of the documentation for `my_crate` above the list of public items in the -crate, as shown in Figure 14-2. - -Figure 14-2: Rendered documentation for `my_crate`, including the comment -describing the crate as a whole - -Documentation comments within items are useful for describing crates and -modules especially. Use them to explain the overall purpose of the container to -help your users understand the crate’s organization. - -### Exporting a Convenient Public API with pub use - -The structure of your public API is a major consideration when publishing a -crate. People who use your crate are less familiar with the structure than you -are and might have difficulty finding the pieces they want to use if your crate -has a large module hierarchy. - -In Chapter 7, we covered how to make items public using the `pub` keyword, and -how to bring items into a scope with the `use` keyword. However, the structure -that makes sense to you while you’re developing a crate might not be very -convenient for your users. You might want to organize your structs in a -hierarchy containing multiple levels, but then people who want to use a type -you’ve defined deep in the hierarchy might have trouble finding out that type -exists. They might also be annoyed at having to enter `use` -`my_crate::`some_module`::`another_module`::`UsefulType`;` rather than `use` -`my_crate::`UsefulType`;`. - -The good news is that if the structure *isn’t* convenient for others to use -from another library, you don’t have to rearrange your internal organization: -instead, you can re-export items to make a public structure that’s different -from your private structure by using `pub use`. *Re-exporting* takes a public -item in one location and makes it public in another location, as if it were -defined in the other location instead. - -For example, say we made a library named `art` for modeling artistic concepts. -Within this library are two modules: a `kinds` module containing two enums -named `PrimaryColor` and `SecondaryColor` and a `utils` module containing a -function named `mix`, as shown in Listing 14-3. - -Filename: src/lib.rs - -``` -//! # 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-- - } -} -``` - -Listing 14-3: An `art` library with items organized into `kinds` and `utils` -modules - -Figure 14-3 shows what the front page of the documentation for this crate -generated by `cargo doc` would look like. - -Figure 14-3: Front page of the documentation for `art` that lists the `kinds` -and `utils` modules - -Note that the `PrimaryColor` and `SecondaryColor` types aren’t listed on the -front page, nor is the `mix` function. We have to click `kinds` and `utils` to -see them. - -Another crate that depends on this library would need `use` statements that -bring the items from `art` into scope, specifying the module structure that’s -currently defined. Listing 14-4 shows an example of a crate that uses the -`PrimaryColor` and `mix` items from the `art` crate. - -Filename: src/main.rs - -``` -use art::kinds::PrimaryColor; -use art::utils::mix; - -fn main() { - let red = PrimaryColor::Red; - let yellow = PrimaryColor::Yellow; - mix(red, yellow); -} -``` - -Listing 14-4: A crate using the `art` crate’s items with its internal structure -exported - -The author of the code in Listing 14-4, which uses the `art` crate, had to -figure out that `PrimaryColor` is in the `kinds` module and `mix` is in the -`utils` module. The module structure of the `art` crate is more relevant to -developers working on the `art` crate than to those using it. The internal -structure doesn’t contain any useful information for someone trying to -understand how to use the `art` crate, but rather causes confusion because -developers who use it have to figure out where to look, and must specify the -module names in the `use` statements. - -To remove the internal organization from the public API, we can modify the -`art` crate code in Listing 14-3 to add `pub use` statements to re-export the -items at the top level, as shown in Listing 14-5. - -Filename: src/lib.rs - -``` -//! # 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-- -} -``` - -Listing 14-5: Adding `pub use` statements to re-export items - -The API documentation that `cargo doc` generates for this crate will now list -and link re-exports on the front page, as shown in Figure 14-4, making the -`PrimaryColor` and `SecondaryColor` types and the `mix` function easier to find. - -Figure 14-4: The front page of the documentation for `art` that lists the -re-exports - -The `art` crate users can still see and use the internal structure from Listing -14-3 as demonstrated in Listing 14-4, or they can use the more convenient -structure in Listing 14-5, as shown in Listing 14-6. - -Filename: src/main.rs - -``` -use art::mix; -use art::PrimaryColor; - -fn main() { - --snip-- -} -``` - -Listing 14-6: A program using the re-exported items from the `art` crate - -In cases where there are many nested modules, re-exporting the types at the top -level with `pub use` can make a significant difference in the experience of -people who use the crate. Another common use of `pub use` is to re-export -definitions of a dependency in the current crate to make that crate’s -definitions part of your crate’s public API. - -Creating a useful public API structure is more of an art than a science, and -you can iterate to find the API that works best for your users. Choosing `pub -use` gives you flexibility in how you structure your crate internally and -decouples that internal structure from what you present to your users. Look at -some of the code of crates you’ve installed to see if their internal structure -differs from their public API. - -### Setting Up a Crates.io Account - -Before you can publish any crates, you need to create an account on -*https://crates.io* and get an API token. To do so, visit the home page at -*https://crates.io* and log in via a GitHub account. (The GitHub account is -currently a requirement, but the site might support other ways of creating an -account in the future.) Once you’re logged in, visit your account settings at -*https://crates.io/me* and retrieve your API key. Then run the `cargo login` -command with your API key, like this: - -``` -$ cargo login abcdefghijklmnopqrstuvwxyz012345 -``` - -This command will inform Cargo of your API token and store it locally in -*~/.cargo/credentials*. Note that this token is a *secret*: do not share it -with anyone else. If you do share it with anyone for any reason, you should -revoke it and generate a new token on *https://crates.io*. - -### Adding Metadata to a New Crate - -Let’s say you have a crate you want to publish. Before publishing, you’ll need -to add some metadata in the `[package]` section of the crate’s *Cargo.toml* -file. - -Your crate will need a unique name. While you’re working on a crate locally, -you can name a crate whatever you’d like. However, crate names on -*https://crates.io* are allocated on a first-come, first-served basis. Once a -crate name is taken, no one else can publish a crate with that name. Before -attempting to publish a crate, search for the name you want to use. If the name -has been used, you will need to find another name and edit the `name` field in -the *Cargo.toml* file under the `[package]` section to use the new name for -publishing, like so: - -Filename: Cargo.toml - -``` -[package] -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: - -``` -$ cargo publish - 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: failed to publish to registry at https://crates.io - -Caused by: - the remote server responded with an error: missing or empty metadata fields: -description, license. Please see https://doc.rust- -lang.org/cargo/reference/manifest.html for how to upload metadata -``` - -This results in an error because you’re missing some crucial information: a -description and license are required so people will know what your crate does -and under what terms they can use it. In *Cargo.toml*, add a description that’s -just a sentence or two, because it will appear with your crate in search -results. For the `license` field, you need to give a *license identifier -value*. The Linux Foundation’s Software Package Data Exchange (SPDX) at -*http://spdx.org/licenses* lists the identifiers you can use for this value. -For example, to specify that you’ve licensed your crate using the MIT License, -add the `MIT` identifier: - -Filename: Cargo.toml - -``` -[package] -name = "guessing_game" -license = "MIT" -``` - -If you want to use a license that doesn’t appear in the SPDX, you need to place -the text of that license in a file, include the file in your project, and then -use `license-file` to specify the name of that file instead of using the -`license` key. - -Guidance on which license is appropriate for your project is beyond the scope -of this book. Many people in the Rust community license their projects in the -same way as Rust by using a dual license of `MIT OR Apache-2.0`. This practice -demonstrates that you can also specify multiple license identifiers separated -by `OR` to have multiple licenses for your project. - -With a unique name, the version, your description, and a license added, the -*Cargo.toml* file for a project that is ready to publish might look like this: - -Filename: Cargo.toml - -``` -[package] -name = "guessing_game" -version = "0.1.0" -edition = "2021" -description = "A fun game where you guess what number the -computer has chosen." -license = "MIT OR Apache-2.0" - -[dependencies] -``` - -Cargo’s documentation at *https://doc.rust-lang.org/cargo* describes other -metadata you can specify to ensure that others can discover and use your crate -more easily. - -### Publishing to Crates.io - -Now that you’ve created an account, saved your API token, chosen a name for -your crate, and specified the required metadata, you’re ready to publish! -Publishing a crate uploads a specific version to *https://crates.io* for others -to use. - -Be careful, because a publish is *permanent*. The version can never be -overwritten, and the code cannot be deleted. One major goal of Crates.io is to -act as a permanent archive of code so that builds of all projects that depend -on crates from *https://crates.io* will continue to work. Allowing version -deletions would make fulfilling that goal impossible. However, there is no -limit to the number of crate versions you can publish. - -Run the `cargo publish` command again. It should succeed now: - -``` -$ cargo publish - 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.19s - Uploading guessing_game v0.1.0 (file:///projects/guessing_game) -``` - -Congratulations! You’ve now shared your code with the Rust community, and -anyone can easily add your crate as a dependency of their project. - -### Publishing a New Version of an Existing Crate - -When you’ve made changes to your crate and are ready to release a new version, -you change the `version` value specified in your *Cargo.toml* file and -republish. Use the Semantic Versioning rules at *http://semver.org* to decide -what an appropriate next version number is, based on the kinds of changes -you’ve made. Then run `cargo publish` to upload the new version. - -### Deprecating Versions from Crates.io with cargo yank - -Although you can’t remove previous versions of a crate, you can prevent any -future projects from adding them as a new dependency. This is useful when a -crate version is broken for one reason or another. In such situations, Cargo -supports yanking a crate version. - -*Yanking* a version prevents new projects from depending on that version while -allowing all existing projects that depend on it to continue. Essentially, a -yank means that all projects with a *Cargo.lock* will not break, and any future -*Cargo.lock* files generated will not use the yanked version. - -To yank a version of a crate, in the directory of the crate that you’ve -previously published, run `cargo yank` and specify which version you want to -yank. For example, if we’ve published a crate named `guessing_game` version -1.0.1 and we want to yank it, in the project directory for `guessing_game` we’d -run: - -``` -$ cargo yank --vers 1.0.1 - Updating crates.io index - Yank guessing_game@1.0.1 -``` - -By adding `--undo` to the command, you can also undo a yank and allow projects -to start depending on a version again: - -``` -$ cargo yank --vers 1.0.1 --undo - Updating crates.io index - Unyank guessing_game@1.0.1 -``` - -A yank *does not* delete any code. It cannot, for example, delete accidentally -uploaded secrets. If that happens, you must reset those secrets immediately. - -## Cargo Workspaces - -In Chapter 12, we built a package that included a binary crate and a library -crate. As your project develops, you might find that the library crate -continues to get bigger and you want to split your package further into -multiple library crates. Cargo offers a feature called *workspaces* that can -help manage multiple related packages that are developed in tandem. - -### Creating a Workspace - -A *workspace* is a set of packages that share the same *Cargo.lock* and output -directory. Let’s make a project using a workspace—we’ll use trivial code so we -can concentrate on the structure of the workspace. There are multiple ways to -structure a workspace, so we’ll just show one common way. We’ll have a -workspace containing a binary and two libraries. The binary, which will provide -the main functionality, will depend on the two libraries. One library will -provide an `add_one` function and the other library an `add_two` function. -These three crates will be part of the same workspace. We’ll start by creating -a new directory for the workspace: - -``` -$ mkdir add -$ cd add -``` - -Next, in the *add* directory, we create the *Cargo.toml* file that will -configure the entire workspace. This file won’t have a `[package]` section. -Instead, it will start with a `[workspace]` section that will allow us to add -members to the workspace by specifying the path to the package with our binary -crate; in this case, that path is *adder*: - -Filename: Cargo.toml - -``` -[workspace] - -members = [ - "adder", -] -``` - -Next, we’ll create the `adder` binary crate by running `cargo new` within the -*add* directory: - -``` -$ cargo new adder - Created binary (application) `adder` package -``` - -At this point, we can build the workspace by running `cargo build`. The files -in your *add* directory should look like this: - -``` -├── Cargo.lock -├── Cargo.toml -├── adder -│ ├── Cargo.toml -│ └── src -│ └── main.rs -└── target -``` - -The workspace has one *target* directory at the top level that the compiled -artifacts will be placed into; the `adder` package doesn’t have its own -*target* directory. Even if we were to run `cargo build` from inside the -*adder* directory, the compiled artifacts would still end up in *add/target* -rather than *add/adder/target*. Cargo structures the *target* directory in a -workspace like this because the crates in a workspace are meant to depend on -each other. If each crate had its own *target* directory, each crate would have -to recompile each of the other crates in the workspace to place the artifacts -in its own *target* directory. By sharing one *target* directory, the crates -can avoid unnecessary rebuilding. - -### Creating the Second Package in the Workspace - -Next, let’s create another member package in the workspace and call it -`add_one`. Change the top-level *Cargo.toml* to specify the *add_one* path in -the `members` list: - -Filename: Cargo.toml - -``` -[workspace] - -members = [ - "adder", - "add_one", -] -``` - -Then generate a new library crate named `add_one`: - -``` -$ cargo new add_one --lib - Created library `add_one` package -``` - -Your *add* directory should now have these directories and files: - -``` -├── Cargo.lock -├── Cargo.toml -├── add_one -│ ├── Cargo.toml -│ └── src -│ └── lib.rs -├── adder -│ ├── Cargo.toml -│ └── src -│ └── main.rs -└── target -``` - -In the *add_one/src/lib.rs* file, let’s add an `add_one` function: - -Filename: add_one/src/lib.rs - -``` -pub fn add_one(x: i32) -> i32 { - x + 1 -} -``` - -Now we can have the `adder` package with our binary depend on the `add_one` -package that has our library. First we’ll need to add a path dependency on -`add_one` to *adder/Cargo.toml*: - -Filename: adder/Cargo.toml - -``` -[dependencies] -add_one = { path = "../add_one" } -``` - -Cargo doesn’t assume that crates in a workspace will depend on each other, so -we need to be explicit about the dependency relationships. - -Next, let’s use the `add_one` function (from the `add_one` crate) in the -`adder` crate. Open the *adder/src/main.rs* file and add a `use` line at the -top to bring the new `add_one` library crate into scope. Then change the `main` -function to call the `add_one` function, as in Listing 14-7. - -Filename: adder/src/main.rs - -``` -use add_one; - -fn main() { - let num = 10; - println!( - "Hello, world! {num} plus one is {}!", - add_one::add_one(num) - ); -} -``` - -Listing 14-7: Using the `add_one` library crate from the `adder` crate - -Let’s build the workspace by running `cargo build` in the top-level *add* -directory! - -``` -$ 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.68s -``` - -To run the binary crate from the *add* directory, we can specify which package -in the workspace we want to run by using the `-p` argument and the package name -with `cargo run`: - -``` -$ cargo run -p adder - Finished dev [unoptimized + debuginfo] target(s) in 0.0s - Running `target/debug/adder` -Hello, world! 10 plus one is 11! -``` - -This runs the code in *adder/src/main.rs*, which depends on the `add_one` crate. - -#### Depending on an External Package in a Workspace - -Notice that the workspace has only one *Cargo.lock* file at the top level, -rather than having a *Cargo.lock* in each crate’s directory. This ensures that -all crates are using the same version of all dependencies. If we add the `rand` -package to the *adder/Cargo.toml* and *add_one/Cargo.toml* files, Cargo will -resolve both of those to one version of `rand` and record that in the one -*Cargo.lock*. Making all crates in the workspace use the same dependencies -means the crates will always be compatible with each other. Let’s add the -`rand` crate to the `[dependencies]` section in the *add_one/Cargo.toml* file -so we can use the `rand` crate in the `add_one` crate: - -Filename: add_one/Cargo.toml - -``` -[dependencies] -rand = "0.8.5" -``` - -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. We will get one warning because we aren’t -referring to the `rand` we brought into scope: - -``` -$ cargo build - Updating crates.io index - Downloaded rand v0.8.5 - --snip-- - Compiling rand v0.8.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.18s -``` - -The top-level *Cargo.lock* now contains information about the dependency of -`add_one` on `rand`. However, even though `rand` is used somewhere in the -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` package, we’ll get an error: - -``` -$ cargo build - --snip-- - Compiling adder v0.1.0 (file:///projects/add/adder) -error[E0432]: unresolved import `rand` - --> adder/src/main.rs:2:5 - | -2 | use rand; - | ^^^^ no external crate `rand` -``` - -To fix this, edit the *Cargo.toml* file for the `adder` package and indicate -that `rand` is a dependency for it as well. Building the `adder` package will -add `rand` to the list of dependencies for `adder` in *Cargo.lock*, but no -additional copies of `rand` will be downloaded. Cargo has ensured that every -crate in every package in the workspace using the `rand` package will be using -the same version, saving us space and ensuring that the crates in the workspace -will be compatible with each other. - -#### Adding a Test to a Workspace - -For another enhancement, let’s add a test of the `add_one::add_one` function -within the `add_one` crate: - -Filename: add_one/src/lib.rs - -``` -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)); - } -} -``` - -Now run `cargo test` in the top-level *add* directory. Running `cargo test` in -a workspace structured like this one will run the tests for all the crates in -the workspace: - -``` -$ cargo test - Compiling add_one v0.1.0 (file:///projects/add/add_one) - Compiling adder v0.1.0 (file:///projects/add/adder) - Finished test [unoptimized + debuginfo] target(s) in 0.27s - Running unittests src/lib.rs (target/debug/deps/add_one-f0253159197f7841) - -running 1 test -test tests::it_works ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; -finished in 0.00s - - Running unittests src/main.rs (target/debug/deps/adder-49979ff40686fa8e) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; -finished in 0.00s - - Doc-tests add_one - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; -finished in 0.00s -``` - -The first section of the output shows that the `it_works` test in the `add_one` -crate passed. The next section shows that zero tests were found in the `adder` -crate, and then the last section shows zero documentation tests were found in -the `add_one` crate. - -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: - -``` -$ cargo test -p add_one - Finished test [unoptimized + debuginfo] target(s) in 0.00s - Running unittests src/lib.rs (target/debug/deps/add_one-b3235fea9a156f74) - -running 1 test -test tests::it_works ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; -finished in 0.00s - - Doc-tests add_one - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; -finished in 0.00s -``` - -This output shows `cargo test` only ran the tests for the `add_one` crate and -didn’t run the `adder` crate tests. - -If you publish the crates in the workspace to *https://crates.io*, each crate -in the workspace will need to be published separately. Like `cargo test`, we -can publish a particular crate in our workspace by using the `-p` flag and -specifying the name of the crate we want to publish. - -For additional practice, add an `add_two` crate to this workspace in a similar -way as the `add_one` crate! - -As your project grows, consider using a workspace: it provides -easier-to-understand, smaller, individual components than one big blob of code. -Furthermore, keeping the crates in a workspace can make coordination between -crates easier if they are often changed at the same time. - -## Installing Binaries with cargo install - -The `cargo install` command allows you to install and use binary crates -locally. This isn’t intended to replace system packages; it’s meant to be a -convenient way for Rust developers to install tools that others have shared on -*https://crates.io*. Note that you can only install packages that have binary -targets. A *binary target* is the runnable program that is created if the crate -has a *src/main.rs* file or another file specified as a binary, as opposed to a -library target that isn’t runnable on its own but is suitable for including -within other programs. Usually, crates have information in the *README* file -about whether a crate is a library, has a binary target, or both. - -All binaries installed with `cargo install` are stored in the installation -root’s *bin* folder. If you installed Rust using *rustup.rs* and don’t have any -custom configurations, this directory will be *$HOME/.cargo/bin*. Ensure that -directory is in your `$PATH` to be able to run programs you’ve installed with -`cargo install`. - -For example, in Chapter 12 we mentioned that there’s a Rust implementation of -the `grep` tool called `ripgrep` for searching files. To install `ripgrep`, we -can run the following: - -``` -$ cargo install ripgrep - Updating crates.io index - Downloaded ripgrep v13.0.0 - Downloaded 1 crate (243.3 KB) in 0.88s - Installing ripgrep v13.0.0 - --snip-- - Compiling ripgrep v13.0.0 - Finished release [optimized + debuginfo] target(s) in 3m 10s - Installing ~/.cargo/bin/rg - Installed package `ripgrep v13.0.0` (executable `rg`) -``` - -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! - -## Extending Cargo with Custom Commands - -Cargo is designed so you can extend it with new subcommands without having to -modify it. If a binary in your `$PATH` is named `cargo-something`, you can run -it as if it were a Cargo subcommand by running `cargo something`. Custom -commands like this are also listed when you run `cargo --list`. Being able to -use `cargo install` to install extensions and then run them just like the -built-in Cargo tools is a super-convenient benefit of Cargo’s design! - -## Summary - -Sharing code with Cargo and *https://crates.io* is part of what makes the Rust -ecosystem useful for many different tasks. Rust’s standard library is small and -stable, but crates are easy to share, use, and improve on a timeline different -from that of the language. Don’t be shy about sharing code that’s useful to you -on *https://crates.io*; it’s likely that it will be useful to someone else as -well! - diff --git a/rustbook-en/nostarch/chapter15.md b/rustbook-en/nostarch/chapter15.md deleted file mode 100644 index c0e847da1..000000000 --- a/rustbook-en/nostarch/chapter15.md +++ /dev/null @@ -1,2080 +0,0 @@ - - -[TOC] - -# Smart Pointers - -A *pointer* is a general concept for a variable that contains an address in -memory. This address refers to, or “points at,” some other data. The most -common kind of pointer in Rust is a reference, which you learned about in -Chapter 4. References are indicated by the `&` symbol and borrow the value they -point to. They don’t have any special capabilities other than referring to -data, and they have no overhead. - -*Smart pointers*, on the other hand, are data structures that act like a -pointer but also have additional metadata and capabilities. The concept of -smart pointers isn’t unique to Rust: smart pointers originated in C++ and exist -in other languages as well. Rust has a variety of smart pointers defined in the -standard library that provide functionality beyond that provided by references. -To explore the general concept, we’ll look at a couple of different examples of -smart pointers, including a *reference counting* smart pointer type. This -pointer enables you to allow data to have multiple owners by keeping track of -the number of owners and, when no owners remain, cleaning up the data. - -Rust, with its concept of ownership and borrowing, has an additional difference -between references and smart pointers: while references only borrow data, in -many cases smart pointers *own* the data they point to. - -Though we didn’t call them as such at the time, we’ve already encountered a few -smart pointers in this book, including `String` and `Vec` in Chapter 8. Both -of these types count as smart pointers because they own some memory and allow -you to manipulate it. They also have metadata and extra capabilities or -guarantees. `String`, for example, stores its capacity as metadata and has the -extra ability to ensure its data will always be valid UTF-8. - -Smart pointers are usually implemented using structs. Unlike an ordinary -struct, smart pointers implement the `Deref` and `Drop` traits. The `Deref` -trait allows an instance of the smart pointer struct to behave like a reference -so you can write your code to work with either references or smart pointers. -The `Drop` trait allows you to customize the code that’s run when an instance -of the smart pointer goes out of scope. In this chapter, we’ll discuss both -traits and demonstrate why they’re important to smart pointers. - -Given that the smart pointer pattern is a general design pattern used -frequently in Rust, this chapter won’t cover every existing smart pointer. Many -libraries have their own smart pointers, and you can even write your own. We’ll -cover the most common smart pointers in the standard library: - -* `Box`, for allocating values on the heap -* `Rc`, a reference counting type that enables multiple ownership -* `Ref` and `RefMut`, accessed through `RefCell`, a type that enforces -the borrowing rules at runtime instead of compile time - -In addition, we’ll cover the *interior mutability* pattern where an immutable -type exposes an API for mutating an interior value. We’ll also discuss -*reference cycles*: how they can leak memory and how to prevent them. - -Let’s dive in! - -## Using Box to Point to Data on the Heap - -The most straightforward smart pointer is a *box*, whose type is written -`Box`. Boxes allow you to store data on the heap rather than the stack. What -remains on the stack is the pointer to the heap data. Refer to Chapter 4 to -review the difference between the stack and the heap. - -Boxes don’t have performance overhead, other than storing their data on the -heap instead of on the stack. But they don’t have many extra capabilities -either. You’ll use them most often in these situations: - -* When you have a type whose size can’t be known at compile time and you want -to use a value of that type in a context that requires an exact size -* When you have a large amount of data and you want to transfer ownership but -ensure the data won’t be copied when you do so -* When you want to own a value and you care only that it’s a type that -implements a particular trait rather than being of a specific type - -We’ll demonstrate the first situation in “Enabling Recursive Types with Boxes” -on page XX. In the second case, transferring ownership of a large amount of -data can take a long time because the data is copied around on the stack. To -improve performance in this situation, we can store the large amount of data on -the heap in a box. Then, only the small amount of pointer data is copied around -on the stack, while the data it references stays in one place on the heap. The -third case is known as a *trait object*, and “Using Trait Objects That Allow -for Values of Different Types” on page XX is devoted to that topic. So what you -learn here you’ll apply again in that section! - -### Using Box to Store Data on the Heap - -Before we discuss the heap storage use case for `Box`, we’ll cover the -syntax and how to interact with values stored within a `Box`. - -Listing 15-1 shows how to use a box to store an `i32` value on the heap. - -Filename: src/main.rs - -``` -fn main() { - let b = Box::new(5); - println!("b = {b}"); -} -``` - -Listing 15-1: Storing an `i32` value on the heap using a box - -We define the variable `b` to have the value of a `Box` that points to the -value `5`, which is allocated on the heap. This program will print `b = 5`; in -this case, we can access the data in the box similar to how we would if this -data were on the stack. Just like any owned value, when a box goes out of -scope, as `b` does at the end of `main`, it will be deallocated. The -deallocation happens both for the box (stored on the stack) and the data it -points to (stored on the heap). - -Putting a single value on the heap isn’t very useful, so you won’t use boxes by -themselves in this way very often. Having values like a single `i32` on the -stack, where they’re stored by default, is more appropriate in the majority of -situations. Let’s look at a case where boxes allow us to define types that we -wouldn’t be allowed to define if we didn’t have boxes. - -### Enabling Recursive Types with Boxes - -A value of a *recursive type* can have another value of the same type as part -of itself. Recursive types pose an issue because at compile time Rust needs to -know how much space a type takes up. However, the nesting of values of -recursive types could theoretically continue infinitely, so Rust can’t know how -much space the value needs. Because boxes have a known size, we can enable -recursive types by inserting a box in the recursive type definition. - -As an example of a recursive type, let’s explore the *cons list*. This is a -data type commonly found in functional programming languages. The cons list -type we’ll define is straightforward except for the recursion; therefore, the -concepts in the example we’ll work with will be useful any time you get into -more complex situations involving recursive types. - -#### More Information About the Cons List - -A *cons list* is a data structure that comes from the Lisp programming language -and its dialects, is made up of nested pairs, and is the Lisp version of a -linked list. Its name comes from the `cons` function (short for *construct -function*) in Lisp that constructs a new pair from its two arguments. By -calling `cons` on a pair consisting of a value and another pair, we can -construct cons lists made up of recursive pairs. - -For example, here’s a pseudocode representation of a cons list containing the -list `1, 2, 3` with each pair in parentheses: - -``` -(1, (2, (3, Nil))) -``` - -Each item in a cons list contains two elements: the value of the current item -and the next item. The last item in the list contains only a value called `Nil` -without a next item. A cons list is produced by recursively calling the `cons` -function. The canonical name to denote the base case of the recursion is `Nil`. -Note that this is not the same as the “null” or “nil” concept in Chapter 6, -which is an invalid or absent value. - -The cons list isn’t a commonly used data structure in Rust. Most of the time -when you have a list of items in Rust, `Vec` is a better choice to use. -Other, more complex recursive data types *are* useful in various situations, -but by starting with the cons list in this chapter, we can explore how boxes -let us define a recursive data type without much distraction. - -Listing 15-2 contains an enum definition for a cons list. Note that this code -won’t compile yet because the `List` type doesn’t have a known size, which -we’ll demonstrate. - -Filename: src/main.rs - -``` -enum List { - Cons(i32, List), - Nil, -} -``` - -Listing 15-2: The first attempt at defining an enum to represent a cons list -data structure of `i32` values - -> Note: We’re implementing a cons list that holds only `i32` values for the -purposes of this example. We could have implemented it using generics, as we -discussed in Chapter 10, to define a cons list type that could store values of -any type. - -Using the `List` type to store the list `1, 2, 3` would look like the code in -Listing 15-3. - -Filename: src/main.rs - -``` ---snip-- - -use crate::List::{Cons, Nil}; - -fn main() { - let list = Cons(1, Cons(2, Cons(3, Nil))); -} -``` - -Listing 15-3: Using the `List` enum to store the list `1, 2, 3` - -The first `Cons` value holds `1` and another `List` value. This `List` value is -another `Cons` value that holds `2` and another `List` value. This `List` value -is one more `Cons` value that holds `3` and a `List` value, which is finally -`Nil`, the non-recursive variant that signals the end of the list. - -If we try to compile the code in Listing 15-3, we get the error shown in -Listing 15-4. - -``` -error[E0072]: recursive type `List` has infinite size - --> src/main.rs:1:1 - | -1 | enum List { - | ^^^^^^^^^ recursive type has infinite size -2 | Cons(i32, List), - | ---- recursive without indirection - | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` -representable - | -2 | Cons(i32, Box), - | ++++ + -``` - -Listing 15-4: The error we get when attempting to define a recursive enum - -The error shows this type “has infinite size.” The reason is that we’ve defined -`List` with a variant that is recursive: it holds another value of itself -directly. As a result, Rust can’t figure out how much space it needs to store a -`List` value. Let’s break down why we get this error. First we’ll look at how -Rust decides how much space it needs to store a value of a non-recursive type. - -#### Computing the Size of a Non-Recursive Type - -Recall the `Message` enum we defined in Listing 6-2 when we discussed enum -definitions in Chapter 6: - -``` -enum Message { - Quit, - Move { x: i32, y: i32 }, - Write(String), - ChangeColor(i32, i32, i32), -} -``` - -To determine how much space to allocate for a `Message` value, Rust goes -through each of the variants to see which variant needs the most space. Rust -sees that `Message::Quit` doesn’t need any space, `Message::Move` needs enough -space to store two `i32` values, and so forth. Because only one variant will be -used, the most space a `Message` value will need is the space it would take to -store the largest of its variants. - -Contrast this with what happens when Rust tries to determine how much space a -recursive type like the `List` enum in Listing 15-2 needs. The compiler starts -by looking at the `Cons` variant, which holds a value of type `i32` and a value -of type `List`. Therefore, `Cons` needs an amount of space equal to the size of -an `i32` plus the size of a `List`. To figure out how much memory the `List` -type needs, the compiler looks at the variants, starting with the `Cons` -variant. The `Cons` variant holds a value of type `i32` and a value of type -`List`, and this process continues infinitely, as shown in Figure 15-1. - -Figure 15-1: An infinite `List` consisting of infinite `Cons` variants - -#### Using Box to Get a Recursive Type with a Known Size - -Because Rust can’t figure out how much space to allocate for recursively -defined types, the compiler gives an error with this helpful suggestion: - -``` -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `List` -representable - | -2 | Cons(i32, Box), - | ++++ + -``` - -In this suggestion, *indirection* means that instead of storing a value -directly, we should change the data structure to store the value indirectly by -storing a pointer to the value instead. - -Because a `Box` is a pointer, Rust always knows how much space a `Box` -needs: a pointer’s size doesn’t change based on the amount of data it’s -pointing to. This means we can put a `Box` inside the `Cons` variant instead -of another `List` value directly. The `Box` will point to the next `List` -value that will be on the heap rather than inside the `Cons` variant. -Conceptually, we still have a list, created with lists holding other lists, but -this implementation is now more like placing the items next to one another -rather than inside one another. - -We can change the definition of the `List` enum in Listing 15-2 and the usage -of the `List` in Listing 15-3 to the code in Listing 15-5, which will compile. - -Filename: src/main.rs - -``` -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) - )) - )) - ); -} -``` - -Listing 15-5: Definition of `List` that uses `Box` in order to have a known -size - -The `Cons` variant needs the size of an `i32` plus the space to store the box’s -pointer data. The `Nil` variant stores no values, so it needs less space than -the `Cons` variant. We now know that any `List` value will take up the size of -an `i32` plus the size of a box’s pointer data. By using a box, we’ve broken -the infinite, recursive chain, so the compiler can figure out the size it needs -to store a `List` value. Figure 15-2 shows what the `Cons` variant looks like -now. - -Figure 15-2: A `List` that is not infinitely sized, because `Cons` holds a `Box` - -Boxes provide only the indirection and heap allocation; they don’t have any -other special capabilities, like those we’ll see with the other smart pointer -types. They also don’t have the performance overhead that these special -capabilities incur, so they can be useful in cases like the cons list where the -indirection is the only feature we need. We’ll look at more use cases for boxes -in Chapter 17. - -The `Box` type is a smart pointer because it implements the `Deref` trait, -which allows `Box` values to be treated like references. When a `Box` -value goes out of scope, the heap data that the box is pointing to is cleaned -up as well because of the `Drop` trait implementation. These two traits will be -even more important to the functionality provided by the other smart pointer -types we’ll discuss in the rest of this chapter. Let’s explore these two traits -in more detail. - -## Treating Smart Pointers Like Regular References with Deref - -Implementing the `Deref` trait allows you to customize the behavior of the -*dereference operator* `*` (not to be confused with the multiplication or glob -operator). By implementing `Deref` in such a way that a smart pointer can be -treated like a regular reference, you can write code that operates on -references and use that code with smart pointers too. - -Let’s first look at how the dereference operator works with regular references. -Then we’ll try to define a custom type that behaves like `Box`, and see why -the dereference operator doesn’t work like a reference on our newly defined -type. We’ll explore how implementing the `Deref` trait makes it possible for -smart pointers to work in ways similar to references. Then we’ll look at Rust’s -*deref coercion* feature and how it lets us work with either references or -smart pointers. - -> Note: There’s one big difference between the `MyBox` type we’re about to -build and the real `Box`: our version will not store its data on the heap. -We are focusing this example on `Deref`, so where the data is actually stored -is less important than the pointer-like behavior. - -### Following the Pointer to the Value - -A regular reference is a type of pointer, and one way to think of a pointer is -as an arrow to a value stored somewhere else. In Listing 15-6, we create a -reference to an `i32` value and then use the dereference operator to follow the -reference to the value. - -Filename: src/main.rs - -``` -fn main() { - 1 let x = 5; - 2 let y = &x; - - 3 assert_eq!(5, x); - 4 assert_eq!(5, *y); -} -``` - -Listing 15-6: Using the dereference operator to follow a reference to an `i32` -value - -The variable `x` holds an `i32` value `5` [1]. We set `y` equal to a reference -to `x` [2]. We can assert that `x` is equal to `5` [3]. However, if we want to -make an assertion about the value in `y`, we have to use `*y` to follow the -reference to the value it’s pointing to (hence *dereference*) so the compiler -can compare the actual value [4]. Once we dereference `y`, we have access to -the integer value `y` is pointing to that we can compare with `5`. - -If we tried to write `assert_eq!(5, y);` instead, we would get this compilation -error: - -``` -error[E0277]: can't compare `{integer}` with `&{integer}` - --> src/main.rs:6:5 - | -6 | assert_eq!(5, y); - | ^^^^^^^^^^^^^^^^ no implementation for `{integer} == -&{integer}` - | - = help: the trait `PartialEq<&{integer}>` is not implemented -for `{integer}` -``` - -Comparing a number and a reference to a number isn’t allowed because they’re -different types. We must use the dereference operator to follow the reference -to the value it’s pointing to. - -### Using Box Like a Reference - -We can rewrite the code in Listing 15-6 to use a `Box` instead of a -reference; the dereference operator used on the `Box` in Listing 15-7 -functions in the same way as the dereference operator used on the reference in -Listing 15-6. - -Filename: src/main.rs - -``` -fn main() { - let x = 5; - 1 let y = Box::new(x); - - assert_eq!(5, x); - 2 assert_eq!(5, *y); -} -``` - -Listing 15-7: Using the dereference operator on a `Box` - -The main difference between Listing 15-7 and Listing 15-6 is that here we set -`y` to be an instance of a box pointing to a copied value of `x` rather than a -reference pointing to the value of `x` [1]. In the last assertion [2], we can -use the dereference operator to follow the box’s pointer in the same way that -we did when `y` was a reference. Next, we’ll explore what is special about -`Box` that enables us to use the dereference operator by defining our own -box type. - -### Defining Our Own Smart Pointer - -Let’s build a smart pointer similar to the `Box` type provided by the -standard library to experience how smart pointers behave differently from -references by default. Then we’ll look at how to add the ability to use the -dereference operator. - -The `Box` type is ultimately defined as a tuple struct with one element, so -Listing 15-8 defines a `MyBox` type in the same way. We’ll also define a -`new` function to match the `new` function defined on `Box`. - -Filename: src/main.rs - -``` - 1 struct MyBox(T); - -impl MyBox { - 2 fn new(x: T) -> MyBox { - 3 MyBox(x) - } -} -``` - -Listing 15-8: Defining a `MyBox` type - -We define a struct named `MyBox` and declare a generic parameter `T` [1] -because we want our type to hold values of any type. The `MyBox` type is a -tuple struct with one element of type `T`. The `MyBox::new` function takes one -parameter of type `T` [2] and returns a `MyBox` instance that holds the value -passed in [3]. - -Let’s try adding the `main` function in Listing 15-7 to Listing 15-8 and -changing it to use the `MyBox` type we’ve defined instead of `Box`. The -code in Listing 15-9 won’t compile because Rust doesn’t know how to dereference -`MyBox`. - -Filename: src/main.rs - -``` -fn main() { - let x = 5; - let y = MyBox::new(x); - - assert_eq!(5, x); - assert_eq!(5, *y); -} -``` - -Listing 15-9: Attempting to use `MyBox` in the same way we used references -and `Box` - -Here’s the resultant compilation error: - -``` -error[E0614]: type `MyBox<{integer}>` cannot be dereferenced - --> src/main.rs:14:19 - | -14 | assert_eq!(5, *y); - | ^^ -``` - -Our `MyBox` type can’t be dereferenced because we haven’t implemented that -ability on our type. To enable dereferencing with the `*` operator, we -implement the `Deref` trait. - -### Implementing the Deref Trait - -As discussed in “Implementing a Trait on a Type” on page XX, to implement a -trait we need to provide implementations for the trait’s required methods. The -`Deref` trait, provided by the standard library, requires us to implement one -method named `deref` that borrows `self` and returns a reference to the inner -data. Listing 15-10 contains an implementation of `Deref` to add to the -definition of `MyBox```. - -Filename: src/main.rs - -``` -use std::ops::Deref; - -impl Deref for MyBox { - 1 type Target = T; - - fn deref(&self) -> &Self::Target { - 2 &self.0 - } -} -``` - -Listing 15-10: Implementing `Deref` on `MyBox` - -The `type Target = T;` syntax [1] defines an associated type for the `Deref` -trait to use. Associated types are a slightly different way of declaring a -generic parameter, but you don’t need to worry about them for now; we’ll cover -them in more detail in Chapter 19. - -We fill in the body of the `deref` method with `&self.0` so `deref` returns a -reference to the value we want to access with the `*` operator [2]; recall from -“Using Tuple Structs Without Named Fields to Create Different Types” on page XX -that `.0` accesses the first value in a tuple struct. The `main` function in -Listing 15-9 that calls `*` on the `MyBox` value now compiles, and the -assertions pass! - -Without the `Deref` trait, the compiler can only dereference `&` references. -The `deref` method gives the compiler the ability to take a value of any type -that implements `Deref` and call the `deref` method to get a `&` reference that -it knows how to dereference. - -When we entered `*y` in Listing 15-9, behind the scenes Rust actually ran this -code: - -``` -*(y.deref()) -``` - -Rust substitutes the `*` operator with a call to the `deref` method and then a -plain dereference so we don’t have to think about whether or not we need to -call the `deref` method. This Rust feature lets us write code that functions -identically whether we have a regular reference or a type that implements -`Deref`. - -The reason the `deref` method returns a reference to a value, and that the -plain dereference outside the parentheses in `*(y.deref())` is still necessary, -has to do with the ownership system. If the `deref` method returned the value -directly instead of a reference to the value, the value would be moved out of -`self`. We don’t want to take ownership of the inner value inside `MyBox` in -this case or in most cases where we use the dereference operator. - -Note that the `*` operator is replaced with a call to the `deref` method and -then a call to the `*` operator just once, each time we use a `*` in our code. -Because the substitution of the `*` operator does not recurse infinitely, we -end up with data of type `i32`, which matches the `5` in `assert_eq!` in -Listing 15-9. - -### Implicit Deref Coercions with Functions and Methods - -*Deref coercion* converts a reference to a type that implements the `Deref` -trait into a reference to another type. For example, deref coercion can convert -`&String` to `&str` because `String` implements the `Deref` trait such that it -returns `&str`. Deref coercion is a convenience Rust performs on arguments to -functions and methods, and works only on types that implement the `Deref` -trait. It happens automatically when we pass a reference to a particular type’s -value as an argument to a function or method that doesn’t match the parameter -type in the function or method definition. A sequence of calls to the `deref` -method converts the type we provided into the type the parameter needs. - -Deref coercion was added to Rust so that programmers writing function and -method calls don’t need to add as many explicit references and dereferences -with `&` and `*`. The deref coercion feature also lets us write more code that -can work for either references or smart pointers. - -To see deref coercion in action, let’s use the `MyBox` type we defined in -Listing 15-8 as well as the implementation of `Deref` that we added in Listing -15-10. Listing 15-11 shows the definition of a function that has a string slice -parameter. - -Filename: src/main.rs - -``` -fn hello(name: &str) { - println!("Hello, {name}!"); -} -``` - -Listing 15-11: A `hello` function that has the parameter `name` of type `&str` - -We can call the `hello` function with a string slice as an argument, such as -`hello("Rust");`, for example. Deref coercion makes it possible to call `hello` -with a reference to a value of type `MyBox`, as shown in Listing 15-12. - -Filename: src/main.rs - -``` -fn main() { - let m = MyBox::new(String::from("Rust")); - hello(&m); -} -``` - -Listing 15-12: Calling `hello` with a reference to a `MyBox` value, -which works because of deref coercion - -Here we’re calling the `hello` function with the argument `&m`, which is a -reference to a `MyBox` value. Because we implemented the `Deref` trait -on `MyBox` in Listing 15-10, Rust can turn `&MyBox` into `&String` -by calling `deref`. The standard library provides an implementation of `Deref` -on `String` that returns a string slice, and this is in the API documentation -for `Deref`. Rust calls `deref` again to turn the `&String` into `&str`, which -matches the `hello` function’s definition. - -If Rust didn’t implement deref coercion, we would have to write the code in -Listing 15-13 instead of the code in Listing 15-12 to call `hello` with a value -of type `&MyBox`. - -Filename: src/main.rs - -``` -fn main() { - let m = MyBox::new(String::from("Rust")); - hello(&(*m)[..]); -} -``` - -Listing 15-13: The code we would have to write if Rust didn’t have deref -coercion - -The `(*m)` dereferences the `MyBox` into a `String`. Then the `&` and -`[..]` take a string slice of the `String` that is equal to the whole string to -match the signature of `hello`. This code without deref coercions is harder to -read, write, and understand with all of these symbols involved. Deref coercion -allows Rust to handle these conversions for us automatically. - -When the `Deref` trait is defined for the types involved, Rust will analyze the -types and use `Deref::deref` as many times as necessary to get a reference to -match the parameter’s type. The number of times that `Deref::deref` needs to be -inserted is resolved at compile time, so there is no runtime penalty for taking -advantage of deref coercion! - -### How Deref Coercion Interacts with Mutability - -Similar to how you use the `Deref` trait to override the `*` operator on -immutable references, you can use the `DerefMut` trait to override the `*` -operator on mutable references. - -Rust does deref coercion when it finds types and trait implementations in three -cases: - -* From `&T` to `&U` when `T: Deref` -* From `&mut T` to `&mut U` when `T: DerefMut` -* From `&mut T` to `&U` when `T: Deref` - -The first two cases are the same except that the second implements mutability. -The first case states that if you have a `&T`, and `T` implements `Deref` to -some type `U`, you can get a `&U` transparently. The second case states that -the same deref coercion happens for mutable references. - -The third case is trickier: Rust will also coerce a mutable reference to an -immutable one. But the reverse is *not* possible: immutable references will -never coerce to mutable references. Because of the borrowing rules, if you have -a mutable reference, that mutable reference must be the only reference to that -data (otherwise, the program wouldn’t compile). Converting one mutable -reference to one immutable reference will never break the borrowing rules. -Converting an immutable reference to a mutable reference would require that the -initial immutable reference is the only immutable reference to that data, but -the borrowing rules don’t guarantee that. Therefore, Rust can’t make the -assumption that converting an immutable reference to a mutable reference is -possible. - -## Running Code on Cleanup with the Drop Trait - -The second trait important to the smart pointer pattern is `Drop`, which lets -you customize what happens when a value is about to go out of scope. You can -provide an implementation for the `Drop` trait on any type, and that code can -be used to release resources like files or network connections. - -We’re introducing `Drop` in the context of smart pointers because the -functionality of the `Drop` trait is almost always used when implementing a -smart pointer. For example, when a `Box` is dropped it will deallocate the -space on the heap that the box points to. - -In some languages, for some types, the programmer must call code to free memory -or resources every time they finish using an instance of those types. Examples -include file handles, sockets, and locks. If they forget, the system might -become overloaded and crash. In Rust, you can specify that a particular bit of -code be run whenever a value goes out of scope, and the compiler will insert -this code automatically. As a result, you don’t need to be careful about -placing cleanup code everywhere in a program that an instance of a particular -type is finished with—you still won’t leak resources! - -You specify the code to run when a value goes out of scope by implementing the -`Drop` trait. The `Drop` trait requires you to implement one method named -`drop` that takes a mutable reference to `self`. To see when Rust calls `drop`, -let’s implement `drop` with `println!` statements for now. - -Listing 15-14 shows a `CustomSmartPointer` struct whose only custom -functionality is that it will print `Dropping CustomSmartPointer!` when the -instance goes out of scope, to show when Rust runs the `drop` method. - -Filename: src/main.rs - -``` -struct CustomSmartPointer { - data: String, -} - -1 impl Drop for CustomSmartPointer { - fn drop(&mut self) { - 2 println!( - "Dropping CustomSmartPointer with data `{}`!", - self.data - ); - } -} - -fn main() { - 3 let c = CustomSmartPointer { - data: String::from("my stuff"), - }; - 4 let d = CustomSmartPointer { - data: String::from("other stuff"), - }; - 5 println!("CustomSmartPointers created."); -6 } -``` - -Listing 15-14: A `CustomSmartPointer` struct that implements the `Drop` trait -where we would put our cleanup code - -The `Drop` trait is included in the prelude, so we don’t need to bring it into -scope. We implement the `Drop` trait on `CustomSmartPointer` [1] and provide an -implementation for the `drop` method that calls `println!` [2]. The body of the -`drop` method is where you would place any logic that you wanted to run when an -instance of your type goes out of scope. We’re printing some text here to -demonstrate visually when Rust will call `drop`. - -In `main`, we create two instances of `CustomSmartPointer` at [3] and [4] and -then print `CustomSmartPointers created` [5]. At the end of `main` [6], our -instances of `CustomSmartPointer` will go out of scope, and Rust will call the -code we put in the `drop` method [2], printing our final message. Note that we -didn’t need to call the `drop` method explicitly. - -When we run this program, we’ll see the following output: - -``` -CustomSmartPointers created. -Dropping CustomSmartPointer with data `other stuff`! -Dropping CustomSmartPointer with data `my stuff`! -``` - -Rust automatically called `drop` for us when our instances went out of scope, -calling the code we specified. Variables are dropped in the reverse order of -their creation, so `d` was dropped before `c`. This example’s purpose is to -give you a visual guide to how the `drop` method works; usually you would -specify the cleanup code that your type needs to run rather than a print -message. - -Unfortunately, it’s not straightforward to disable the automatic `drop` -functionality. Disabling `drop` isn’t usually necessary; the whole point of the -`Drop` trait is that it’s taken care of automatically. Occasionally, however, -you might want to clean up a value early. One example is when using smart -pointers that manage locks: you might want to force the `drop` method that -releases the lock so that other code in the same scope can acquire the lock. -Rust doesn’t let you call the `Drop` trait’s `drop` method manually; instead, -you have to call the `std::mem::drop` function provided by the standard library -if you want to force a value to be dropped before the end of its scope. - -If we try to call the `Drop` trait’s `drop` method manually by modifying the -`main` function from Listing 15-14, as shown in Listing 15-15, we’ll get a -compiler error. - -Filename: src/main.rs - -``` -fn main() { - let c = CustomSmartPointer { - data: String::from("some data"), - }; - println!("CustomSmartPointer created."); - c.drop(); - println!( - "CustomSmartPointer dropped before the end of main." - ); -} -``` - -Listing 15-15: Attempting to call the `drop` method from the `Drop` trait -manually to clean up early - -When we try to compile this code, we’ll get this error: - -``` -error[E0040]: explicit use of destructor method - --> src/main.rs:16:7 - | -16 | c.drop(); - | --^^^^-- - | | | - | | explicit destructor calls not allowed - | help: consider using `drop` function: `drop(c)` -``` - -This error message states that we’re not allowed to explicitly call `drop`. The -error message uses the term *destructor*, which is the general programming term -for a function that cleans up an instance. A *destructor* is analogous to a -*constructor*, which creates an instance. The `drop` function in Rust is one -particular destructor. - -Rust doesn’t let us call `drop` explicitly because Rust would still -automatically call `drop` on the value at the end of `main`. This would cause a -*double free* error because Rust would be trying to clean up the same value -twice. - -We can’t disable the automatic insertion of `drop` when a value goes out of -scope, and we can’t call the `drop` method explicitly. So, if we need to force -a value to be cleaned up early, we use the `std::mem::drop` function. - -The `std::mem::drop` function is different from the `drop` method in the `Drop` -trait. We call it by passing as an argument the value we want to force-drop. -The function is in the prelude, so we can modify `main` in Listing 15-15 to -call the `drop` function, as shown in Listing 15-16. - -Filename: src/main.rs - -``` -fn main() { - let c = CustomSmartPointer { - data: String::from("some data"), - }; - println!("CustomSmartPointer created."); - drop(c); - println!( - "CustomSmartPointer dropped before the end of main." - ); -} -``` - -Listing 15-16: Calling `std::mem::drop` to explicitly drop a value before it -goes out of scope - -Running this code will print the following: - -``` -CustomSmartPointer created. -Dropping CustomSmartPointer with data `some data`! -CustomSmartPointer dropped before the end of main. -``` - -The text `Dropping CustomSmartPointer with data `some data`!` is printed -between the `CustomSmartPointer created.` and `CustomSmartPointer dropped -before the end of main.` text, showing that the `drop` method code is called to -drop `c` at that point. - -You can use code specified in a `Drop` trait implementation in many ways to -make cleanup convenient and safe: for instance, you could use it to create your -own memory allocator! With the `Drop` trait and Rust’s ownership system, you -don’t have to remember to clean up because Rust does it automatically. - -You also don’t have to worry about problems resulting from accidentally -cleaning up values still in use: the ownership system that makes sure -references are always valid also ensures that `drop` gets called only once when -the value is no longer being used. - -Now that we’ve examined `Box` and some of the characteristics of smart -pointers, let’s look at a few other smart pointers defined in the standard -library. - -## Rc, the Reference Counted Smart Pointer - -In the majority of cases, ownership is clear: you know exactly which variable -owns a given value. However, there are cases when a single value might have -multiple owners. For example, in graph data structures, multiple edges might -point to the same node, and that node is conceptually owned by all of the edges -that point to it. A node shouldn’t be cleaned up unless it doesn’t have any -edges pointing to it and so has no owners. - -You have to enable multiple ownership explicitly by using the Rust type -`Rc`, which is an abbreviation for *reference counting*. The `Rc` type -keeps track of the number of references to a value to determine whether or not -the value is still in use. If there are zero references to a value, the value -can be cleaned up without any references becoming invalid. - -Imagine `Rc` as a TV in a family room. When one person enters to watch TV, -they turn it on. Others can come into the room and watch the TV. When the last -person leaves the room, they turn off the TV because it’s no longer being used. -If someone turns off the TV while others are still watching it, there would be -an uproar from the remaining TV watchers! - -We use the `Rc` type when we want to allocate some data on the heap for -multiple parts of our program to read and we can’t determine at compile time -which part will finish using the data last. If we knew which part would finish -last, we could just make that part the data’s owner, and the normal ownership -rules enforced at compile time would take effect. - -Note that `Rc` is only for use in single-threaded scenarios. When we discuss -concurrency in Chapter 16, we’ll cover how to do reference counting in -multithreaded programs. - -### Using Rc to Share Data - -Let’s return to our cons list example in Listing 15-5. Recall that we defined -it using `Box`. This time, we’ll create two lists that both share ownership -of a third list. Conceptually, this looks similar to Figure 15-3. - -Figure 15-3: Two lists, `b` and `c`, sharing ownership of a third list, `a` - -We’ll create list `a` that contains `5` and then `10`. Then we’ll make two more -lists: `b` that starts with `3` and `c` that starts with `4`. Both `b` and `c` -lists will then continue on to the first `a` list containing `5` and `10`. In -other words, both lists will share the first list containing `5` and `10`. - -Trying to implement this scenario using our definition of `List` with `Box` -won’t work, as shown in Listing 15-17. - -Filename: src/main.rs - -``` -enum List { - Cons(i32, Box), - Nil, -} - -use crate::List::{Cons, Nil}; - -fn main() { - let a = Cons(5, Box::new(Cons(10, Box::new(Nil)))); - 1 let b = Cons(3, Box::new(a)); - 2 let c = Cons(4, Box::new(a)); -} -``` - -Listing 15-17: Demonstrating that we’re not allowed to have two lists using -`Box` that try to share ownership of a third list - -When we compile this code, we get this error: - -``` -error[E0382]: use of moved value: `a` - --> src/main.rs:11:30 - | -9 | let a = Cons(5, Box::new(Cons(10, Box::new(Nil)))); - | - move occurs because `a` has type `List`, which -does not implement the `Copy` trait -10 | let b = Cons(3, Box::new(a)); - | - value moved here -11 | let c = Cons(4, Box::new(a)); - | ^ value used here after move -``` - -The `Cons` variants own the data they hold, so when we create the `b` list [1], -`a` is moved into `b` and `b` owns `a`. Then, when we try to use `a` again when -creating `c` [2], we’re not allowed to because `a` has been moved. - -We could change the definition of `Cons` to hold references instead, but then -we would have to specify lifetime parameters. By specifying lifetime -parameters, we would be specifying that every element in the list will live at -least as long as the entire list. This is the case for the elements and lists -in Listing 15-17, but not in every scenario. - -Instead, we’ll change our definition of `List` to use `Rc` in place of -`Box`, as shown in Listing 15-18. Each `Cons` variant will now hold a value -and an `Rc` pointing to a `List`. When we create `b`, instead of taking -ownership of `a`, we’ll clone the `Rc` that `a` is holding, thereby -increasing the number of references from one to two and letting `a` and `b` -share ownership of the data in that `Rc`. We’ll also clone `a` when -creating `c`, increasing the number of references from two to three. Every time -we call `Rc::clone`, the reference count to the data within the `Rc` will -increase, and the data won’t be cleaned up unless there are zero references to -it. - -Filename: src/main.rs - -``` -enum List { - Cons(i32, Rc), - Nil, -} - -use crate::List::{Cons, Nil}; -1 use std::rc::Rc; - -fn main() { - 2 let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); - 3 let b = Cons(3, Rc::clone(&a)); - 4 let c = Cons(4, Rc::clone(&a)); -} -``` - -Listing 15-18: A definition of `List` that uses `Rc` - -We need to add a `use` statement to bring `Rc` into scope [1] because it’s -not in the prelude. In `main`, we create the list holding `5` and `10` and -store it in a new `Rc` in `a` [2]. Then, when we create `b` [3] and `c` -[4], we call the `Rc::clone` function and pass a reference to the `Rc` in -`a` as an argument. - -We could have called `a.clone()` rather than `Rc::clone(&a)`, but Rust’s -convention is to use `Rc::clone` in this case. The implementation of -`Rc::clone` doesn’t make a deep copy of all the data like most types’ -implementations of `clone` do. The call to `Rc::clone` only increments the -reference count, which doesn’t take much time. Deep copies of data can take a -lot of time. By using `Rc::clone` for reference counting, we can visually -distinguish between the deep-copy kinds of clones and the kinds of clones that -increase the reference count. When looking for performance problems in the -code, we only need to consider the deep-copy clones and can disregard calls to -`Rc::clone`. - -### Cloning an Rc Increases the Reference Count - -Let’s change our working example in Listing 15-18 so we can see the reference -counts changing as we create and drop references to the `Rc` in `a`. - -In Listing 15-19, we’ll change `main` so it has an inner scope around list `c`; -then we can see how the reference count changes when `c` goes out of scope. - -Filename: src/main.rs - -``` ---snip-- - -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) - ); -} -``` - -Listing 15-19: Printing the reference count - -At each point in the program where the reference count changes, we print the -reference count, which we get by calling the `Rc::strong_count` function. This -function is named `strong_count` rather than `count` because the `Rc` type -also has a `weak_count`; we’ll see what `weak_count` is used for in “Preventing -Reference Cycles Using Weak” on page XX. - -This code prints the following: - -``` -count after creating a = 1 -count after creating b = 2 -count after creating c = 3 -count after c goes out of scope = 2 -``` - -We can see that the `Rc` in `a` has an initial reference count of 1; then -each time we call `clone`, the count goes up by 1. When `c` goes out of scope, -the count goes down by 1. We don’t have to call a function to decrease the -reference count like we have to call `Rc::clone` to increase the reference -count: the implementation of the `Drop` trait decreases the reference count -automatically when an `Rc` value goes out of scope. - -What we can’t see in this example is that when `b` and then `a` go out of scope -at the end of `main`, the count is then 0, and the `Rc` is cleaned up -completely. Using `Rc` allows a single value to have multiple owners, and -the count ensures that the value remains valid as long as any of the owners -still exist. - -Via immutable references, `Rc` allows you to share data between multiple -parts of your program for reading only. If `Rc` allowed you to have multiple -mutable references too, you might violate one of the borrowing rules discussed -in Chapter 4: multiple mutable borrows to the same place can cause data races -and inconsistencies. But being able to mutate data is very useful! In the next -section, we’ll discuss the interior mutability pattern and the `RefCell` -type that you can use in conjunction with an `Rc` to work with this -immutability restriction. - -## RefCell and the Interior Mutability Pattern - -*Interior mutability* is a design pattern in Rust that allows you to mutate -data even when there are immutable references to that data; normally, this -action is disallowed by the borrowing rules. To mutate data, the pattern uses -`unsafe` code inside a data structure to bend Rust’s usual rules that govern -mutation and borrowing. Unsafe code indicates to the compiler that we’re -checking the rules manually instead of relying on the compiler to check them -for us; we will discuss unsafe code more in Chapter 19. - -We can use types that use the interior mutability pattern only when we can -ensure that the borrowing rules will be followed at runtime, even though the -compiler can’t guarantee that. The `unsafe` code involved is then wrapped in a -safe API, and the outer type is still immutable. - -Let’s explore this concept by looking at the `RefCell` type that follows the -interior mutability pattern. - -### Enforcing Borrowing Rules at Runtime with RefCell - -Unlike `Rc`, the `RefCell` type represents single ownership over the data -it holds. So what makes `RefCell` different from a type like `Box`? -Recall the borrowing rules you learned in Chapter 4: - -* At any given time, you can have *either* one mutable reference or any number -of immutable references (but not both). -* References must always be valid. - -With references and `Box`, the borrowing rules’ invariants are enforced at -compile time. With `RefCell`, these invariants are enforced *at runtime*. -With references, if you break these rules, you’ll get a compiler error. With -`RefCell`, if you break these rules, your program will panic and exit. - -The advantages of checking the borrowing rules at compile time are that errors -will be caught sooner in the development process, and there is no impact on -runtime performance because all the analysis is completed beforehand. For those -reasons, checking the borrowing rules at compile time is the best choice in the -majority of cases, which is why this is Rust’s default. - -The advantage of checking the borrowing rules at runtime instead is that -certain memory-safe scenarios are then allowed, where they would’ve been -disallowed by the compile-time checks. Static analysis, like the Rust compiler, -is inherently conservative. Some properties of code are impossible to detect by -analyzing the code: the most famous example is the Halting Problem, which is -beyond the scope of this book but is an interesting topic to research. - -Because some analysis is impossible, if the Rust compiler can’t be sure the -code complies with the ownership rules, it might reject a correct program; in -this way, it’s conservative. If Rust accepted an incorrect program, users -wouldn’t be able to trust in the guarantees Rust makes. However, if Rust -rejects a correct program, the programmer will be inconvenienced, but nothing -catastrophic can occur. The `RefCell` type is useful when you’re sure your -code follows the borrowing rules but the compiler is unable to understand and -guarantee that. - -Similar to `Rc`, `RefCell` is only for use in single-threaded scenarios -and will give you a compile-time error if you try using it in a multithreaded -context. We’ll talk about how to get the functionality of `RefCell` in a -multithreaded program in Chapter 16. - -Here is a recap of the reasons to choose `Box`, `Rc`, or `RefCell`: - -* `Rc` enables multiple owners of the same data; `Box` and `RefCell` -have single owners. -* `Box` allows immutable or mutable borrows checked at compile time; `Rc` -allows only immutable borrows checked at compile time; `RefCell` allows -immutable or mutable borrows checked at runtime. -* Because `RefCell` allows mutable borrows checked at runtime, you can -mutate the value inside the `RefCell` even when the `RefCell` is -immutable. - -Mutating the value inside an immutable value is the *interior mutability* -pattern. Let’s look at a situation in which interior mutability is useful and -examine how it’s possible. - -### Interior Mutability: A Mutable Borrow to an Immutable Value - -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: - -Filename: src/main.rs - -``` -fn main() { - let x = 5; - let y = &mut x; -} -``` - -If you tried to compile this code, you’d get the following error: - -``` -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 -``` - -However, there are situations in which it would be useful for a value to mutate -itself in its methods but appear immutable to other code. Code outside the -value’s methods would not be able to mutate the value. Using `RefCell` is -one way to get the ability to have interior mutability, but `RefCell` -doesn’t get around the borrowing rules completely: the borrow checker in the -compiler allows this interior mutability, and the borrowing rules are checked -at runtime instead. If you violate the rules, you’ll get a `panic!` instead of -a compiler error. - -Let’s work through a practical example where we can use `RefCell` to mutate -an immutable value and see why that is useful. - -#### A Use Case for Interior Mutability: Mock Objects - -Sometimes during testing a programmer will use a type in place of another type, -in order to observe particular behavior and assert that it’s implemented -correctly. This placeholder type is called a *test double*. Think of it in the -sense of a stunt double in filmmaking, where a person steps in and substitutes -for an actor to do a particularly tricky scene. Test doubles stand in for other -types when we’re running tests. *Mock objects* are specific types of test -doubles that record what happens during a test so you can assert that the -correct actions took place. - -Rust doesn’t have objects in the same sense as other languages have objects, -and Rust doesn’t have mock object functionality built into the standard library -as some other languages do. However, you can definitely create a struct that -will serve the same purposes as a mock object. - -Here’s the scenario we’ll test: we’ll create a library that tracks a value -against a maximum value and sends messages based on how close to the maximum -value the current value is. This library could be used to keep track of a -user’s quota for the number of API calls they’re allowed to make, for example. - -Our library will only provide the functionality of tracking how close to the -maximum a value is and what the messages should be at what times. Applications -that use our library will be expected to provide the mechanism for sending the -messages: the application could put a message in the application, send an -email, send a text message, or do something else. The library doesn’t need to -know that detail. All it needs is something that implements a trait we’ll -provide called `Messenger`. Listing 15-20 shows the library code. - -Filename: src/lib.rs - -``` -pub trait Messenger { - 1 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: &'a T, - max: usize - ) -> LimitTracker<'a, T> { - LimitTracker { - messenger, - value: 0, - max, - } - } - - 2 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: You're at 90% of your quota!"); - } else if percentage_of_max >= 0.75 { - self.messenger - .send("Warning: You're at 75% of your quota!"); - } - } -} -``` - -Listing 15-20: A library to keep track of how close a value is to a maximum -value and warn when the value is at certain levels - -One important part of this code is that the `Messenger` trait has one method -called `send` that takes an immutable reference to `self` and the text of the -message [1]. This trait is the interface our mock object needs to implement so -that the mock can be used in the same way a real object is. The other important -part is that we want to test the behavior of the `set_value` method on the -`LimitTracker` [2]. We can change what we pass in for the `value` parameter, -but `set_value` doesn’t return anything for us to make assertions on. We want -to be able to say that if we create a `LimitTracker` with something that -implements the `Messenger` trait and a particular value for `max`, when we pass -different numbers for `value` the messenger is told to send the appropriate -messages. - -We need a mock object that, instead of sending an email or text message when we -call `send`, will only keep track of the messages it’s told to send. We can -create a new instance of the mock object, create a `LimitTracker` that uses the -mock object, call the `set_value` method on `LimitTracker`, and then check that -the mock object has the messages we expect. Listing 15-21 shows an attempt to -implement a mock object to do just that, but the borrow checker won’t allow it. - -Filename: src/lib.rs - -``` -#[cfg(test)] -mod tests { - use super::*; - - 1 struct MockMessenger { - 2 sent_messages: Vec, - } - - impl MockMessenger { - 3 fn new() -> MockMessenger { - MockMessenger { - sent_messages: vec![], - } - } - } - - 4 impl Messenger for MockMessenger { - fn send(&self, message: &str) { - 5 self.sent_messages.push(String::from(message)); - } - } - - #[test] - 6 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); - } -} -``` - -Listing 15-21: An attempt to implement a `MockMessenger` that isn’t allowed by -the borrow checker - -This test code defines a `MockMessenger` struct [1] that has a `sent_messages` -field with a `Vec` of `String` values [2] to keep track of the messages it’s -told to send. We also define an associated function `new` [3] to make it -convenient to create new `MockMessenger` values that start with an empty list -of messages. We then implement the `Messenger` trait for `MockMessenger` [4] so -we can give a `MockMessenger` to a `LimitTracker`. In the definition of the -`send` method [5], we take the message passed in as a parameter and store it in -the `MockMessenger` list of `sent_messages`. - -In the test, we’re testing what happens when the `LimitTracker` is told to set -`value` to something that is more than 75 percent of the `max` value [6]. First -we create a new `MockMessenger`, which will start with an empty list of -messages. Then we create a new `LimitTracker` and give it a reference to the -new `MockMessenger` and a `max` value of `100`. We call the `set_value` method -on the `LimitTracker` with a value of `80`, which is more than 75 percent of -100. Then we assert that the list of messages that the `MockMessenger` is -keeping track of should now have one message in it. - -However, there’s one problem with this test, as shown here: - -``` -error[E0596]: cannot borrow `self.sent_messages` as mutable, as it is behind a -`&` reference - --> src/lib.rs:58:13 - | -2 | fn send(&self, msg: &str); - | ----- help: consider changing that to be a mutable reference: -`&mut self` -... -58 | self.sent_messages.push(String::from(message)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a -`&` reference, so the data it refers to cannot be borrowed as mutable -``` - -We can’t modify the `MockMessenger` to keep track of the messages because the -`send` method takes an immutable reference to `self`. We also can’t take the -suggestion from the error text to use `&mut self` instead because then the -signature of `send` wouldn’t match the signature in the `Messenger` trait -definition (feel free to try it and see what error message you get). - -This is a situation in which interior mutability can help! We’ll store the -`sent_messages` within a `RefCell`, and then the `send` method will be able -to modify `sent_messages` to store the messages we’ve seen. Listing 15-22 shows -what that looks like. - -Filename: src/lib.rs - -``` -#[cfg(test)] -mod tests { - use super::*; - use std::cell::RefCell; - - struct MockMessenger { - 1 sent_messages: RefCell>, - } - - impl MockMessenger { - fn new() -> MockMessenger { - MockMessenger { - 2 sent_messages: RefCell::new(vec![]), - } - } - } - - impl Messenger for MockMessenger { - fn send(&self, message: &str) { - self.sent_messages - 3 .borrow_mut() - .push(String::from(message)); - } - } - - #[test] - fn it_sends_an_over_75_percent_warning_message() { - --snip-- - - assert_eq!( - 4 mock_messenger.sent_messages.borrow().len(), - 1 - ); - } -} -``` - -Listing 15-22: Using `RefCell` to mutate an inner value while the outer -value is considered immutable - -The `sent_messages` field is now of type `RefCell>` [1] instead of -`Vec`. In the `new` function, we create a new `RefCell>` -instance around the empty vector [2]. - -For the implementation of the `send` method, the first parameter is still an -immutable borrow of `self`, which matches the trait definition. We call -`borrow_mut` on the `RefCell>` in `self.sent_messages` [3] to get a -mutable reference to the value inside the `RefCell>`, which is the -vector. Then we can call `push` on the mutable reference to the vector to keep -track of the messages sent during the test. - -The last change we have to make is in the assertion: to see how many items are -in the inner vector, we call `borrow` on the `RefCell>` to get an -immutable reference to the vector [4]. - -Now that you’ve seen how to use `RefCell`, let’s dig into how it works! - -#### Keeping Track of Borrows at Runtime with RefCell - -When creating immutable and mutable references, we use the `&` and `&mut` -syntax, respectively. With `RefCell`, we use the `borrow` and `borrow_mut` -methods, which are part of the safe API that belongs to `RefCell`. The -`borrow` method returns the smart pointer type `Ref`, and `borrow_mut` -returns the smart pointer type `RefMut`. Both types implement `Deref`, so we -can treat them like regular references. - -The `RefCell` keeps track of how many `Ref` and `RefMut` smart -pointers are currently active. Every time we call `borrow`, the `RefCell` -increases its count of how many immutable borrows are active. When a `Ref` -value goes out of scope, the count of immutable borrows goes down by 1. Just -like the compile-time borrowing rules, `RefCell` lets us have many immutable -borrows or one mutable borrow at any point in time. - -If we try to violate these rules, rather than getting a compiler error as we -would with references, the implementation of `RefCell` will panic at -runtime. Listing 15-23 shows a modification of the implementation of `send` in -Listing 15-22. We’re deliberately trying to create two mutable borrows active -for the same scope to illustrate that `RefCell` prevents us from doing this -at runtime. - -Filename: src/lib.rs - -``` -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)); - } -} -``` - -Listing 15-23: Creating two mutable references in the same scope to see that -`RefCell` will panic - -We create a variable `one_borrow` for the `RefMut` smart pointer returned -from `borrow_mut`. Then we create another mutable borrow in the same way in the -variable `two_borrow`. This makes two mutable references in the same scope, -which isn’t allowed. When we run the tests for our library, the code in Listing -15-23 will compile without any errors, but the test will fail: - -``` ----- tests::it_sends_an_over_75_percent_warning_message stdout ---- -thread 'main' panicked at 'already borrowed: BorrowMutError', src/lib.rs:60:53 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -``` - -Notice that the code panicked with the message `already borrowed: -BorrowMutError`. This is how `RefCell` handles violations of the borrowing -rules at runtime. - -Choosing to catch borrowing errors at runtime rather than compile time, as -we’ve done here, means you’d potentially be finding mistakes in your code later -in the development process: possibly not until your code was deployed to -production. Also, your code would incur a small runtime performance penalty as -a result of keeping track of the borrows at runtime rather than compile time. -However, using `RefCell` makes it possible to write a mock object that can -modify itself to keep track of the messages it has seen while you’re using it -in a context where only immutable values are allowed. You can use `RefCell` -despite its trade-offs to get more functionality than regular references -provide. - -### Allowing Multiple Owners of Mutable Data with Rc and RefCell - -A common way to use `RefCell` is in combination with `Rc`. Recall that -`Rc` lets you have multiple owners of some data, but it only gives immutable -access to that data. If you have an `Rc` that holds a `RefCell`, you can -get a value that can have multiple owners *and* that you can mutate! - -For example, recall the cons list example in Listing 15-18 where we used -`Rc` to allow multiple lists to share ownership of another list. Because -`Rc` holds only immutable values, we can’t change any of the values in the -list once we’ve created them. Let’s add in `RefCell` for its ability to -change the values in the lists. Listing 15-24 shows that by using a -`RefCell` in the `Cons` definition, we can modify the value stored in all -the lists. - -Filename: src/main.rs - -``` -#[derive(Debug)] -enum List { - Cons(Rc>, Rc), - Nil, -} - -use crate::List::{Cons, Nil}; -use std::cell::RefCell; -use std::rc::Rc; - -fn main() { - 1 let value = Rc::new(RefCell::new(5)); - - 2 let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil))); - - let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a)); - let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a)); - - 3 *value.borrow_mut() += 10; - - println!("a after = {:?}", a); - println!("b after = {:?}", b); - println!("c after = {:?}", c); -} -``` - -Listing 15-24: Using `Rc>` to create a `List` that we can mutate - -We create a value that is an instance of `Rc>` and store it in a -variable named `value` [1] so we can access it directly later. Then we create a -`List` in `a` with a `Cons` variant that holds `value` [2]. We need to clone -`value` so both `a` and `value` have ownership of the inner `5` value rather -than transferring ownership from `value` to `a` or having `a` borrow from -`value`. - -We wrap the list `a` in an `Rc` so when we create lists `b` and `c`, they -can both refer to `a`, which is what we did in Listing 15-18. - -After we’ve created the lists in `a`, `b`, and `c`, we want to add 10 to the -value in `value` [3]. We do this by calling `borrow_mut` on `value`, which uses -the automatic dereferencing feature we discussed in “Where’s the -> Operator?” -on page XX to dereference the `Rc` to the inner `RefCell` value. The -`borrow_mut` method returns a `RefMut` smart pointer, and we use the -dereference operator on it and change the inner value. - -When we print `a`, `b`, and `c`, we can see that they all have the modified -value of `15` rather than `5`: - -``` -a after = Cons(RefCell { value: 15 }, Nil) -b after = Cons(RefCell { value: 3 }, Cons(RefCell { value: 15 }, Nil)) -c after = Cons(RefCell { value: 4 }, Cons(RefCell { value: 15 }, Nil)) -``` - -This technique is pretty neat! By using `RefCell`, we have an outwardly -immutable `List` value. But we can use the methods on `RefCell` that provide -access to its interior mutability so we can modify our data when we need to. -The runtime checks of the borrowing rules protect us from data races, and it’s -sometimes worth trading a bit of speed for this flexibility in our data -structures. Note that `RefCell` does not work for multithreaded code! -`Mutex` is the thread-safe version of `RefCell`, and we’ll discuss -`Mutex` in Chapter 16. - -## Reference Cycles Can Leak Memory - -Rust’s memory safety guarantees make it difficult, but not impossible, to -accidentally create memory that is never cleaned up (known as a *memory leak*). -Preventing memory leaks entirely is not one of Rust’s guarantees, meaning -memory leaks are memory safe in Rust. We can see that Rust allows memory leaks -by using `Rc` and `RefCell`: it’s possible to create references where -items refer to each other in a cycle. This creates memory leaks because the -reference count of each item in the cycle will never reach 0, and the values -will never be dropped. - -### Creating a Reference Cycle - -Let’s look at how a reference cycle might happen and how to prevent it, -starting with the definition of the `List` enum and a `tail` method in Listing -15-25. - -Filename: src/main.rs - -``` -use crate::List::{Cons, Nil}; -use std::cell::RefCell; -use std::rc::Rc; - -#[derive(Debug)] -enum List { - 1 Cons(i32, RefCell>), - Nil, -} - -impl List { - 2 fn tail(&self) -> Option<&RefCell>> { - match self { - Cons(_, item) => Some(item), - Nil => None, - } - } -} -``` - -Listing 15-25: A cons list definition that holds a `RefCell` so we can -modify what a `Cons` variant is referring to - -We’re using another variation of the `List` definition from Listing 15-5. The -second element in the `Cons` variant is now `RefCell>` [1], meaning -that instead of having the ability to modify the `i32` value as we did in -Listing 15-24, we want to modify the `List` value a `Cons` variant is pointing -to. We’re also adding a `tail` method [2] to make it convenient for us to -access the second item if we have a `Cons` variant. - -In Listing 15-26, we’re adding a `main` function that uses the definitions in -Listing 15-25. This code creates a list in `a` and a list in `b` that points to -the list in `a`. Then it modifies the list in `a` to point to `b`, creating a -reference cycle. There are `println!` statements along the way to show what the -reference counts are at various points in this process. - -Filename: src/main.rs - -``` -fn main() { - 1 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()); - - 2 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()); - - 3 if let Some(link) = a.tail() { - 4 *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()); -} -``` - -Listing 15-26: Creating a reference cycle of two `List` values pointing to each -other - -We create an `Rc` instance holding a `List` value in the variable `a` -with an initial list of `5, Nil` [1]. We then create an `Rc` instance -holding another `List` value in the variable `b` that contains the value `10` -and points to the list in `a` [2]. - -We modify `a` so it points to `b` instead of `Nil`, creating a cycle. We do -that by using the `tail` method to get a reference to the `RefCell>` -in `a`, which we put in the variable `link` [3]. Then we use the `borrow_mut` -method on the `RefCell>` to change the value inside from an `Rc` -that holds a `Nil` value to the `Rc` in `b` [4]. - -When we run this code, keeping the last `println!` commented out for the -moment, we’ll get this output: - -``` -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 -``` - -The reference count of the `Rc` instances in both `a` and `b` is 2 after -we change the list in `a` to point to `b`. At the end of `main`, Rust drops the -variable `b`, which decreases the reference count of the `b` `Rc` -instance from 2 to 1. The memory that `Rc` has on the heap won’t be -dropped at this point because its reference count is 1, not 0. Then Rust drops -`a`, which decreases the reference count of the `a` `Rc` instance from 2 -to 1 as well. This instance’s memory can’t be dropped either, because the other -`Rc` instance still refers to it. The memory allocated to the list will -remain uncollected forever. To visualize this reference cycle, we’ve created a -diagram in Figure 15-4. - -Figure 15-4: A reference cycle of lists `a` and `b` pointing to each other - -If you uncomment the last `println!` and run the program, Rust will try to -print this cycle with `a` pointing to `b` pointing to `a` and so forth until it -overflows the stack. - -Compared to a real-world program, the consequences of creating a reference -cycle in this example aren’t very dire: right after we create the reference -cycle, the program ends. However, if a more complex program allocated lots of -memory in a cycle and held onto it for a long time, the program would use more -memory than it needed and might overwhelm the system, causing it to run out of -available memory. - -Creating reference cycles is not easily done, but it’s not impossible either. -If you have `RefCell` values that contain `Rc` values or similar nested -combinations of types with interior mutability and reference counting, you must -ensure that you don’t create cycles; you can’t rely on Rust to catch them. -Creating a reference cycle would be a logic bug in your program that you should -use automated tests, code reviews, and other software development practices to -minimize. - -Another solution for avoiding reference cycles is reorganizing your data -structures so that some references express ownership and some references don’t. -As a result, you can have cycles made up of some ownership relationships and -some non-ownership relationships, and only the ownership relationships affect -whether or not a value can be dropped. In Listing 15-25, we always want `Cons` -variants to own their list, so reorganizing the data structure isn’t possible. -Let’s look at an example using graphs made up of parent nodes and child nodes -to see when non-ownership relationships are an appropriate way to prevent -reference cycles. - -### Preventing Reference Cycles Using Weak - -So far, we’ve demonstrated that calling `Rc::clone` increases the -`strong_count` of an `Rc` instance, and an `Rc` instance is only cleaned -up if its `strong_count` is 0. You can also create a *weak reference* to the -value within an `Rc` instance by calling `Rc::downgrade` and passing a -reference to the `Rc`. Strong references are how you can share ownership of -an `Rc` instance. Weak references don’t express an ownership relationship, -and their count doesn’t affect when an `Rc` instance is cleaned up. They -won’t cause a reference cycle because any cycle involving some weak references -will be broken once the strong reference count of values involved is 0. - -When you call `Rc::downgrade`, you get a smart pointer of type `Weak`. -Instead of increasing the `strong_count` in the `Rc` instance by 1, calling -`Rc::downgrade` increases the `weak_count` by 1. The `Rc` type uses -`weak_count` to keep track of how many `Weak` references exist, similar to -`strong_count`. The difference is the `weak_count` doesn’t need to be 0 for the -`Rc` instance to be cleaned up. - -Because the value that `Weak` references might have been dropped, to do -anything with the value that a `Weak` is pointing to you must make sure the -value still exists. Do this by calling the `upgrade` method on a `Weak` -instance, which will return an `Option>`. You’ll get a result of `Some` -if the `Rc` value has not been dropped yet and a result of `None` if the -`Rc` value has been dropped. Because `upgrade` returns an `Option>`, -Rust will ensure that the `Some` case and the `None` case are handled, and -there won’t be an invalid pointer. - -As an example, rather than using a list whose items know only about the next -item, we’ll create a tree whose items know about their children items *and* -their parent items. - -#### Creating a Tree Data Structure: A Node with Child Nodes - -To start, we’ll build a tree with nodes that know about their child nodes. -We’ll create a struct named `Node` that holds its own `i32` value as well as -references to its children `Node` values: - -Filename: src/main.rs - -``` -use std::cell::RefCell; -use std::rc::Rc; - -#[derive(Debug)] -struct Node { - value: i32, - children: RefCell>>, -} -``` - -We want a `Node` to own its children, and we want to share that ownership with -variables so we can access each `Node` in the tree directly. To do this, we -define the `Vec` items to be values of type `Rc`. We also want to -modify which nodes are children of another node, so we have a `RefCell` in -`children` around the `Vec>`. - -Next, we’ll use our struct definition and create one `Node` instance named -`leaf` with the value `3` and no children, and another instance named `branch` -with the value `5` and `leaf` as one of its children, as shown in Listing 15-27. - -Filename: src/main.rs - -``` -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)]), - }); -} -``` - -Listing 15-27: Creating a `leaf` node with no children and a `branch` node with -`leaf` as one of its children - -We clone the `Rc` in `leaf` and store that in `branch`, meaning the -`Node` in `leaf` now has two owners: `leaf` and `branch`. We can get from -`branch` to `leaf` through `branch.children`, but there’s no way to get from -`leaf` to `branch`. The reason is that `leaf` has no reference to `branch` and -doesn’t know they’re related. We want `leaf` to know that `branch` is its -parent. We’ll do that next. - -#### Adding a Reference from a Child to Its Parent - -To make the child node aware of its parent, we need to add a `parent` field to -our `Node` struct definition. The trouble is in deciding what the type of -`parent` should be. We know it can’t contain an `Rc` because that would -create a reference cycle with `leaf.parent` pointing to `branch` and -`branch.children` pointing to `leaf`, which would cause their `strong_count` -values to never be 0. - -Thinking about the relationships another way, a parent node should own its -children: if a parent node is dropped, its child nodes should be dropped as -well. However, a child should not own its parent: if we drop a child node, the -parent should still exist. This is a case for weak references! - -So, instead of `Rc`, we’ll make the type of `parent` use `Weak`, -specifically a `RefCell>`. Now our `Node` struct definition looks -like this: - -Filename: src/main.rs - -``` -use std::cell::RefCell; -use std::rc::{Rc, Weak}; - -#[derive(Debug)] -struct Node { - value: i32, - parent: RefCell>, - children: RefCell>>, -} -``` - -A node will be able to refer to its parent node but doesn’t own its parent. In -Listing 15-28, we update `main` to use this new definition so the `leaf` node -will have a way to refer to its parent, `branch`. - -Filename: src/main.rs - -``` -fn main() { - let leaf = Rc::new(Node { - value: 3, - 1 parent: RefCell::new(Weak::new()), - children: RefCell::new(vec![]), - }); - - 2 println!( - "leaf parent = {:?}", - leaf.parent.borrow().upgrade() - ); - - let branch = Rc::new(Node { - value: 5, - 3 parent: RefCell::new(Weak::new()), - children: RefCell::new(vec![Rc::clone(&leaf)]), - }); - - 4 *leaf.parent.borrow_mut() = Rc::downgrade(&branch); - - 5 println!( - "leaf parent = {:?}", - leaf.parent.borrow().upgrade() - ); -} -``` - -Listing 15-28: A `leaf` node with a weak reference to its parent node, `branch` - -Creating the `leaf` node looks similar to Listing 15-27 with the exception of -the `parent` field: `leaf` starts out without a parent, so we create a new, -empty `Weak` reference instance [1]. - -At this point, when we try to get a reference to the parent of `leaf` by using -the `upgrade` method, we get a `None` value. We see this in the output from the -first `println!` statement [2]: - -``` -leaf parent = None -``` - -When we create the `branch` node, it will also have a new `Weak` -reference in the `parent` field [3] because `branch` doesn’t have a parent -node. We still have `leaf` as one of the children of `branch`. Once we have the -`Node` instance in `branch`, we can modify `leaf` to give it a `Weak` -reference to its parent [4]. We use the `borrow_mut` method on the -`RefCell>` in the `parent` field of `leaf`, and then we use the -`Rc::downgrade` function to create a `Weak` reference to `branch` from -the `Rc` in `branch`. - -When we print the parent of `leaf` again [5], this time we’ll get a `Some` -variant holding `branch`: now `leaf` can access its parent! When we print -`leaf`, we also avoid the cycle that eventually ended in a stack overflow like -we had in Listing 15-26; the `Weak` references are printed as `(Weak)`: - -``` -leaf parent = Some(Node { value: 5, parent: RefCell { value: (Weak) }, -children: RefCell { value: [Node { value: 3, parent: RefCell { value: (Weak) }, -children: RefCell { value: [] } }] } }) -``` - -The lack of infinite output indicates that this code didn’t create a reference -cycle. We can also tell this by looking at the values we get from calling -`Rc::strong_count` and `Rc::weak_count`. - -#### Visualizing Changes to strong_count and weak_count - -Let’s look at how the `strong_count` and `weak_count` values of the `Rc` -instances change by creating a new inner scope and moving the creation of -`branch` into that scope. By doing so, we can see what happens when `branch` is -created and then dropped when it goes out of scope. The modifications are shown -in Listing 15-29. - -Filename: src/main.rs - -``` -fn main() { - let leaf = Rc::new(Node { - value: 3, - parent: RefCell::new(Weak::new()), - children: RefCell::new(vec![]), - }); - - 1 println!( - "leaf strong = {}, weak = {}", - Rc::strong_count(&leaf), - Rc::weak_count(&leaf), - ); - - 2 { - 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); - - 3 println!( - "branch strong = {}, weak = {}", - Rc::strong_count(&branch), - Rc::weak_count(&branch), - ); - - 4 println!( - "leaf strong = {}, weak = {}", - Rc::strong_count(&leaf), - Rc::weak_count(&leaf), - ); - 5 } - - 6 println!( - "leaf parent = {:?}", - leaf.parent.borrow().upgrade() - ); - 7 println!( - "leaf strong = {}, weak = {}", - Rc::strong_count(&leaf), - Rc::weak_count(&leaf), - ); -} -``` - -Listing 15-29: Creating `branch` in an inner scope and examining strong and -weak reference counts - -After `leaf` is created, its `Rc` has a strong count of 1 and a weak -count of 0 [1]. In the inner scope [2], we create `branch` and associate it -with `leaf`, at which point when we print the counts [3], the `Rc` in -`branch` will have a strong count of 1 and a weak count of 1 (for `leaf.parent` -pointing to `branch` with a `Weak`). When we print the counts in `leaf` -[4], we’ll see it will have a strong count of 2 because `branch` now has a -clone of the `Rc` of `leaf` stored in `branch.children`, but will still -have a weak count of 0. - -When the inner scope ends [5], `branch` goes out of scope and the strong count -of the `Rc` decreases to 0, so its `Node` is dropped. The weak count of 1 -from `leaf.parent` has no bearing on whether or not `Node` is dropped, so we -don’t get any memory leaks! - -If we try to access the parent of `leaf` after the end of the scope, we’ll get -`None` again [6]. At the end of the program [7], the `Rc` in `leaf` has a -strong count of 1 and a weak count of 0 because the variable `leaf` is now the -only reference to the `Rc` again. - -All of the logic that manages the counts and value dropping is built into -`Rc` and `Weak` and their implementations of the `Drop` trait. By -specifying that the relationship from a child to its parent should be a -`Weak` reference in the definition of `Node`, you’re able to have parent -nodes point to child nodes and vice versa without creating a reference cycle -and memory leaks. - -## Summary - -This chapter covered how to use smart pointers to make different guarantees and -trade-offs from those Rust makes by default with regular references. The -`Box` type has a known size and points to data allocated on the heap. The -`Rc` type keeps track of the number of references to data on the heap so -that data can have multiple owners. The `RefCell` type with its interior -mutability gives us a type that we can use when we need an immutable type but -need to change an inner value of that type; it also enforces the borrowing -rules at runtime instead of at compile time. - -Also discussed were the `Deref` and `Drop` traits, which enable a lot of the -functionality of smart pointers. We explored reference cycles that can cause -memory leaks and how to prevent them using `Weak`. - -If this chapter has piqued your interest and you want to implement your own -smart pointers, check out “The Rustonomicon” at -*https://doc.rust-lang.org/stable/nomicon* for more useful information. - -Next, we’ll talk about concurrency in Rust. You’ll even learn about a few new -smart pointers. - diff --git a/rustbook-en/nostarch/chapter16.md b/rustbook-en/nostarch/chapter16.md deleted file mode 100644 index 7c5389e4f..000000000 --- a/rustbook-en/nostarch/chapter16.md +++ /dev/null @@ -1,1226 +0,0 @@ - - -[TOC] - -# Fearless Concurrency - -Handling concurrent programming safely and efficiently is another of Rust’s -major goals. *Concurrent programming*, where different parts of a program -execute independently, and *parallel programming*, where different parts of a -program execute at the same time, are becoming increasingly important as more -computers take advantage of their multiple processors. Historically, -programming in these contexts has been difficult and error prone: Rust hopes to -change that. - -Initially, the Rust team thought that ensuring memory safety and preventing -concurrency problems were two separate challenges to be solved with different -methods. Over time, the team discovered that the ownership and type systems are -a powerful set of tools to help manage memory safety *and* concurrency -problems! By leveraging ownership and type checking, many concurrency errors -are compile-time errors in Rust rather than runtime errors. Therefore, rather -than making you spend lots of time trying to reproduce the exact circumstances -under which a runtime concurrency bug occurs, incorrect code will refuse to -compile and present an error explaining the problem. As a result, you can fix -your code while you’re working on it rather than potentially after it has been -shipped to production. We’ve nicknamed this aspect of Rust *fearless* -*concurrency*. Fearless concurrency allows you to write code that is free of -subtle bugs and is easy to refactor without introducing new bugs. - -> Note: For simplicity’s sake, we’ll refer to many of the problems as -*concurrent* rather than being more precise by saying *concurrent and/or -parallel*. If this book were about concurrency and/or parallelism, we’d be more -specific. For this chapter, please mentally substitute *concurrent and/or -parallel* whenever we use *concurrent*. - -Many languages are dogmatic about the solutions they offer for handling -concurrent problems. For example, Erlang has elegant functionality for -message-passing concurrency but has only obscure ways to share state between -threads. Supporting only a subset of possible solutions is a reasonable -strategy for higher-level languages because a higher-level language promises -benefits from giving up some control to gain abstractions. However, lower-level -languages are expected to provide the solution with the best performance in any -given situation and have fewer abstractions over the hardware. Therefore, Rust -offers a variety of tools for modeling problems in whatever way is appropriate -for your situation and requirements. - -Here are the topics we’ll cover in this chapter: - -* How to create threads to run multiple pieces of code at the same time -* *Message-passing* concurrency, where channels send messages between threads -* *Shared-state* concurrency, where multiple threads have access to some piece -of data -* The `Sync` and `Send` traits, which extend Rust’s concurrency guarantees to -user-defined types as well as types provided by the standard library - -## Using Threads to Run Code Simultaneously - -In most current operating systems, an executed program’s code is run in a -*process*, and the operating system will manage multiple processes at once. -Within a program, you can also have independent parts that run simultaneously. -The features that run these independent parts are called *threads*. For -example, a web server could have multiple threads so that it could respond to -more than one request at the same time. - -Splitting the computation in your program into multiple threads to run multiple -tasks at the same time can improve performance, but it also adds complexity. -Because threads can run simultaneously, there’s no inherent guarantee about the -order in which parts of your code on different threads will run. This can lead -to problems, such as: - -* Race conditions, where threads are accessing data or resources in an -inconsistent order -* Deadlocks, where two threads are waiting for each other, preventing both -threads from continuing -* Bugs that happen only in certain situations and are hard to reproduce and fix -reliably - -Rust attempts to mitigate the negative effects of using threads, but -programming in a multithreaded context still takes careful thought and requires -a code structure that is different from that in programs running in a single -thread. - -Programming languages implement threads in a few different ways, and many -operating systems provide an API the language can call for creating new -threads. The Rust standard library uses a *1:1* model of thread implementation, -whereby a program uses one operating system thread per one language thread. -There are crates that implement other models of threading that make different -trade-offs to the 1:1 model. - -### Creating a New Thread with spawn - -To create a new thread, we call the `thread::spawn` function and pass it a -closure (we talked about closures in Chapter 13) containing the code we want to -run in the new thread. The example in Listing 16-1 prints some text from a main -thread and other text from a new thread. - -Filename: src/main.rs - -``` -use std::thread; -use std::time::Duration; - -fn main() { - thread::spawn(|| { - for i in 1..10 { - println!("hi number {i} from the spawned thread!"); - thread::sleep(Duration::from_millis(1)); - } - }); - - for i in 1..5 { - println!("hi number {i} from the main thread!"); - thread::sleep(Duration::from_millis(1)); - } -} -``` - -Listing 16-1: Creating a new thread to print one thing while the main thread -prints something else - -Note that when the main thread of a Rust program completes, all spawned threads -are shut down, whether or not they have finished running. The output from this -program might be a little different every time, but it will look similar to the -following: - -``` -hi number 1 from the main thread! -hi number 1 from the spawned thread! -hi number 2 from the main thread! -hi number 2 from the spawned thread! -hi number 3 from the main thread! -hi number 3 from the spawned thread! -hi number 4 from the main thread! -hi number 4 from the spawned thread! -hi number 5 from the spawned thread! -``` - -The calls to `thread::sleep` force a thread to stop its execution for a short -duration, allowing a different thread to run. The threads will probably take -turns, but that isn’t guaranteed: it depends on how your operating system -schedules the threads. In this run, the main thread printed first, even though -the print statement from the spawned thread appears first in the code. And even -though we told the spawned thread to print until `i` is 9, it only got to 5 -before the main thread shut down. - -If you run this code and only see output from the main thread, or don’t see any -overlap, try increasing the numbers in the ranges to create more opportunities -for the operating system to switch between the threads. - -### Waiting for All Threads to Finish Using join Handles - -The code in Listing 16-1 not only stops the spawned thread prematurely most of -the time due to the main thread ending, but because there is no guarantee on -the order in which threads run, we also can’t guarantee that the spawned thread -will get to run at all! - -We can fix the problem of the spawned thread not running or of it ending -prematurely by saving the return value of `thread::spawn` in a variable. The -return type of `thread::spawn` is `JoinHandle`. A `JoinHandle` is an -owned value that, when we call the `join` method on it, will wait for its -thread to finish. Listing 16-2 shows how to use the `JoinHandle` of the -thread we created in Listing 16-1 and call `join` to make sure the spawned -thread finishes before `main` exits. - -Filename: src/main.rs - -``` -use std::thread; -use std::time::Duration; - -fn main() { - let handle = thread::spawn(|| { - for i in 1..10 { - println!("hi number {i} from the spawned thread!"); - thread::sleep(Duration::from_millis(1)); - } - }); - - for i in 1..5 { - println!("hi number {i} from the main thread!"); - thread::sleep(Duration::from_millis(1)); - } - - handle.join().unwrap(); -} -``` - -Listing 16-2: Saving a `JoinHandle` from `thread::spawn` to guarantee the -thread is run to completion - -Calling `join` on the handle blocks the thread currently running until the -thread represented by the handle terminates. *Blocking* a thread means that -thread is prevented from performing work or exiting. Because we’ve put the call -to `join` after the main thread’s `for` loop, running Listing 16-2 should -produce output similar to this: - -``` -hi number 1 from the main thread! -hi number 2 from the main thread! -hi number 1 from the spawned thread! -hi number 3 from the main thread! -hi number 2 from the spawned thread! -hi number 4 from the main thread! -hi number 3 from the spawned thread! -hi number 4 from the spawned thread! -hi number 5 from the spawned thread! -hi number 6 from the spawned thread! -hi number 7 from the spawned thread! -hi number 8 from the spawned thread! -hi number 9 from the spawned thread! -``` - -The two threads continue alternating, but the main thread waits because of the -call to `handle.join()` and does not end until the spawned thread is finished. - -But let’s see what happens when we instead move `handle.join()` before the -`for` loop in `main`, like this: - -Filename: src/main.rs - -``` -use std::thread; -use std::time::Duration; - -fn main() { - let handle = thread::spawn(|| { - for i in 1..10 { - println!("hi number {i} from the spawned thread!"); - thread::sleep(Duration::from_millis(1)); - } - }); - - handle.join().unwrap(); - - for i in 1..5 { - println!("hi number {i} from the main thread!"); - thread::sleep(Duration::from_millis(1)); - } -} -``` - -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: - -``` -hi number 1 from the spawned thread! -hi number 2 from the spawned thread! -hi number 3 from the spawned thread! -hi number 4 from the spawned thread! -hi number 5 from the spawned thread! -hi number 6 from the spawned thread! -hi number 7 from the spawned thread! -hi number 8 from the spawned thread! -hi number 9 from the spawned thread! -hi number 1 from the main thread! -hi number 2 from the main thread! -hi number 3 from the main thread! -hi number 4 from the main thread! -``` - -Small details, such as where `join` is called, can affect whether or not your -threads run at the same time. - -### Using move Closures with Threads - -We’ll often use the `move` keyword with closures passed to `thread::spawn` -because the closure will then take ownership of the values it uses from the -environment, thus transferring ownership of those values from one thread to -another. In “Capturing the Environment with Closures” on page XX, we discussed -`move` in the context of closures. Now we’ll concentrate more on the -interaction between `move` and `thread::spawn`. - -Notice in Listing 16-1 that the closure we pass to `thread::spawn` takes no -arguments: we’re not using any data from the main thread in the spawned -thread’s code. To use data from the main thread in the spawned thread, the -spawned thread’s closure must capture the values it needs. Listing 16-3 shows -an attempt to create a vector in the main thread and use it in the spawned -thread. However, this won’t work yet, as you’ll see in a moment. - -Filename: src/main.rs - -``` -use std::thread; - -fn main() { - let v = vec![1, 2, 3]; - - let handle = thread::spawn(|| { - println!("Here's a vector: {:?}", v); - }); - - handle.join().unwrap(); -} -``` - -Listing 16-3: Attempting to use a vector created by the main thread in another -thread - -The closure uses `v`, so it will capture `v` and make it part of the closure’s -environment. Because `thread::spawn` runs this closure in a new thread, we -should be able to access `v` inside that new thread. But when we compile this -example, we get the following error: - -``` -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 || { - | ++++ -``` - -Rust *infers* how to capture `v`, and because `println!` only needs a reference -to `v`, the closure tries to borrow `v`. However, there’s a problem: Rust can’t -tell how long the spawned thread will run, so it doesn’t know whether the -reference to `v` will always be valid. - -Listing 16-4 provides a scenario that’s more likely to have a reference to `v` -that won’t be valid. - -Filename: src/main.rs - -``` -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(); -} -``` - -Listing 16-4: A thread with a closure that attempts to capture a reference to -`v` from a main thread that drops `v` - -If Rust allowed us to run this code, there’s a possibility that the spawned -thread would be immediately put in the background without running at all. The -spawned thread has a reference to `v` inside, but the main thread immediately -drops `v`, using the `drop` function we discussed in Chapter 15. Then, when the -spawned thread starts to execute, `v` is no longer valid, so a reference to it -is also invalid. Oh no! - -To fix the compiler error in Listing 16-3, we can use the error message’s -advice: - -``` -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 || { - | ++++ -``` - -By adding the `move` keyword before the closure, we force the closure to take -ownership of the values it’s using rather than allowing Rust to infer that it -should borrow the values. The modification to Listing 16-3 shown in Listing -16-5 will compile and run as we intend. - -Filename: src/main.rs - -``` -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(); -} -``` - -Listing 16-5: Using the `move` keyword to force a closure to take ownership of -the values it uses - -We might be tempted to try the same thing to fix the code in Listing 16-4 where -the main thread called `drop` by using a `move` closure. However, this fix will -not work because what Listing 16-4 is trying to do is disallowed for a -different reason. If we added `move` to the closure, we 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: - -``` -error[E0382]: use of moved value: `v` - --> src/main.rs:10:10 - | -4 | let v = vec![1, 2, 3]; - | - move occurs because `v` has type `Vec`, which does not -implement the `Copy` trait -5 | -6 | let handle = thread::spawn(move || { - | ------- value moved into closure here -7 | println!("Here's a vector: {:?}", v); - | - variable moved due to use in -closure -... -10 | drop(v); // oh no! - | ^ value used here after move -``` - -Rust’s ownership rules have saved us again! We got an error from the code in -Listing 16-3 because Rust was being conservative and only borrowing `v` for the -thread, which meant the main thread could theoretically invalidate the spawned -thread’s reference. By telling Rust to move ownership of `v` to the spawned -thread, we’re guaranteeing Rust that the main thread won’t use `v` anymore. If -we change Listing 16-4 in the same way, we’re then violating the ownership -rules when we try to use `v` in the main thread. The `move` keyword overrides -Rust’s conservative default of borrowing; it doesn’t let us violate the -ownership rules. - -Now that we’ve covered what threads are and the methods supplied by the thread -API, let’s look at some situations in which we can use threads. - -## Using Message Passing to Transfer Data Between Threads - -One increasingly popular approach to ensuring safe concurrency is *message -passing*, where threads or actors communicate by sending each other messages -containing data. Here’s the idea in a slogan from the Go language documentation -at *https://golang.org/doc/effective_go.html#concurrency*: “Do not communicate -by sharing memory; instead, share memory by communicating.” - -To accomplish message-sending concurrency, Rust’s standard library provides an -implementation of *channels*. A channel is a general programming concept by -which data is sent from one thread to another. - -You can imagine a channel in programming as being like a directional channel of -water, such as a stream or a river. If you put something like a rubber duck -into a river, it will travel downstream to the end of the waterway. - -A channel has two halves: a transmitter and a receiver. The transmitter half is -the upstream location where you put the rubber duck into the river, and the -receiver half is where the rubber duck ends up downstream. One part of your -code calls methods on the transmitter with the data you want to send, and -another part checks the receiving end for arriving messages. A channel is said -to be *closed* if either the transmitter or receiver half is dropped. - -Here, we’ll work up to a program that has one thread to generate values and -send them down a channel, and another thread that will receive the values and -print them out. We’ll be sending simple values between threads using a channel -to illustrate the feature. Once you’re familiar with the technique, you could -use channels for any threads that need to communicate with each other, such as -a chat system or a system where many threads perform parts of a calculation and -send the parts to one thread that aggregates the results. - -First, in Listing 16-6, we’ll create a channel but not do anything with it. -Note that this won’t compile yet because Rust can’t tell what type of values we -want to send over the channel. - -Filename: src/main.rs - -``` -use std::sync::mpsc; - -fn main() { - let (tx, rx) = mpsc::channel(); -} -``` - -Listing 16-6: Creating a channel and assigning the two halves to `tx` and `rx` - -We create a new channel using the `mpsc::channel` function; `mpsc` stands for -*multiple producer, single consumer*. In short, the way Rust’s standard library -implements channels means a channel can have multiple *sending* ends that -produce values but only one *receiving* end that consumes those values. Imagine -multiple streams flowing together into one big river: everything sent down any -of the streams will end up in one river at the end. We’ll start with a single -producer for now, but we’ll add multiple producers when we get this example -working. - -The `mpsc::channel` function returns a tuple, the first element of which is the -sending end—the transmitter—and the second element of which is the receiving -end—the receiver. The abbreviations `tx` and `rx` are traditionally used in -many fields for *transmitter* and *receiver*, respectively, so we name our -variables as such to indicate each end. We’re using a `let` statement with a -pattern that destructures the tuples; we’ll discuss the use of patterns in -`let` statements and destructuring in Chapter 18. For now, know that using a -`let` statement in this way is a convenient approach to extract the pieces of -the tuple returned by `mpsc::channel`. - -Let’s move the transmitting end into a spawned thread and have it send one -string so the spawned thread is communicating with the main thread, as shown in -Listing 16-7. This is like putting a rubber duck in the river upstream or -sending a chat message from one thread to another. - -Filename: src/main.rs - -``` -use std::sync::mpsc; -use std::thread; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let val = String::from("hi"); - tx.send(val).unwrap(); - }); -} -``` - -Listing 16-7: Moving `tx` to a spawned thread and sending `"hi"` - -Again, we’re using `thread::spawn` to create a new thread and then using `move` -to move `tx` into the closure so the spawned thread owns `tx`. The spawned -thread needs to own the transmitter to be able to send messages through the -channel. - -The transmitter has a `send` method that takes the value we want to send. The -`send` method returns a `Result` type, so if the receiver has already -been dropped and there’s nowhere to send a value, the send operation will -return an error. In this example, we’re calling `unwrap` to panic in case of an -error. But in a real application, we would handle it properly: return to -Chapter 9 to review strategies for proper error handling. - -In Listing 16-8, we’ll get the value from the receiver in the main thread. This -is like retrieving the rubber duck from the water at the end of the river or -receiving a chat message. - -Filename: src/main.rs - -``` -use std::sync::mpsc; -use std::thread; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let val = String::from("hi"); - tx.send(val).unwrap(); - }); - - let received = rx.recv().unwrap(); - println!("Got: {received}"); -} -``` - -Listing 16-8: Receiving the value `"hi"` in the main thread and printing it - -The receiver has two useful methods: `recv` and `try_recv`. We’re using `recv`, -short for *receive*, which will block the main thread’s execution and wait -until a value is sent down the channel. Once a value is sent, `recv` will -return it in a `Result`. When the transmitter closes, `recv` will return -an error to signal that no more values will be coming. - -The `try_recv` method doesn’t block, but will instead return a `Result` -immediately: an `Ok` value holding a message if one is available and an `Err` -value if there aren’t any messages this time. Using `try_recv` is useful if -this thread has other work to do while waiting for messages: we could write a -loop that calls `try_recv` every so often, handles a message if one is -available, and otherwise does other work for a little while until checking -again. - -We’ve used `recv` in this example for simplicity; we don’t have any other work -for the main thread to do other than wait for messages, so blocking the main -thread is appropriate. - -When we run the code in Listing 16-8, we’ll see the value printed from the main -thread: - -``` -Got: hi -``` - -Perfect! - -### Channels and Ownership Transference - -The ownership rules play a vital role in message sending because they help you -write safe, concurrent code. Preventing errors in concurrent programming is the -advantage of thinking about ownership throughout your Rust programs. Let’s do -an experiment to show how channels and ownership work together to prevent -problems: we’ll try to use a `val` value in the spawned thread *after* we’ve -sent it down the channel. Try compiling the code in Listing 16-9 to see why -this code isn’t allowed. - -Filename: src/main.rs - -``` -use std::sync::mpsc; -use std::thread; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let val = String::from("hi"); - tx.send(val).unwrap(); - println!("val is {val}"); - }); - - let received = rx.recv().unwrap(); - println!("Got: {received}"); -} -``` - -Listing 16-9: Attempting to use `val` after we’ve sent it down the channel - -Here, we try to print `val` after we’ve sent it down the channel via `tx.send`. -Allowing this would be a bad idea: once the value has been sent to another -thread, that thread could modify or drop it before we try to use the value -again. Potentially, the other thread’s modifications could cause errors or -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: - -``` -error[E0382]: borrow of moved value: `val` - --> src/main.rs:10:31 - | -8 | let val = String::from("hi"); - | --- move occurs because `val` has type `String`, which does -not implement the `Copy` trait -9 | tx.send(val).unwrap(); - | --- value moved here -10 | println!("val is {val}"); - | ^^^ value borrowed here after move -``` - -Our concurrency mistake has caused a compile-time error. The `send` function -takes ownership of its parameter, and when the value is moved the receiver -takes ownership of it. This stops us from accidentally using the value again -after sending it; the ownership system checks that everything is okay. - -### Sending Multiple Values and Seeing the Receiver Waiting - -The code in Listing 16-8 compiled and ran, but it didn’t clearly show us that -two separate threads were talking to each other over the channel. In Listing -16-10 we’ve made some modifications that will prove the code in Listing 16-8 is -running concurrently: the spawned thread will now send multiple messages and -pause for a second between each message. - -Filename: src/main.rs - -``` -use std::sync::mpsc; -use std::thread; -use std::time::Duration; - -fn main() { - let (tx, rx) = mpsc::channel(); - - thread::spawn(move || { - let vals = vec![ - String::from("hi"), - String::from("from"), - String::from("the"), - String::from("thread"), - ]; - - for val in vals { - tx.send(val).unwrap(); - thread::sleep(Duration::from_secs(1)); - } - }); - - for received in rx { - println!("Got: {received}"); - } -} -``` - -Listing 16-10: Sending multiple messages and pausing between each one - -This time, the spawned thread has a vector of strings that we want to send to -the main thread. We iterate over them, sending each individually, and pause -between each by calling the `thread::sleep` function with a `Duration` value of -one second. - -In the main thread, we’re not calling the `recv` function explicitly anymore: -instead, we’re treating `rx` as an iterator. For each value received, we’re -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 one-second pause in between each line: - -``` -Got: hi -Got: from -Got: the -Got: thread -``` - -Because we don’t have any code that pauses or delays in the `for` loop in the -main thread, we can tell that the main thread is waiting to receive values from -the spawned thread. - -### Creating Multiple Producers by Cloning the Transmitter - -Earlier we mentioned that `mpsc` was an acronym for *multiple producer, single -consumer*. Let’s put `mpsc` to use and expand the code in Listing 16-10 to -create multiple threads that all send values to the same receiver. We can do so -by cloning the transmitter, as shown in Listing 16-11. - -Filename: src/main.rs - -``` ---snip-- - -let (tx, rx) = mpsc::channel(); - -let tx1 = tx.clone(); -thread::spawn(move || { - let vals = vec![ - String::from("hi"), - String::from("from"), - String::from("the"), - String::from("thread"), - ]; - - for val in vals { - tx1.send(val).unwrap(); - thread::sleep(Duration::from_secs(1)); - } -}); - -thread::spawn(move || { - let vals = vec![ - String::from("more"), - String::from("messages"), - String::from("for"), - String::from("you"), - ]; - - for val in vals { - tx.send(val).unwrap(); - thread::sleep(Duration::from_secs(1)); - } -}); - -for received in rx { - println!("Got: {received}"); -} - ---snip-- -``` - -Listing 16-11: Sending multiple messages from multiple producers - -This time, before we create the first spawned thread, we call `clone` on the -transmitter. This will give us a new transmitter we can pass to the first -spawned thread. We pass the original transmitter to a second spawned thread. -This gives us two threads, each sending different messages to the one receiver. - -When you run the code, your output should look something like this: - -``` -Got: hi -Got: more -Got: from -Got: messages -Got: for -Got: the -Got: thread -Got: you -``` - -You might see the values in another order, depending on your system. This is -what makes concurrency interesting as well as difficult. If you experiment with -`thread::sleep`, giving it various values in the different threads, each run -will be more nondeterministic and create different output each time. - -Now that we’ve looked at how channels work, let’s look at a different method of -concurrency. - -## Shared-State Concurrency - -Message passing is a fine way to handle concurrency, but it’s not the only way. -Another method would be for multiple threads to access the same shared data. -Consider this part of the slogan from the Go language documentation again: “Do -not communicate by sharing memory.” - -What would communicating by sharing memory look like? In addition, why would -message-passing enthusiasts caution not to use memory sharing? - -In a way, channels in any programming language are similar to single ownership -because once you transfer a value down a channel, you should no longer use that -value. Shared-memory concurrency is like multiple ownership: multiple threads -can access the same memory location at the same time. As you saw in Chapter 15, -where smart pointers made multiple ownership possible, multiple ownership can -add complexity because these different owners need managing. Rust’s type system -and ownership rules greatly assist in getting this management correct. For an -example, let’s look at mutexes, one of the more common concurrency primitives -for shared memory. - -### Using Mutexes to Allow Access to Data from One Thread at a Time - -*Mutex* is an abbreviation for *mutual exclusion*, as in a mutex allows only -one thread to access some data at any given time. To access the data in a -mutex, a thread must first signal that it wants access by asking to acquire the -mutex’s *lock*. The lock is a data structure that is part of the mutex that -keeps track of who currently has exclusive access to the data. Therefore, the -mutex is described as *guarding* the data it holds via the locking system. - -Mutexes have a reputation for being difficult to use because you have to -remember two rules: - -1. You must attempt to acquire the lock before using the data. -1. When you’re done with the data that the mutex guards, you must unlock the -data so other threads can acquire the lock. - -For a real-world metaphor for a mutex, imagine a panel discussion at a -conference with only one microphone. Before a panelist can speak, they have to -ask or signal that they want to use the microphone. When they get the -microphone, they can talk for as long as they want to and then hand the -microphone to the next panelist who requests to speak. If a panelist forgets to -hand the microphone off when they’re finished with it, no one else is able to -speak. If management of the shared microphone goes wrong, the panel won’t work -as planned! - -Management of mutexes can be incredibly tricky to get right, which is why so -many people are enthusiastic about channels. However, thanks to Rust’s type -system and ownership rules, you can’t get locking and unlocking wrong. - -#### The API of Mutex - -As an example of how to use a mutex, let’s start by using a mutex in a -single-threaded context, as shown in Listing 16-12. - -Filename: src/main.rs - -``` -use std::sync::Mutex; - -fn main() { - 1 let m = Mutex::new(5); - - { - 2 let mut num = m.lock().unwrap(); - 3 *num = 6; - 4 } - - 5 println!("m = {:?}", m); -} -``` - -Listing 16-12: Exploring the API of `Mutex` in a single-threaded context for -simplicity - -As with many types, we create a `Mutex` using the associated function `new` -[1]. To access the data inside the mutex, we use the `lock` method to acquire -the lock [2]. This call will block the current thread so it can’t do any work -until it’s our turn to have the lock. - -The call to `lock` would fail if another thread holding the lock panicked. In -that case, no one would ever be able to get the lock, so we’ve chosen to -`unwrap` and have this thread panic if we’re in that situation. - -After we’ve acquired the lock, we can treat the return value, named `num` in -this case, as a mutable reference to the data inside. The type system ensures -that we acquire a lock before using the value in `m`. The type of `m` is -`Mutex`, not `i32`, so we *must* call `lock` to be able to use the `i32` -value. We can’t forget; the type system won’t let us access the inner `i32` -otherwise. - -As you might suspect, `Mutex` is a smart pointer. More accurately, the call -to `lock` *returns* a smart pointer called `MutexGuard`, wrapped in a -`LockResult` that we handled with the call to `unwrap`. The `MutexGuard` smart -pointer implements `Deref` to point at our inner data; the smart pointer also -has a `Drop` implementation that releases the lock automatically when a -`MutexGuard` goes out of scope, which happens at the end of the inner scope -[4]. As a result, we don’t risk forgetting to release the lock and blocking the -mutex from being used by other threads because the lock release happens -automatically. - -After dropping the lock, we can print the mutex value and see that we were able -to change the inner `i32` to `6` [5]. - -#### Sharing a Mutex Between Multiple Threads - -Now let’s try to share a value between multiple threads using `Mutex`. We’ll -spin up 10 threads and have them each increment a counter value by 1, so the -counter goes from 0 to 10. The example in Listing 16-13 will have a compiler -error, and we’ll use that error to learn more about using `Mutex` and how -Rust helps us use it correctly. - -Filename: src/main.rs - -``` -use std::sync::Mutex; -use std::thread; - -fn main() { - 1 let counter = Mutex::new(0); - let mut handles = vec![]; - - 2 for _ in 0..10 { - 3 let handle = thread::spawn(move || { - 4 let mut num = counter.lock().unwrap(); - - 5 *num += 1; - }); - 6 handles.push(handle); - } - - for handle in handles { - 7 handle.join().unwrap(); - } - - 8 println!("Result: {}", *counter.lock().unwrap()); -} -``` - -Listing 16-13: Ten threads, each incrementing a counter guarded by a `Mutex` - -We create a `counter` variable to hold an `i32` inside a `Mutex` [1], as we -did in Listing 16-12. Next, we create 10 threads by iterating over a range of -numbers [2]. We use `thread::spawn` and give all the threads the same closure: -one that moves the counter into the thread [3], acquires a lock on the -`Mutex` by calling the `lock` method [4], and then adds 1 to the value in -the mutex [5]. When a thread finishes running its closure, `num` will go out of -scope and release the lock so another thread can acquire it. - -In the main thread, we collect all the join handles [6]. Then, as we did in -Listing 16-2, we call `join` on each handle to make sure all the threads finish -[7]. At that point, the main thread will acquire the lock and print the result -of this program [8]. - -We hinted that this example wouldn’t compile. Now let’s find out why! - -``` -error[E0382]: use of moved value: `counter` - --> src/main.rs:9:36 - | -5 | let counter = Mutex::new(0); - | ------- move occurs because `counter` has type `Mutex`, which -does not implement the `Copy` trait -... -9 | let handle = thread::spawn(move || { - | ^^^^^^^ value moved into closure here, -in previous iteration of loop -10 | let mut num = counter.lock().unwrap(); - | ------- use occurs due to use in closure -``` - -The error message states that the `counter` value was moved in the previous -iteration of the loop. Rust is telling us that we can’t move the ownership of -lock `counter` into multiple threads. Let’s fix the compiler error with the -multiple-ownership method we discussed in Chapter 15. - -#### Multiple Ownership with Multiple Threads - -In Chapter 15, we gave a value to multiple owners by using the smart pointer -`Rc` to create a reference counted value. Let’s do the same here and see -what happens. We’ll wrap the `Mutex` in `Rc` in Listing 16-14 and clone -the `Rc` before moving ownership to the thread. - -Filename: src/main.rs - -``` -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()); -} -``` - -Listing 16-14: Attempting to use `Rc` to allow multiple threads to own the -`Mutex` - -Once again, we compile and get… different errors! The compiler is teaching us a -lot. - -``` -error[E0277]: `Rc>` cannot be sent between threads safely 1 - --> src/main.rs:11:22 - | -11 | let handle = thread::spawn(move || { - | ______________________^^^^^^^^^^^^^_- - | | | - | | `Rc>` cannot be sent between threads -safely -12 | | let mut num = counter.lock().unwrap(); -13 | | -14 | | *num += 1; -15 | | }); - | |_________- within this `[closure@src/main.rs:11:36: 15:10]` - | -= help: within `[closure@src/main.rs:11:36: 15:10]`, the trait `Send` is not -implemented for `Rc>` 2 - = note: required because it appears within the type -`[closure@src/main.rs:11:36: 15:10]` -note: required by a bound in `spawn` -``` - -Wow, that error message is very wordy! Here’s the important part to focus on: -``Rc>` cannot be sent between threads safely` [1]. The compiler is -also telling us the reason why: `the trait `Send` is not implemented for -`Rc>`` [2]. We’ll talk about `Send` in the next section: it’s one of -the traits that ensures the types we use with threads are meant for use in -concurrent situations. - -Unfortunately, `Rc` is not safe to share across threads. When `Rc` -manages the reference count, it adds to the count for each call to `clone` and -subtracts from the count when each clone is dropped. But it doesn’t use any -concurrency primitives to make sure that changes to the count can’t be -interrupted by another thread. This could lead to wrong counts—subtle bugs that -could in turn lead to memory leaks or a value being dropped before we’re done -with it. What we need is a type exactly like `Rc` but one that makes changes -to the reference count in a thread-safe way. - -#### Atomic Reference Counting with Arc - -Fortunately, `Arc` *is* a type like `Rc` that is safe to use in -concurrent situations. The *a* stands for *atomic*, meaning it’s an *atomically -reference counted* type. Atomics are an additional kind of concurrency -primitive that we won’t cover in detail here: see the standard library -documentation for `std::sync::atomic` for more details. At this point, you just -need to know that atomics work like primitive types but are safe to share -across threads. - -You might then wonder why all primitive types aren’t atomic and why standard -library types aren’t implemented to use `Arc` by default. The reason is that -thread safety comes with a performance penalty that you only want to pay when -you really need to. If you’re just performing operations on values within a -single thread, your code can run faster if it doesn’t have to enforce the -guarantees atomics provide. - -Let’s return to our example: `Arc` and `Rc` have the same API, so we fix -our program by changing the `use` line, the call to `new`, and the call to -`clone`. The code in Listing 16-15 will finally compile and run. - -Filename: src/main.rs - -``` -use std::sync::{Arc, Mutex}; -use std::thread; - -fn main() { - let counter = Arc::new(Mutex::new(0)); - let mut handles = vec![]; - - for _ in 0..10 { - let counter = Arc::clone(&counter); - let handle = thread::spawn(move || { - let mut num = counter.lock().unwrap(); - - *num += 1; - }); - handles.push(handle); - } - - for handle in handles { - handle.join().unwrap(); - } - - println!("Result: {}", *counter.lock().unwrap()); -} -``` - -Listing 16-15: Using an `Arc` to wrap the `Mutex` to be able to share -ownership across multiple threads - -This code will print the following: - -``` -Result: 10 -``` - -We did it! We counted from 0 to 10, which may not seem very impressive, but it -did teach us a lot about `Mutex` and thread safety. You could also use this -program’s structure to do more complicated operations than just incrementing a -counter. Using this strategy, you can divide a calculation into independent -parts, split those parts across threads, and then use a `Mutex` to have each -thread update the final result with its part. - -Note that if you are doing simple numerical operations, there are types simpler -than `Mutex` types provided by the `std::sync::atomic` module of the -standard library. These types provide safe, concurrent, atomic access to -primitive types. We chose to use `Mutex` with a primitive type for this -example so we could concentrate on how `Mutex` works. - -### Similarities Between RefCell/Rc and Mutex/Arc - -You might have noticed that `counter` is immutable but we could get a mutable -reference to the value inside it; this means `Mutex` provides interior -mutability, as the `Cell` family does. In the same way we used `RefCell` in -Chapter 15 to allow us to mutate contents inside an `Rc`, we use `Mutex` -to mutate contents inside an `Arc`. - -Another detail to note is that Rust can’t protect you from all kinds of logic -errors when you use `Mutex`. Recall in Chapter 15 that using `Rc` came -with the risk of creating reference cycles, where two `Rc` values refer to -each other, causing memory leaks. Similarly, `Mutex` comes with the risk of -creating *deadlocks*. These occur when an operation needs to lock two resources -and two threads have each acquired one of the locks, causing them to wait for -each other forever. If you’re interested in deadlocks, try creating a Rust -program that has a deadlock; then research deadlock mitigation strategies for -mutexes in any language and have a go at implementing them in Rust. The -standard library API documentation for `Mutex` and `MutexGuard` offers -useful information. - -We’ll round out this chapter by talking about the `Send` and `Sync` traits and -how we can use them with custom types. - -## Extensible Concurrency with the Send and Sync Traits - -Interestingly, the Rust language has *very* few concurrency features. Almost -every concurrency feature we’ve talked about so far in this chapter has been -part of the standard library, not the language. Your options for handling -concurrency are not limited to the language or the standard library; you can -write your own concurrency features or use those written by others. - -However, two concurrency concepts are embedded in the language: the -`std::marker` traits `Send` and `Sync` . - -### Allowing Transference of Ownership Between Threads with Send - -The `Send` marker trait indicates that ownership of values of the type -implementing `Send` can be transferred between threads. Almost every Rust type -is `Send`, but there are some exceptions, including `Rc`: this cannot be -`Send` because if you cloned an `Rc` value and tried to transfer ownership -of the clone to another thread, both threads might update the reference count -at the same time. For this reason, `Rc` is implemented for use in -single-threaded situations where you don’t want to pay the thread-safe -performance penalty. - -Therefore, Rust’s type system and trait bounds ensure that you can never -accidentally send an `Rc` value across threads unsafely. When we tried to do -this in Listing 16-14, we got the error `the trait `Send` is not implemented -for `Rc>``. When we switched to `Arc`, which is `Send`, the code -compiled. - -Any type composed entirely of `Send` types is automatically marked as `Send` as -well. Almost all primitive types are `Send`, aside from raw pointers, which -we’ll discuss in Chapter 19. - -### Allowing Access from Multiple Threads with Sync - -The `Sync` marker trait indicates that it is safe for the type implementing -`Sync` to be referenced from multiple threads. In other words, any type `T` is -`Sync` if `&T` (an immutable reference to `T`) is `Send`, meaning the reference -can be sent safely to another thread. Similar to `Send`, primitive types are -`Sync`, and types composed entirely of types that are `Sync` are also `Sync`. - -The smart pointer `Rc` is also not `Sync` for the same reasons that it’s not -`Send`. The `RefCell` type (which we talked about in Chapter 15) and the -family of related `Cell` types are not `Sync`. The implementation of borrow -checking that `RefCell` does at runtime is not thread-safe. The smart -pointer `Mutex` is `Sync` and can be used to share access with multiple -threads, as you saw in “Sharing a Mutex Between Multiple Threads” on page XX. - -### Implementing Send and Sync Manually Is Unsafe - -Because types that are made up of `Send` and `Sync` traits are automatically -also `Send` and `Sync`, we don’t have to implement those traits manually. As -marker traits, they don’t even have any methods to implement. They’re just -useful for enforcing invariants related to concurrency. - -Manually implementing these traits involves implementing unsafe Rust code. -We’ll talk about using unsafe Rust code in Chapter 19; for now, the important -information is that building new concurrent types not made up of `Send` and -`Sync` parts requires careful thought to uphold the safety guarantees. “The -Rustonomicon” at *https://doc.rust-lang.org/stable/nomicon* has more -information about these guarantees and how to uphold them. - -## Summary - -This isn’t the last you’ll see of concurrency in this book: the project in -Chapter 20 will use the concepts in this chapter in a more realistic situation -than the smaller examples discussed here. - -As mentioned earlier, because very little of how Rust handles concurrency is -part of the language, many concurrency solutions are implemented as crates. -These evolve more quickly than the standard library, so be sure to search -online for the current, state-of-the-art crates to use in multithreaded -situations. - -The Rust standard library provides channels for message passing and smart -pointer types, such as `Mutex` and `Arc`, that are safe to use in -concurrent contexts. The type system and the borrow checker ensure that the -code using these solutions won’t end up with data races or invalid references. -Once you get your code to compile, you can rest assured that it will happily -run on multiple threads without the kinds of hard-to-track-down bugs common in -other languages. Concurrent programming is no longer a concept to be afraid of: -go forth and make your programs concurrent, fearlessly! - -Next, we’ll talk about idiomatic ways to model problems and structure solutions -as your Rust programs get bigger. In addition, we’ll discuss how Rust’s idioms -relate to those you might be familiar with from object-oriented programming. - diff --git a/rustbook-en/nostarch/chapter17.md b/rustbook-en/nostarch/chapter17.md deleted file mode 100644 index 946d20a11..000000000 --- a/rustbook-en/nostarch/chapter17.md +++ /dev/null @@ -1,1233 +0,0 @@ - - -[TOC] - -# Object-Oriented Programming Features - -Object-oriented programming (OOP) is a way of modeling programs. Objects as a -programmatic concept were introduced in the programming language Simula in the -1960s. Those objects influenced Alan Kay’s programming architecture in which -objects pass messages to each other. To describe this architecture, he coined -the term *object-oriented programming* in 1967. Many competing definitions -describe what OOP is, and by some of these definitions Rust is object oriented -but by others it is not. In this chapter, we’ll explore certain characteristics -that are commonly considered object oriented and how those characteristics -translate to idiomatic Rust. We’ll then show you how to implement an -object-oriented design pattern in Rust and discuss the trade-offs of doing so -versus implementing a solution using some of Rust’s strengths instead. - -## Characteristics of Object-Oriented Languages - -There is no consensus in the programming community about what features a -language must have to be considered object oriented. Rust is influenced by many -programming paradigms, including OOP; for example, we explored the features -that came from functional programming in Chapter 13. Arguably, OOP languages -share certain common characteristics, namely objects, encapsulation, and -inheritance. Let’s look at what each of those characteristics means and whether -Rust supports it. - -### Objects Contain Data and Behavior - -The book *Design Patterns: Elements of Reusable Object-Oriented Software* by -Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (Addison-Wesley, -1994), colloquially referred to as *The Gang of Four* book, is a catalog of -object-oriented design patterns. It defines OOP in this way: - -Object-oriented programs are made up of objects. An *object* packages both data -and the procedures that operate on that data. The procedures are typically -called *methods* or *operations*. - -Using this definition, Rust is object oriented: structs and enums have data, -and `impl` blocks provide methods on structs and enums. Even though structs and -enums with methods aren’t *called* objects, they provide the same -functionality, according to the Gang of Four’s definition of objects. - -### Encapsulation That Hides Implementation Details - -Another aspect commonly associated with OOP is the idea of *encapsulation*, -which means that the implementation details of an object aren’t accessible to -code using that object. Therefore, the only way to interact with an object is -through its public API; code using the object shouldn’t be able to reach into -the object’s internals and change data or behavior directly. This enables the -programmer to change and refactor an object’s internals without needing to -change the code that uses the object. - -We discussed how to control encapsulation in Chapter 7: we can use the `pub` -keyword to decide which modules, types, functions, and methods in our code -should be public, and by default everything else is private. For example, we -can define a struct `AveragedCollection` that has a field containing a vector -of `i32` values. The struct can also have a field that contains the average of -the values in the vector, meaning the average doesn’t have to be computed on -demand whenever anyone needs it. In other words, `AveragedCollection` will -cache the calculated average for us. Listing 17-1 has the definition of the -`AveragedCollection` struct. - -Filename: src/lib.rs - -``` -pub struct AveragedCollection { - list: Vec, - average: f64, -} -``` - -Listing 17-1: An `AveragedCollection` struct that maintains a list of integers -and the average of the items in the collection - -The struct is marked `pub` so that other code can use it, but the fields within -the struct remain private. This is important in this case because we want to -ensure that whenever a value is added or removed from the list, the average is -also updated. We do this by implementing `add`, `remove`, and `average` methods -on the struct, as shown in Listing 17-2. - -Filename: src/lib.rs - -``` -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; - } -} -``` - -Listing 17-2: Implementations of the public methods `add`, `remove`, and -`average` on `AveragedCollection` - -The public methods `add`, `remove`, and `average` are the only ways to access -or modify data in an instance of `AveragedCollection`. When an item is added to -`list` using the `add` method or removed using the `remove` method, the -implementations of each call the private `update_average` method that handles -updating the `average` field as well. - -We leave the `list` and `average` fields private so there is no way for -external code to add or remove items to or from the `list` field directly; -otherwise, the `average` field might become out of sync when the `list` -changes. The `average` method returns the value in the `average` field, -allowing external code to read the `average` but not modify it. - -Because we’ve encapsulated the implementation details of the struct -`AveragedCollection`, we can easily change aspects, such as the data structure, -in the future. For instance, we could use a `HashSet` instead of a -`Vec` for the `list` field. As long as the signatures of the `add`, -`remove`, and `average` public methods stayed the same, code using -`AveragedCollection` wouldn’t need to change. If we made `list` public instead, -this wouldn’t necessarily be the case: `HashSet` and `Vec` have -different methods for adding and removing items, so the external code would -likely have to change if it were modifying `list` directly. - -If encapsulation is a required aspect for a language to be considered object -oriented, then Rust meets that requirement. The option to use `pub` or not for -different parts of code enables encapsulation of implementation details. - -### Inheritance as a Type System and as Code Sharing - -*Inheritance* is a mechanism whereby an object can inherit elements from -another object’s definition, thus gaining the parent object’s data and behavior -without you having to define them again. - -If a language must have inheritance to be object oriented, then Rust is not -such a language. There is no way to define a struct that inherits the parent -struct’s fields and method implementations without using a macro. - -However, if you’re used to having inheritance in your programming toolbox, you -can use other solutions in Rust, depending on your reason for reaching for -inheritance in the first place. - -You would choose inheritance for two main reasons. One is for reuse of code: -you can implement particular behavior for one type, and inheritance enables you -to reuse that implementation for a different type. You can do this in a limited -way in Rust code using default trait method implementations, which you saw in -Listing 10-14 when we added a default implementation of the `summarize` method -on the `Summary` trait. Any type implementing the `Summary` trait would have -the `summarize` method available on it without any further code. This is -similar to a parent class having an implementation of a method and an -inheriting child class also having the implementation of the method. We can -also override the default implementation of the `summarize` method when we -implement the `Summary` trait, which is similar to a child class overriding the -implementation of a method inherited from a parent class. - -The other reason to use inheritance relates to the type system: to enable a -child type to be used in the same places as the parent type. This is also -called *polymorphism*, which means that you can substitute multiple objects for -each other at runtime if they share certain characteristics. - -> ### Polymorphism -> -> To many people, polymorphism is synonymous with inheritance. But it’s -actually a more general concept that refers to code that can work with data of -multiple types. For inheritance, those types are generally subclasses. -> -> Rust instead uses generics to abstract over different possible types and -trait bounds to impose constraints on what those types must provide. This is -sometimes called *bounded parametric polymorphism*. - -Inheritance has recently fallen out of favor as a programming design solution -in many programming languages because it’s often at risk of sharing more code -than necessary. Subclasses shouldn’t always share all characteristics of their -parent class but will do so with inheritance. This can make a program’s design -less flexible. It also introduces the possibility of calling methods on -subclasses that don’t make sense or that cause errors because the methods don’t -apply to the subclass. In addition, some languages will only allow single -inheritance (meaning a subclass can only inherit from one class), further -restricting the flexibility of a program’s design. - -For these reasons, Rust takes the different approach of using trait objects -instead of inheritance. Let’s look at how trait objects enable polymorphism in -Rust. - -## Using Trait Objects That Allow for Values of Different Types - -In Chapter 8, we mentioned that one limitation of vectors is that they can -store elements of only one type. We created a workaround in Listing 8-9 where -we defined a `SpreadsheetCell` enum that had variants to hold integers, floats, -and text. This meant we could store different types of data in each cell and -still have a vector that represented a row of cells. This is a perfectly good -solution when our interchangeable items are a fixed set of types that we know -when our code is compiled. - -However, sometimes we want our library user to be able to extend the set of -types that are valid in a particular situation. To show how we might achieve -this, we’ll create an example graphical user interface (GUI) tool that iterates -through a list of items, calling a `draw` method on each one to draw it to the -screen—a common technique for GUI tools. We’ll create a library crate called -`gui` that contains the structure of a GUI library. This crate might include -some types for people to use, such as `Button` or `TextField`. In addition, -`gui` users will want to create their own types that can be drawn: for -instance, one programmer might add an `Image` and another might add a -`SelectBox`. - -We won’t implement a full-fledged GUI library for this example but will show -how the pieces would fit together. At the time of writing the library, we can’t -know and define all the types other programmers might want to create. But we do -know that `gui` needs to keep track of many values of different types, and it -needs to call a `draw` method on each of these differently typed values. It -doesn’t need to know exactly what will happen when we call the `draw` method, -just that the value will have that method available for us to call. - -To do this in a language with inheritance, we might define a class named -`Component` that has a method named `draw` on it. The other classes, such as -`Button`, `Image`, and `SelectBox`, would inherit from `Component` and thus -inherit the `draw` method. They could each override the `draw` method to define -their custom behavior, but the framework could treat all of the types as if -they were `Component` instances and call `draw` on them. But because Rust -doesn’t have inheritance, we need another way to structure the `gui` library to -allow users to extend it with new types. - -### Defining a Trait for Common Behavior - -To implement the behavior we want `gui` to have, we’ll define a trait named -`Draw` that will have one method named `draw`. Then we can define a vector that -takes a *trait object*. A trait object points to both an instance of a type -implementing our specified trait and a table used to look up trait methods on -that type at runtime. We create a trait object by specifying some sort of -pointer, such as a `&` reference or a `Box` smart pointer, then the `dyn` -keyword, and then specifying the relevant trait. (We’ll talk about the reason -trait objects must use a pointer in “Dynamically Sized Types and the Sized -Trait” on page XX.) We can use trait objects in place of a generic or concrete -type. Wherever we use a trait object, Rust’s type system will ensure at compile -time that any value used in that context will implement the trait object’s -trait. Consequently, we don’t need to know all the possible types at compile -time. - -We’ve mentioned that, in Rust, we refrain from calling structs and enums -“objects” to distinguish them from other languages’ objects. In a struct or -enum, the data in the struct fields and the behavior in `impl` blocks are -separated, whereas in other languages, the data and behavior combined into one -concept is often labeled an object. However, trait objects *are* more like -objects in other languages in the sense that they combine data and behavior. -But trait objects differ from traditional objects in that we can’t add data to -a trait object. Trait objects aren’t as generally useful as objects in other -languages: their specific purpose is to allow abstraction across common -behavior. - -Listing 17-3 shows how to define a trait named `Draw` with one method named -`draw`. - -Filename: src/lib.rs - -``` -pub trait Draw { - fn draw(&self); -} -``` - -Listing 17-3: Definition of the `Draw` trait - -This syntax should look familiar from our discussions on how to define traits -in Chapter 10. Next comes some new syntax: Listing 17-4 defines a struct named -`Screen` that holds a vector named `components`. This vector is of type -`Box`, which is a trait object; it’s a stand-in for any type inside a -`Box` that implements the `Draw` trait. - -Filename: src/lib.rs - -``` -pub struct Screen { - pub components: Vec>, -} -``` - -Listing 17-4: Definition of the `Screen` struct with a `components` field -holding a vector of trait objects that implement the `Draw` trait - -On the `Screen` struct, we’ll define a method named `run` that will call the -`draw` method on each of its `components`, as shown in Listing 17-5. - -Filename: src/lib.rs - -``` -impl Screen { - pub fn run(&self) { - for component in self.components.iter() { - component.draw(); - } - } -} -``` - -Listing 17-5: A `run` method on `Screen` that calls the `draw` method on each -component - -This works differently from defining a struct that uses a generic type -parameter with trait bounds. A generic type parameter can only be substituted -with one concrete type at a time, whereas trait objects allow for multiple -concrete types to fill in for the trait object at runtime. For example, we -could have defined the `Screen` struct using a generic type and a trait bound, -as in Listing 17-6. - -Filename: src/lib.rs - -``` -pub struct Screen { - pub components: Vec, -} - -impl Screen -where - T: Draw, -{ - pub fn run(&self) { - for component in self.components.iter() { - component.draw(); - } - } -} -``` - -Listing 17-6: An alternate implementation of the `Screen` struct and its `run` -method using generics and trait bounds - -This restricts us to a `Screen` instance that has a list of components all of -type `Button` or all of type `TextField`. If you’ll only ever have homogeneous -collections, using generics and trait bounds is preferable because the -definitions will be monomorphized at compile time to use the concrete types. - -On the other hand, with the method using trait objects, one `Screen` instance -can hold a `Vec` that contains a `Box