Compare commits

...

25 Commits

Author SHA1 Message Date
LukeMathWalker
0910f3909f Add formats. 2024-08-06 10:31:06 +02:00
mckzm
2765fdaa0e Fix reference to supertrait syntax in 09_error_trait.md (#124)
The [Error trait](https://rust-exercises.com/100-exercises/05_ticket_v2/09_error_trait.html?highlight=supertrait#the-error-trait) chapter states that the reader may recall the supertrait syntax from the [Sized trait](https://rust-exercises.com/100-exercises/04_traits/08_sized) chapter. Actually the syntax is introduced in the [From and Into](https://rust-exercises.com/100-exercises/04_traits/09_from) chapter instead. This PR amends the text accordingly.
2024-08-05 17:53:07 +02:00
Luca Palmieri
96f06708b0 Render the book in PDF using pandoc and LaTeX. (#126)
* Render the book in PDF using `pandoc` and LaTeX.

* Fix installs.

* Go the apt-get route

* Another attempt

* Avoid installing twice.

* Re-order.

* Add more packages.

* Minimise deps. Fix link checker.

* Missing package.

* Missing package.

* Missing package.

* More packages.

* Missing package.

* Missing package.

* More packages...

* Remove.

* Fix link checker.

* Fix link checker.

* Fix path.

* Add subtitle.

* Avoid running over the right margin.

* Avoid running over the right margin.

* Formatting
2024-08-05 17:52:15 +02:00
mckzm
e732ea82e4 Fix minor typo in 09_bounded.md (#125)
Trim errant `s` from `enqueue`'s end in [Bounded vs unbounded channels](https://rust-exercises.com/100-exercises/07_threads/09_bounded.html):

`if the producers enqueues messages` -> `if the producers enqueue messages`
2024-08-05 15:03:31 +02:00
LukeMathWalker
5ef0a6aa12 Formatting 2024-08-01 15:33:23 +02:00
LukeMathWalker
f882f0416d Change exercise for mutable slices. Closes #26 2024-08-01 15:33:13 +02:00
LukeMathWalker
6029a8fc17 Ensure that overflow checks are active for the copy exercise. Closes #64 2024-08-01 15:14:10 +02:00
LukeMathWalker
056505d89f It's enough for one field to be private. Closes #69 2024-08-01 15:10:50 +02:00
LukeMathWalker
b039a6c5c2 Formatting 2024-08-01 15:09:40 +02:00
LukeMathWalker
3a9c9ea520 Remove reference to cargo new to avoid confusion. Closes #71. 2024-08-01 15:09:24 +02:00
LukeMathWalker
3f4d31148f Add cargo-modules. Closes #101 2024-08-01 14:56:43 +02:00
LukeMathWalker
2f067058ce Fix #104 2024-08-01 14:54:25 +02:00
LukeMathWalker
be5c0e8bae Reword 'static issues. Closes #117 2024-08-01 14:53:53 +02:00
LukeMathWalker
a6056381bd No need to deploy anymore. 2024-07-30 16:13:20 +02:00
code-cp
59833f2a55 Update 06_async_aware_primitives.md (#122)
Fix a typo
2024-07-28 12:46:20 +02:00
Zhang Zihao
9a2086081c Fix a typo (#116) 2024-07-17 08:08:22 +02:00
Jack Moffitt
f272843c61 Remove pub visibility on server() as the argument has a private type. This gets rid of a warning. (#112) 2024-07-07 21:18:43 +02:00
Evgeniy Filimonov
fccad08921 07_threads: 03_leak: Leak vector with Vec::leak, not Box::leak (#107) 2024-06-30 18:23:20 +02:00
Palash Nigam (He/Him)
de45f8adf2 Ch-08 Futures Exercise 02: Fix typo (#106) 2024-06-30 00:18:46 +02:00
LOGI
5660a2f7a8 fix(typo): a module name in comments (#102)
The output of the compiler does not include the module name of the `Ticket` struct and the root module of this exercise is `visibility` rather than `encapsulation` which is the root module of the next exercise.
2024-06-27 11:35:11 +02:00
Saqib Ahmed
491319a6d5 fix: fix a typo (#103) 2024-06-27 11:34:02 +02:00
Jerry Wu
83cf1cad62 Update 11_locks.md (#94)
Suggest removing an extra semicolon.
2024-06-20 10:21:53 +02:00
Ernie Hershey
d8d7e73f1c fix syntax with comma (#89)
Example doesn't compile with a comma here
2024-06-20 10:21:33 +02:00
Onè
468de3c0ac Change test to require impl (#87)
impl std::ops::Add<&SaturatingU16> for SaturatingU16
2024-06-20 10:21:14 +02:00
tomgrbz
c86360f3c4 Remove array/slice syntax from argument &mut str in TODO comment for lowercase func (#99)
Co-authored-by: thomasgrbic <grbic.t@northeastern.edu>
2024-06-20 10:18:55 +02:00
40 changed files with 450 additions and 279 deletions

View File

@@ -18,6 +18,47 @@ jobs:
- uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install plugin - name: Install plugin
run: cargo install --path helpers/mdbook-exercise-linker run: cargo install --path helpers/mdbook-exercise-linker
- name: Install mdbook-pandoc and related dependencies
run: |
cargo install mdbook-pandoc --locked --version 0.7.1
sudo apt-get update
sudo apt-get install -y fonts-noto
export PANDOC_VERSION=3.3
curl -LsSf https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-linux-amd64.tar.gz | tar zxf -
echo "$PWD/pandoc-${PANDOC_VERSION}/bin" >> $GITHUB_PATH
shell: bash
- name: Setup TeX Live
uses: teatimeguest/setup-texlive-action@v3
with:
packages:
scheme-basic
luatex
lualatex-math
luacolor
luatexbase
luaotfload
framed
unicode-math
xcolor
geometry
longtable
booktabs
array
lua-ul
etoolbox
fancyvrb
footnote
selnolig
natbib
csquotes
bookmark
xurl
amsmath
setspace
iftex
- name: Check `tlmgr` version
run: tlmgr --version
- uses: taiki-e/install-action@v2 - uses: taiki-e/install-action@v2
with: with:
tool: mdbook tool: mdbook
@@ -33,24 +74,19 @@ jobs:
--exclude-loopback --exclude-loopback
--require-https --require-https
--no-progress --no-progress
book/book book/book/html/
# Upload the book as an artifact # Upload the HTML book as an artifact
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
with: with:
name: book name: book
path: book/book # When you support multiple formats, the output directory changes
# Commit and push all changed files. # to include the format in its path.
# Must only affect files that are listed in "paths-ignore". path: book/book/html
- name: Git commit build artifacts # Upload the PDF book as an artifact
# Only run on main branch push (e.g. pull request merge). - uses: actions/upload-artifact@v4
if: github.event_name == 'push' with:
run: | name: paperback
git checkout -b deploy path: book/book/pandoc/pdf/100-exercises-to-learn-rust.pdf
git config --global user.name "Deployer"
git config --global user.email "username@users.noreply.github.com"
git add --force book/book
git commit -m "Render book"
git push --set-upstream --force-with-lease origin deploy
formatter: formatter:
runs-on: ubuntu-latest runs-on: ubuntu-latest

356
Cargo.lock generated
View File

@@ -4,9 +4,9 @@ version = 3
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.21.0" version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
dependencies = [ dependencies = [
"gimli", "gimli",
] ]
@@ -56,9 +56,9 @@ dependencies = [
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.14" version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"anstyle-parse", "anstyle-parse",
@@ -71,33 +71,33 @@ dependencies = [
[[package]] [[package]]
name = "anstyle" name = "anstyle"
version = "1.0.7" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]] [[package]]
name = "anstyle-parse" name = "anstyle-parse"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [ dependencies = [
"utf8parse", "utf8parse",
] ]
[[package]] [[package]]
name = "anstyle-query" name = "anstyle-query"
version = "1.0.3" version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
name = "anstyle-wincon" name = "anstyle-wincon"
version = "3.0.3" version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"windows-sys 0.52.0", "windows-sys 0.52.0",
@@ -144,9 +144,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]] [[package]]
name = "backtrace" name = "backtrace"
version = "0.3.71" version = "0.3.73"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
dependencies = [ dependencies = [
"addr2line", "addr2line",
"cc", "cc",
@@ -171,9 +171,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.5.0" version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
@@ -201,9 +201,9 @@ dependencies = [
[[package]] [[package]]
name = "bstr" name = "bstr"
version = "1.9.1" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
dependencies = [ dependencies = [
"memchr", "memchr",
"regex-automata", "regex-automata",
@@ -231,9 +231,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.6.0" version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]] [[package]]
name = "cancellation" name = "cancellation"
@@ -244,9 +244,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.97" version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@@ -270,23 +270,23 @@ dependencies = [
"android-tzdata", "android-tzdata",
"iana-time-zone", "iana-time-zone",
"num-traits", "num-traits",
"windows-targets 0.52.5", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.4" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
] ]
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.2" version = "4.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -297,18 +297,18 @@ dependencies = [
[[package]] [[package]]
name = "clap_complete" name = "clap_complete"
version = "4.5.2" version = "4.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e" checksum = "a8670053e87c316345e384ca1f3eba3006fc6355ed8b8a1140d104e109e3df34"
dependencies = [ dependencies = [
"clap", "clap",
] ]
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.7.0" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]] [[package]]
name = "client" name = "client"
@@ -323,9 +323,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.1" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]] [[package]]
name = "combinators" name = "combinators"
@@ -473,9 +473,9 @@ dependencies = [
[[package]] [[package]]
name = "env_filter" name = "env_filter"
version = "0.1.0" version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
dependencies = [ dependencies = [
"log", "log",
"regex", "regex",
@@ -483,9 +483,9 @@ dependencies = [
[[package]] [[package]]
name = "env_logger" name = "env_logger"
version = "0.11.3" version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -680,9 +680,9 @@ dependencies = [
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.28.1" version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]] [[package]]
name = "globset" name = "globset"
@@ -826,9 +826,9 @@ dependencies = [
[[package]] [[package]]
name = "httparse" name = "httparse"
version = "1.8.0" version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
[[package]] [[package]]
name = "httpdate" name = "httpdate"
@@ -844,9 +844,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.28" version = "0.14.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@@ -953,9 +953,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.2.6" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown",
@@ -1019,9 +1019,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "is_terminal_polyfill" name = "is_terminal_polyfill"
version = "1.70.0" version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "iter" name = "iter"
@@ -1078,9 +1078,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.154" version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]] [[package]]
name = "libdbus-sys" name = "libdbus-sys"
@@ -1125,9 +1125,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.21" version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]] [[package]]
name = "mac" name = "mac"
@@ -1208,9 +1208,9 @@ dependencies = [
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.2" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]] [[package]]
name = "mime" name = "mime"
@@ -1220,9 +1220,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "mime_guess" name = "mime_guess"
version = "2.0.4" version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [ dependencies = [
"mime", "mime",
"unicase", "unicase",
@@ -1230,9 +1230,9 @@ dependencies = [
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.2" version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [ dependencies = [
"adler", "adler",
] ]
@@ -1249,6 +1249,18 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "mio"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
dependencies = [
"hermit-abi",
"libc",
"wasi",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "modules" name = "modules"
version = "0.1.0" version = "0.1.0"
@@ -1265,11 +1277,11 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]] [[package]]
name = "normpath" name = "normpath"
version = "1.2.0" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5831952a9476f2fed74b77d74182fa5ddc4d21c72ec45a333b250e3ed0272804" checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed"
dependencies = [ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -1278,7 +1290,7 @@ version = "6.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.6.0",
"crossbeam-channel", "crossbeam-channel",
"filetime", "filetime",
"fsevent-sys", "fsevent-sys",
@@ -1286,7 +1298,7 @@ dependencies = [
"kqueue", "kqueue",
"libc", "libc",
"log", "log",
"mio", "mio 0.8.11",
"walkdir", "walkdir",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@@ -1318,21 +1330,11 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "object" name = "object"
version = "0.32.2" version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -1400,9 +1402,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.2" version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [ dependencies = [
"lock_api", "lock_api",
"parking_lot_core", "parking_lot_core",
@@ -1416,9 +1418,9 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"redox_syscall 0.5.1", "redox_syscall 0.5.3",
"smallvec", "smallvec",
"windows-targets 0.52.5", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@@ -1443,9 +1445,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "pest" name = "pest"
version = "2.7.10" version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95"
dependencies = [ dependencies = [
"memchr", "memchr",
"thiserror", "thiserror",
@@ -1454,9 +1456,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_derive" name = "pest_derive"
version = "2.7.10" version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a"
dependencies = [ dependencies = [
"pest", "pest",
"pest_generator", "pest_generator",
@@ -1464,9 +1466,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_generator" name = "pest_generator"
version = "2.7.10" version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183"
dependencies = [ dependencies = [
"pest", "pest",
"pest_meta", "pest_meta",
@@ -1477,9 +1479,9 @@ dependencies = [
[[package]] [[package]]
name = "pest_meta" name = "pest_meta"
version = "2.7.10" version = "2.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"pest", "pest",
@@ -1583,9 +1585,12 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.17" version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
]
[[package]] [[package]]
name = "precomputed-hash" name = "precomputed-hash"
@@ -1595,9 +1600,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.82" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -1608,7 +1613,7 @@ version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.6.0",
"memchr", "memchr",
"pulldown-cmark-escape", "pulldown-cmark-escape",
"unicase", "unicase",
@@ -1670,11 +1675,11 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.1" version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.6.0",
] ]
[[package]] [[package]]
@@ -1683,9 +1688,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.10.4" version = "1.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -1695,9 +1700,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.4.6" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -1706,9 +1711,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.8.3" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]] [[package]]
name = "resizing" name = "resizing"
@@ -1741,7 +1746,7 @@ version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
dependencies = [ dependencies = [
"bitflags 2.5.0", "bitflags 2.6.0",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
@@ -1799,18 +1804,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.202" version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.202" version = "1.0.204"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1819,11 +1824,12 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.117" version = "1.0.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr",
"ryu", "ryu",
"serde", "serde",
] ]
@@ -1998,9 +2004,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.63" version = "2.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -2017,12 +2023,13 @@ version = "0.1.0"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.10.1" version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"once_cell",
"rustix", "rustix",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@@ -2050,18 +2057,18 @@ dependencies = [
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.60" version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.60" version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -2089,9 +2096,9 @@ dependencies = [
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
dependencies = [ dependencies = [
"tinyvec_macros", "tinyvec_macros",
] ]
@@ -2104,28 +2111,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.37.0" version = "1.39.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
"libc", "libc",
"mio", "mio 1.0.1",
"num_cpus",
"parking_lot", "parking_lot",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"windows-sys 0.48.0", "windows-sys 0.52.0",
] ]
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "2.2.0" version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -2293,9 +2299,9 @@ dependencies = [
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.0" version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [ dependencies = [
"form_urlencoded", "form_urlencoded",
"idna", "idna",
@@ -2310,9 +2316,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]] [[package]]
name = "utf8parse" name = "utf8parse"
version = "0.2.1" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "validation" name = "validation"
@@ -2338,9 +2344,9 @@ version = "0.1.0"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "visibility" name = "visibility"
@@ -2479,11 +2485,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]] [[package]]
name = "winapi-util" name = "winapi-util"
version = "0.1.8" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -2498,7 +2504,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [ dependencies = [
"windows-targets 0.52.5", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@@ -2516,7 +2522,16 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets 0.52.5", "windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets 0.52.6",
] ]
[[package]] [[package]]
@@ -2536,18 +2551,18 @@ dependencies = [
[[package]] [[package]]
name = "windows-targets" name = "windows-targets"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm 0.52.5", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.5", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.5", "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm", "windows_i686_gnullvm",
"windows_i686_msvc 0.52.5", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.5", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.5", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.5", "windows_x86_64_msvc 0.52.6",
] ]
[[package]] [[package]]
@@ -2558,9 +2573,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
@@ -2570,9 +2585,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
@@ -2582,15 +2597,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]] [[package]]
name = "windows_i686_gnullvm" name = "windows_i686_gnullvm"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
@@ -2600,9 +2615,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
@@ -2612,9 +2627,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
@@ -2624,9 +2639,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
@@ -2636,9 +2651,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.5" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "without_channels" name = "without_channels"
@@ -2646,3 +2661,24 @@ version = "0.1.0"
dependencies = [ dependencies = [
"ticket_fields", "ticket_fields",
] ]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

View File

@@ -1,3 +1,8 @@
[workspace] [workspace]
members = ["exercises/*/*", "helpers/common", "helpers/mdbook-exercise-linker", "helpers/ticket_fields"] members = ["exercises/*/*", "helpers/common", "helpers/mdbook-exercise-linker", "helpers/ticket_fields"]
resolver = "2" resolver = "2"
# This is needed to guarantee the expected behaviour on that specific exercise,
# regardless of the "global" setting for `overflow-checks` on the `dev` profile.
[profile.dev.package.copy]
overflow-checks = true

View File

@@ -1,10 +1,44 @@
[book] [book]
authors = ["Luca Palmieri (Mainmatter)"] authors = ["Luca Palmieri"]
language = "en" language = "en"
multilingual = false multilingual = false
src = "src" src = "src"
title = "100 Exercises To Learn Rust" title = "100 Exercises To Learn Rust"
[output.pandoc]
optional = true
hosted-html = "https://rust-exercises.com/100-exercises/"
[output.pandoc.profile.pdf] # options to pass to Pandoc (see https://pandoc.org/MANUAL.html)
output-file = "100-exercises-to-learn-rust.pdf"
to = "latex"
highlight-style = "tango"
# We use `lualatext` because, right now, it's the only engine
# that supports fallback fonts, which we need for emojis.
pdf-engine = "lualatex"
[output.pandoc.profile.pdf.variables]
subtitle = "A hands-on course by Mainmatter"
# You can get these fonts here: https://fonts.google.com/selection?query=noto+color+
mainfont = "Noto Serif"
sansfont = "Noto Sans"
monofont = "Noto Sans Mono"
mainfontfallback = ["Noto Color Emoji:mode=harf"]
sansfontfallback = ["Noto Color Emoji:mode=harf"]
monofontfallback = [
"Noto Color Emoji:mode=harf",
]
linkcolor = "blue"
urlcolor = "blue"
urlstyle = "rm"
documentclass = "book"
fontsize = "11pt"
geometry = "papersize={8in,10in},top=2cm,bottom=2cm,left=2.4cm,right=2.4cm"
header-includes = [
# Reduce font size of code blocks
"\\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\\\\{\\},fontsize=\\small}",
]
[output.html] [output.html]
git-repository-url = "https://github.com/mainmatter/100-exercises-to-learn-rust" git-repository-url = "https://github.com/mainmatter/100-exercises-to-learn-rust"

View File

@@ -32,6 +32,11 @@ a mentor to help you along the way should you get stuck. You can
also find solutions to all exercises in the also find solutions to all exercises in the
[`solutions` branch of the GitHub repository](https://github.com/mainmatter/100-exercises-to-learn-rust/tree/solutions). [`solutions` branch of the GitHub repository](https://github.com/mainmatter/100-exercises-to-learn-rust/tree/solutions).
## Formats
You can browse the course material in the browser, at [rust-exercises.com/100-exercises/](https://rust-exercises.com/100-exercises/).\
You can also [download the course material as a PDF file](https://rust-exercises.com/100-exercises-to-learn-rust.pdf), for offline reading.
## Structure ## Structure
On the left side of the screen, you can see that the course is divided into sections. On the left side of the screen, you can see that the course is divided into sections.

View File

@@ -72,7 +72,8 @@ error: literal out of range for `i8`
4 | let a = 255 as i8; 4 | let a = 255 as i8;
| ^^^ | ^^^
| |
= note: the literal `255` does not fit into the type `i8` whose range is `-128..=127` = note: the literal `255` does not fit into the type `i8`
whose range is `-128..=127`
= help: consider using the type `u8` instead = help: consider using the type `u8` instead
= note: `#[deny(overflowing_literals)]` on by default = note: `#[deny(overflowing_literals)]` on by default
``` ```

View File

@@ -48,7 +48,7 @@ You can create an instance of a struct by specifying the values for each field:
// Syntax: <StructName> { <field_name>: <value>, ... } // Syntax: <StructName> { <field_name>: <value>, ... }
let ticket = Ticket { let ticket = Ticket {
title: "Build a ticket system".into(), title: "Build a ticket system".into(),
description: "Create a system that can manage tickets across a Kanban board".into(), description: "A Kanban board".into(),
status: "Open".into() status: "Open".into()
}; };
``` ```
@@ -130,7 +130,8 @@ let default_config = Configuration::default();
You can use the function call syntax even for methods that take `self` as their first parameter: You can use the function call syntax even for methods that take `self` as their first parameter:
```rust ```rust
// Function call syntax: <StructName>::<method_name>(<instance>, <parameters>) // Function call syntax:
// <StructName>::<method_name>(<instance>, <parameters>)
let is_open = Ticket::is_open(ticket); let is_open = Ticket::is_open(ticket);
``` ```

View File

@@ -81,7 +81,7 @@ You have to use a **path** pointing to the entity you want to access.
You can compose the path in various ways: You can compose the path in various ways:
- starting from the root of the current crate, e.g. `crate::module_1::module_2::MyStruct` - starting from the root of the current crate, e.g. `crate::module_1::MyStruct`
- starting from the parent module, e.g. `super::my_function` - starting from the parent module, e.g. `super::my_function`
- starting from the current module, e.g. `sub_module_1::MyStruct` - starting from the current module, e.g. `sub_module_1::MyStruct`
@@ -112,3 +112,10 @@ where each name comes from and potentially introducing name conflicts.\
Nonetheless, it can be useful in some cases, like when writing unit tests. You might have noticed Nonetheless, it can be useful in some cases, like when writing unit tests. You might have noticed
that most of our test modules start with a `use super::*;` statement to bring all the items from the parent module that most of our test modules start with a `use super::*;` statement to bring all the items from the parent module
(the one being tested) into scope. (the one being tested) into scope.
## Visualizing the module tree
If you're struggling to picture the module tree of your project, you can try using
[`cargo-modules`](https://crates.io/crates/cargo-modules) to visualize it!
Refer to their documentation for installation instructions and usage examples.

View File

@@ -23,14 +23,14 @@ To enforce stricter rules, we must keep the fields private[^newtype].
We can then provide public methods to interact with a `Ticket` instance. We can then provide public methods to interact with a `Ticket` instance.
Those public methods will have the responsibility of upholding our invariants (e.g. a title must not be empty). Those public methods will have the responsibility of upholding our invariants (e.g. a title must not be empty).
If all fields are private, it is no longer possible to create a `Ticket` instance directly using the struct If at least one field is private it is no longer possible to create a `Ticket` instance directly using the struct
instantiation syntax: instantiation syntax:
```rust ```rust
// This won't work! // This won't work!
let ticket = Ticket { let ticket = Ticket {
title: "Build a ticket system".into(), title: "Build a ticket system".into(),
description: "Create a system that can manage tickets across a Kanban board".into(), description: "A Kanban board".into(),
status: "Open".into() status: "Open".into()
}; };
``` ```

View File

@@ -44,9 +44,11 @@ error[E0382]: use of moved value: `ticket`
| -------- `ticket` moved due to this method call | -------- `ticket` moved due to this method call
... ...
30 | println!("Your next task is: {}", ticket.title()); 30 | println!("Your next task is: {}", ticket.title());
| ^^^^^^ value used here after move | ^^^^^^
| value used here after move
| |
note: `Ticket::status` takes ownership of the receiver `self`, which moves `ticket` note: `Ticket::status` takes ownership of the receiver `self`,
which moves `ticket`
--> src/main.rs:12:23 --> src/main.rs:12:23
| |
12 | pub fn status(self) -> String { 12 | pub fn status(self) -> String {
@@ -130,9 +132,11 @@ error[E0382]: use of moved value: `ticket`
| -------- `ticket` moved due to this method call | -------- `ticket` moved due to this method call
... ...
30 | println!("Your next task is: {}", ticket.title()); 30 | println!("Your next task is: {}", ticket.title());
| ^^^^^^ value used here after move | ^^^^^^
| value used here after move
| |
note: `Ticket::status` takes ownership of the receiver `self`, which moves `ticket` note: `Ticket::status` takes ownership of the receiver `self`,
which moves `ticket`
--> src/main.rs:12:23 --> src/main.rs:12:23
| |
12 | pub fn status(self) -> String { 12 | pub fn status(self) -> String {
@@ -199,8 +203,10 @@ fn main() {
active: true, active: true,
}; };
// `b` is a reference to the `version` field of `config`. // `b` is a reference to the `version` field of `config`.
// The type of `b` is `&u32`, since it contains a reference to a `u32` value. // The type of `b` is `&u32`, since it contains a reference to
// We create a reference by borrowing `config.version`, using the `&` operator. // a `u32` value.
// We create a reference by borrowing `config.version`, using
// the `&` operator.
// Same symbol (`&`), different meaning depending on the context! // Same symbol (`&`), different meaning depending on the context!
let b: &u32 = &config.version; let b: &u32 = &config.version;
// ^ The type annotation is not necessary, // ^ The type annotation is not necessary,

View File

@@ -50,7 +50,11 @@ It takes ownership of `self`, changes the title, and returns the modified `Ticke
This is how you'd use it: This is how you'd use it:
```rust ```rust
let ticket = Ticket::new("Title".into(), "Description".into(), "To-Do".into()); let ticket = Ticket::new(
"Title".into(),
"Description".into(),
"To-Do".into()
);
let ticket = ticket.set_title("New title".into()); let ticket = ticket.set_title("New title".into());
``` ```
@@ -88,7 +92,11 @@ Nothing is returned.
You'd use it like this: You'd use it like this:
```rust ```rust
let mut ticket = Ticket::new("Title".into(), "Description".into(), "To-Do".into()); let mut ticket = Ticket::new(
"Title".into(),
"Description".into(),
"To-Do".into()
);
ticket.set_title("New title".into()); ticket.set_title("New title".into());
// Use the modified ticket // Use the modified ticket

View File

@@ -18,11 +18,25 @@ the function's arguments, local variables and a few "bookkeeping" values.\
When the function returns, the stack frame is popped off the stack[^stack-overflow]. When the function returns, the stack frame is popped off the stack[^stack-overflow].
```text ```text
+-----------------+ +-----------------+
func2 | frame for func2 | func2 | frame for func1 |
+-----------------+ is called +-----------------+ returns +-----------------+ +-----------------+
| frame for func1 | -----------> | frame for func1 | ---------> | frame for func1 | |
+-----------------+ +-----------------+ +-----------------+ | func2 is
| called
v
+-----------------+
| frame for func2 |
+-----------------+
| frame for func1 |
+-----------------+
|
| func2
| returns
v
+-----------------+
| frame for func1 |
+-----------------+
``` ```
From an operational point of view, stack allocation/de-allocation is **very fast**.\ From an operational point of view, stack allocation/de-allocation is **very fast**.\

View File

@@ -94,7 +94,8 @@ fn print_if_even<T>(n: T) {
This code won't compile: This code won't compile:
```text ```text
error[E0599]: no method named `is_even` found for type parameter `T` in the current scope error[E0599]: no method named `is_even` found for type parameter `T`
in the current scope
--> src/lib.rs:2:10 --> src/lib.rs:2:10
| |
1 | fn print_if_even<T>(n: T) { 1 | fn print_if_even<T>(n: T) {
@@ -106,7 +107,9 @@ error[E0277]: `T` doesn't implement `Debug`
--> src/lib.rs:3:19 --> src/lib.rs:3:19
| |
3 | println!("{n:?} is even"); 3 | println!("{n:?} is even");
| ^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^
| `T` cannot be formatted using `{:?}` because
| it doesn't implement `Debug`
| |
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
| |

View File

@@ -72,7 +72,8 @@ You can, for example, create a `&str` from a `String` like this:
```rust ```rust
let mut s = String::with_capacity(5); let mut s = String::with_capacity(5);
s.push_str("Hello"); s.push_str("Hello");
// Create a string slice reference from the `String`, skipping the first byte. // Create a string slice reference from the `String`,
// skipping the first byte.
let slice: &str = &s[1..]; let slice: &str = &s[1..];
``` ```

View File

@@ -11,7 +11,8 @@ to the pointer: the length of the slice it points to. Going back to the example
```rust ```rust
let mut s = String::with_capacity(5); let mut s = String::with_capacity(5);
s.push_str("Hello"); s.push_str("Hello");
// Create a string slice reference from the `String`, skipping the first byte. // Create a string slice reference from the `String`,
// skipping the first byte.
let slice: &str = &s[1..]; let slice: &str = &s[1..];
``` ```

View File

@@ -3,7 +3,11 @@
Let's go back to where our string journey started: Let's go back to where our string journey started:
```rust ```rust
let ticket = Ticket::new("A title".into(), "A description".into(), "To-Do".into()); let ticket = Ticket::new(
"A title".into(),
"A description".into(),
"To-Do".into()
);
``` ```
We now know enough to start unpacking what `.into()` is doing here. We now know enough to start unpacking what `.into()` is doing here.
@@ -14,7 +18,11 @@ This is the signature of the `new` method:
```rust ```rust
impl Ticket { impl Ticket {
pub fn new(title: String, description: String, status: String) -> Self { pub fn new(
title: String,
description: String,
status: String
) -> Self {
// [...] // [...]
} }
} }
@@ -108,7 +116,7 @@ let title = String::from("A title");
We've been primarily using `.into()`, though.\ We've been primarily using `.into()`, though.\
If you check out the [implementors of `Into`](https://doc.rust-lang.org/std/convert/trait.Into.html#implementors) If you check out the [implementors of `Into`](https://doc.rust-lang.org/std/convert/trait.Into.html#implementors)
you won't find `Into<&str> for String`. What's going on? you won't find `Into<String> for &str`. What's going on?
`From` and `Into` are **dual traits**.\ `From` and `Into` are **dual traits**.\
In particular, `Into` is implemented for any type that implements `From` using a **blanket implementation**: In particular, `Into` is implemented for any type that implements `From` using a **blanket implementation**:

View File

@@ -44,7 +44,8 @@ impl Drop for MyType {
The compiler will complain with this error message: The compiler will complain with this error message:
```text ```text
error[E0184]: the trait `Copy` cannot be implemented for this type; the type has a destructor error[E0184]: the trait `Copy` cannot be implemented for this type;
the type has a destructor
--> src/lib.rs:2:17 --> src/lib.rs:2:17
| |
2 | #[derive(Clone, Copy)] 2 | #[derive(Clone, Copy)]

View File

@@ -14,7 +14,11 @@ pub struct Ticket {
} }
impl Ticket { impl Ticket {
pub fn new(title: String, description: String, status: String) -> Self { pub fn new(
title: String,
description: String,
status: String
) -> Self {
// [...] // [...]
} }
} }

View File

@@ -8,7 +8,10 @@ impl Ticket {
match &self.status { match &self.status {
Status::InProgress { assigned_to } => assigned_to, Status::InProgress { assigned_to } => assigned_to,
Status::Done | Status::ToDo => { Status::Done | Status::ToDo => {
panic!("Only `In-Progress` tickets can be assigned to someone"), panic!(
"Only `In-Progress` tickets can be \
assigned to someone"
)
} }
} }
} }
@@ -33,7 +36,9 @@ impl Ticket {
if let Status::InProgress { assigned_to } = &self.status { if let Status::InProgress { assigned_to } = &self.status {
assigned_to assigned_to
} else { } else {
panic!("Only `In-Progress` tickets can be assigned to someone"); panic!(
"Only `In-Progress` tickets can be assigned to someone"
);
} }
} }
} }
@@ -48,7 +53,9 @@ you can use the `let/else` construct:
impl Ticket { impl Ticket {
pub fn assigned_to(&self) -> &str { pub fn assigned_to(&self) -> &str {
let Status::InProgress { assigned_to } = &self.status else { let Status::InProgress { assigned_to } = &self.status else {
panic!("Only `In-Progress` tickets can be assigned to someone"); panic!(
"Only `In-Progress` tickets can be assigned to someone"
);
}; };
assigned_to assigned_to
} }

View File

@@ -4,7 +4,11 @@ Let's revisit the `Ticket::new` function from the previous exercise:
```rust ```rust
impl Ticket { impl Ticket {
pub fn new(title: String, description: String, status: Status) -> Ticket { pub fn new(
title: String,
description: String,
status: Status
) -> Ticket {
if title.is_empty() { if title.is_empty() {
panic!("Title cannot be empty"); panic!("Title cannot be empty");
} }
@@ -70,8 +74,9 @@ Rust, with `Result`, forces you to **encode fallibility in the function's signat
If a function can fail (and you want the caller to have a shot at handling the error), it must return a `Result`. If a function can fail (and you want the caller to have a shot at handling the error), it must return a `Result`.
```rust ```rust
// Just by looking at the signature, you know that this function can fail. // Just by looking at the signature, you know that this function
// You can also inspect `ParseIntError` to see what kind of failures to expect. // can fail. You can also inspect `ParseIntError` to see what
// kind of failures to expect.
fn parse_int(s: &str) -> Result<i32, ParseIntError> { fn parse_int(s: &str) -> Result<i32, ParseIntError> {
// ... // ...
} }

View File

@@ -14,8 +14,8 @@ fn parse_int(s: &str) -> Result<i32, ParseIntError> {
} }
// This won't compile: we're not handling the error case. // This won't compile: we're not handling the error case.
// We must either use `match` or one of the combinators provided by `Result` // We must either use `match` or one of the combinators provided by
// to "unwrap" the success value or handle the error. // `Result` to "unwrap" the success value or handle the error.
let number = parse_int("42") + 2; let number = parse_int("42") + 2;
``` ```

View File

@@ -22,7 +22,7 @@ that implements the `Error` trait.
pub trait Error: Debug + Display {} pub trait Error: Debug + Display {}
``` ```
You might recall the `:` syntax from [the `Sized` trait](../04_traits/08_sized.md)—it's used to specify **supertraits**. You might recall the `:` syntax from [the `From` trait](../04_traits/09_from.md#supertrait--subtrait)—it's used to specify **supertraits**.
For `Error`, there are two supertraits: `Debug` and `Display`. If a type wants to implement `Error`, it must also For `Error`, there are two supertraits: `Debug` and `Display`. If a type wants to implement `Error`, it must also
implement `Debug` and `Display`. implement `Debug` and `Display`.

View File

@@ -46,18 +46,3 @@ You can override these defaults by explicitly declaring your targets in the `Car
[`cargo`'s documentation](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#cargo-targets) for more details. [`cargo`'s documentation](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#cargo-targets) for more details.
Keep in mind that while a package can contain multiple crates, it can only contain one library crate. Keep in mind that while a package can contain multiple crates, it can only contain one library crate.
## Scaffolding a new package
You can use `cargo` to scaffold a new package:
```bash
cargo new my-binary
```
This will create a new folder, `my-binary`, containing a new Rust package with the same name and a single
binary crate inside. If you want to create a library crate instead, you can use the `--lib` flag:
```bash
cargo new my-library --lib
```

View File

@@ -6,7 +6,7 @@ and why we might want to use them.
## What is a thread? ## What is a thread?
A **thread** is an execution context managed by the underlying operating system.\ A **thread** is an execution context managed by the underlying operating system.\
Each thread has its own stack, instruction pointer, and program counter. Each thread has its own stack and instruction pointer.
A single **process** can manage multiple threads. A single **process** can manage multiple threads.
These threads share the same memory space, which means they can access the same data. These threads share the same memory space, which means they can access the same data.

View File

@@ -11,9 +11,9 @@ error[E0597]: `v` does not live long enough
... ...
15 | let right = &v[split_point..]; 15 | let right = &v[split_point..];
| ^ borrowed value does not live long enough | ^ borrowed value does not live long enough
16 | let left_handle = thread::spawn(move || left.iter().sum::<i32>()); 16 | let left_handle = spawn(move || left.iter().sum::<i32>());
| ------------------------------------------------ | --------------------------------
argument requires that `v` is borrowed for `'static` argument requires that `v` is borrowed for `'static`
19 | } 19 | }
| - `v` dropped here while still borrowed | - `v` dropped here while still borrowed
``` ```

View File

@@ -27,12 +27,12 @@ run out and crash with an out-of-memory error.
fn oom_trigger() { fn oom_trigger() {
loop { loop {
let v: Vec<usize> = Vec::with_capacity(1024); let v: Vec<usize> = Vec::with_capacity(1024);
Box::leak(v); v.leak();
} }
} }
``` ```
At the same time, memory leaked via `Box::leak` is not truly forgotten.\ At the same time, memory leaked via `leak` method is not truly forgotten.\
The operating system can map each memory region to the process responsible for it. The operating system can map each memory region to the process responsible for it.
When the process exits, the operating system will reclaim that memory. When the process exits, the operating system will reclaim that memory.

View File

@@ -3,7 +3,7 @@
So far we've been using unbounded channels.\ So far we've been using unbounded channels.\
You can send as many messages as you want, and the channel will grow to accommodate them.\ You can send as many messages as you want, and the channel will grow to accommodate them.\
In a multi-producer single-consumer scenario, this can be problematic: if the producers In a multi-producer single-consumer scenario, this can be problematic: if the producers
enqueues messages at a faster rate than the consumer can process them, the channel will enqueue messages at a faster rate than the consumer can process them, the channel will
keep growing, potentially consuming all available memory. keep growing, potentially consuming all available memory.
Our recommendation is to **never** use an unbounded channel in a production system.\ Our recommendation is to **never** use an unbounded channel in a production system.\

View File

@@ -10,9 +10,9 @@ In the non-threaded version of the system, updates were fairly straightforward:
## Multithreaded updates ## Multithreaded updates
The same strategy won't work in the current multi-threaded version, The same strategy won't work in the current multithreaded version. The borrow checker would
because the mutable reference would have to be sent over a channel. The borrow checker would stop us: `SyncSender<&mut Ticket>` isn't `'static` because `&mut Ticket` doesn't satisfy the `'static` lifetime, therefore
stop us, because `&mut Ticket` doesn't satisfy the `'static` lifetime requirement of `SyncSender::send`. they can't be captured by the closure that gets passed to `std::thread::spawn`.
There are a few ways to work around this limitation. We'll explore a few of them in the following exercises. There are a few ways to work around this limitation. We'll explore a few of them in the following exercises.

View File

@@ -99,7 +99,7 @@ fn main() {
let guard = lock.lock().unwrap(); let guard = lock.lock().unwrap();
spawn(move || { spawn(move || {
receiver.recv().unwrap();; receiver.recv().unwrap();
}); });
// Try to send the guard over the channel // Try to send the guard over the channel
@@ -118,12 +118,14 @@ error[E0277]: `MutexGuard<'_, i32>` cannot be sent between threads safely
| _-----_^ | _-----_^
| | | | | |
| | required by a bound introduced by this call | | required by a bound introduced by this call
11 | | receiver.recv().unwrap();; 11 | | receiver.recv().unwrap();
12 | | }); 12 | | });
| |_^ `MutexGuard<'_, i32>` cannot be sent between threads safely | |_^ `MutexGuard<'_, i32>` cannot be sent between threads safely
| |
= help: the trait `Send` is not implemented for `MutexGuard<'_, i32>`, which is required by `{closure@src/main.rs:10:7: 10:14}: Send` = help: the trait `Send` is not implemented for `MutexGuard<'_, i32>`,
= note: required for `std::sync::mpsc::Receiver<MutexGuard<'_, i32>>` to implement `Send` which is required by `{closure@src/main.rs:10:7: 10:14}: Send`
= note: required for `std::sync::mpsc::Receiver<MutexGuard<'_, i32>>`
to implement `Send`
note: required because it's used within this closure note: required because it's used within this closure
``` ```

View File

@@ -112,7 +112,7 @@ pub async fn work() {
### `std::thread::spawn` vs `tokio::spawn` ### `std::thread::spawn` vs `tokio::spawn`
You can think of `tokio::spawn` as the asynchronous sibling of `std::spawn::thread`. You can think of `tokio::spawn` as the asynchronous sibling of `std::thread::spawn`.
Notice a key difference: with `std::thread::spawn`, you're delegating control to the OS scheduler. Notice a key difference: with `std::thread::spawn`, you're delegating control to the OS scheduler.
You're not in control of how threads are scheduled. You're not in control of how threads are scheduled.

View File

@@ -55,7 +55,8 @@ note: future is not `Send` as this value is used across an await
| -------- has type `Rc<i32>` which is not `Send` | -------- has type `Rc<i32>` which is not `Send`
12 | // A `.await` point 12 | // A `.await` point
13 | yield_now().await; 13 | yield_now().await;
| ^^^^^ await occurs here, with `non_send` maybe used later | ^^^^^
| await occurs here, with `non_send` maybe used later
note: required by a bound in `tokio::spawn` note: required by a bound in `tokio::spawn`
| |
164 | pub fn spawn<F>(future: F) -> JoinHandle<F::Output> 164 | pub fn spawn<F>(future: F) -> JoinHandle<F::Output>
@@ -84,7 +85,10 @@ trait Future {
type Output; type Output;
// Ignore `Pin` and `Context` for now // Ignore `Pin` and `Context` for now
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>; fn poll(
self: Pin<&mut Self>,
cx: &mut Context<'_>
) -> Poll<Self::Output>;
} }
``` ```

View File

@@ -52,7 +52,7 @@ Yields to runtime
Tries to acquire lock Tries to acquire lock
``` ```
We have a deadlock. Task B we'll never manage to acquire the lock, because the lock We have a deadlock. Task B will never manage to acquire the lock, because the lock
is currently held by task A, which has yielded to the runtime before releasing the is currently held by task A, which has yielded to the runtime before releasing the
lock and won't be scheduled again because the runtime cannot preempt task B. lock and won't be scheduled again because the runtime cannot preempt task B.

View File

@@ -105,5 +105,5 @@ async fn run() {
Check out [`select!`'s documentation](https://tokio.rs/tokio/tutorial/select) for more details.\ Check out [`select!`'s documentation](https://tokio.rs/tokio/tutorial/select) for more details.\
If you need to interleave two asynchronous streams of data (e.g. a socket and a channel), prefer using If you need to interleave two asynchronous streams of data (e.g. a socket and a channel), prefer using
[`StreamExt::merge`](https://docs.rs/tokio-stream/latest/tokio_stream/trait.StreamExt.html#method.merge) instead. [`StreamExt::merge`](https://docs.rs/tokio-stream/latest/tokio_stream/trait.StreamExt.html#method.merge) instead.
- Rather than "abrupt" cancellation, it can be preferable to rely - A [`CancellationToken`](https://docs.rs/tokio-util/latest/tokio_util/sync/struct.CancellationToken.html) may be
on [`CancellationToken`](https://docs.rs/tokio-util/latest/tokio_util/sync/struct.CancellationToken.html). preferable to `JoinHandle::abort` in some cases.

View File

@@ -48,5 +48,5 @@ check out the [Embedded Rust book](https://docs.rust-embedded.org/book/).
You can then find resources on key topics that cut across domains.\ You can then find resources on key topics that cut across domains.\
For testing, check out For testing, check out
["Advanced testing, going beyond the basics"](https://github.com/mainmatter/rust-advanced-testing-workshop).\ ["Advanced testing, going beyond the basics"](https://rust-exercises.com/advanced-testing/).\
For telemetry, check out ["You can't fix what you can't see"](https://github.com/mainmatter/rust-telemetry-workshop). For telemetry, check out ["You can't fix what you can't see"](https://rust-exercises.com/telemetry/).

View File

@@ -48,7 +48,7 @@ mod tests {
// You should be seeing this error when trying to run this exercise: // You should be seeing this error when trying to run this exercise:
// //
// error[E0616]: field `description` of struct `encapsulation::ticket::Ticket` is private // error[E0616]: field `description` of struct `Ticket` is private
// | // |
// | assert_eq!(ticket.description, "A description"); // | assert_eq!(ticket.description, "A description");
// | ^^^^^^^^^^^^^^^^^^ // | ^^^^^^^^^^^^^^^^^^

View File

@@ -6,11 +6,12 @@ fn test_saturating_u16() {
let b: SaturatingU16 = 5u8.into(); let b: SaturatingU16 = 5u8.into();
let c: SaturatingU16 = u16::MAX.into(); let c: SaturatingU16 = u16::MAX.into();
let d: SaturatingU16 = (&1u16).into(); let d: SaturatingU16 = (&1u16).into();
let e = &c;
assert_eq!(a + b, SaturatingU16::from(15u16)); assert_eq!(a + b, SaturatingU16::from(15u16));
assert_eq!(a + c, SaturatingU16::from(u16::MAX)); assert_eq!(a + c, SaturatingU16::from(u16::MAX));
assert_eq!(a + d, SaturatingU16::from(11u16)); assert_eq!(a + d, SaturatingU16::from(11u16));
assert_eq!(a + a, 20u16); assert_eq!(a + a, 20u16);
assert_eq!(a + 5u16, 15u16); assert_eq!(a + 5u16, 15u16);
assert_eq!(a + &u16::MAX, SaturatingU16::from(u16::MAX)); assert_eq!(a + e, SaturatingU16::from(u16::MAX));
} }

View File

@@ -43,7 +43,7 @@ mod tests {
} }
#[test] #[test]
fn thirthieth() { fn thirtieth() {
assert_eq!(fibonacci(30), 832040); assert_eq!(fibonacci(30), 832040);
} }
} }

View File

@@ -1,6 +1,5 @@
// TODO: Define a function named `lowercase` that converts all characters in a string to lowercase, // TODO: Define a function named `squared` that raises all `i32`s within a slice to the power of 2.
// modifying the input in place. // The slice should be modified in place.
// Does it need to take a `&mut String`? Does a `&mut [str]` work? Why or why not?
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
@@ -8,29 +7,22 @@ mod tests {
#[test] #[test]
fn empty() { fn empty() {
let mut s = String::from(""); let mut s = vec![];
lowercase(&mut s); squared(&mut s);
assert_eq!(s, ""); assert_eq!(s, vec![]);
} }
#[test] #[test]
fn one_char() { fn one() {
let mut s = String::from("A"); let mut s = [2];
lowercase(&mut s); squared(&mut s);
assert_eq!(s, "a"); assert_eq!(s, [4]);
} }
#[test] #[test]
fn multiple_chars() { fn multiple() {
let mut s = String::from("Hello, World!"); let mut s = vec![2, 4];
lowercase(&mut s); squared(&mut s);
assert_eq!(s, "hello, world!"); assert_eq!(s, vec![4, 16]);
}
#[test]
fn mut_slice() {
let mut s = "Hello, World!".to_string();
lowercase(s.as_mut_str());
assert_eq!(s, "hello, world!");
} }
} }

View File

@@ -38,7 +38,7 @@ enum Command {
}, },
} }
pub fn server(receiver: Receiver<Command>) { fn server(receiver: Receiver<Command>) {
let mut store = TicketStore::new(); let mut store = TicketStore::new();
loop { loop {
match receiver.recv() { match receiver.recv() {

View File

@@ -33,7 +33,7 @@ impl Preprocessor for ExerciseLinker {
book.sections book.sections
.iter_mut() .iter_mut()
.for_each(|i| process_book_item(i, &root_url)); .for_each(|i| process_book_item(i, &ctx.renderer, &root_url));
Ok(book) Ok(book)
} }
@@ -42,11 +42,11 @@ impl Preprocessor for ExerciseLinker {
} }
} }
fn process_book_item(item: &mut BookItem, root_url: &str) { fn process_book_item(item: &mut BookItem, renderer: &str, root_url: &str) {
match item { match item {
BookItem::Chapter(chapter) => { BookItem::Chapter(chapter) => {
chapter.sub_items.iter_mut().for_each(|item| { chapter.sub_items.iter_mut().for_each(|item| {
process_book_item(item, root_url); process_book_item(item, renderer, root_url);
}); });
let Some(source_path) = &chapter.source_path else { let Some(source_path) = &chapter.source_path else {
@@ -61,10 +61,14 @@ fn process_book_item(item: &mut BookItem, root_url: &str) {
let exercise_path = source_path.strip_suffix(".md").unwrap(); let exercise_path = source_path.strip_suffix(".md").unwrap();
let link_section = format!( let link_section = format!(
"\n## Exercise\n\nThe exercise for this section is located in [`{exercise_path}`]({})", "\n## Exercise\n\nThe exercise for this section is located in [`{exercise_path}`]({})\n",
format!("{}/{}", root_url, exercise_path) format!("{}/{}", root_url, exercise_path)
); );
chapter.content.push_str(&link_section); chapter.content.push_str(&link_section);
if renderer == "pandoc" {
chapter.content.push_str("`\\newpage`{=latex}\n");
}
} }
BookItem::Separator => {} BookItem::Separator => {}
BookItem::PartTitle(_) => {} BookItem::PartTitle(_) => {}