Compare commits

...

44 Commits

Author SHA1 Message Date
Jonas Kruckenberg
8791feb495 Merge pull request #308 from mainmatter/push-uxpvpkpzunoq
update dependencies
2025-10-24 15:05:41 +02:00
Jonas Kruckenberg
a2fe212f44 update dependencies 2025-10-24 14:42:11 +02:00
Meatball Sub
20a2b45e49 Fix typo in TeX Live setup action and format command arguments (#302) 2025-09-30 17:02:41 +02:00
Marcin
c3cb1b38f6 Fix typo in 02_match (#296) 2025-09-03 08:28:37 -07:00
xiorcale
af4fe9cedb fix typo in 7.14 sync (#278) 2025-06-09 07:04:07 +02:00
Geert-Johan Riemer
21f3427c92 Update 03_variants_with_data.md (#264) 2025-03-03 16:32:13 +01:00
Karolis Strazdas
b839c770b5 Fix typos in 08_overflow.md. (#261)
* Fix a typo in "Profiles" section - change "form" to "from". 
* Remove "etc.", as it should not be used together with "e.g.".
2025-02-23 09:57:34 +01:00
dawe
fd23b201fe add missing word in 03_runtime.md (#259) 2025-02-15 10:09:16 +01:00
David Ekete
13850a6b01 Update 04_scoped_threads.md (#258)
Improved phrasing for  the `scope` h2
2025-02-08 10:21:56 +01:00
LukeMathWalker
a7865baf3c Update redirects 2025-01-30 15:14:11 +01:00
LukeMathWalker
0e1c66814d Update shortened links 2025-01-30 15:07:03 +01:00
Luca Palmieri
2f059fc5ba Link to wr website 2025-01-30 14:29:47 +01:00
James Judd
63402ef5c2 Fix dead link to blog.acolyer.org (#253)
Co-authored-by: James Judd <james@lucidchart.com>
2025-01-30 14:13:05 +01:00
Luca Palmieri
892c37ead9 Typo. 2025-01-30 14:03:45 +01:00
Gabriel Crispino
c745cf8ddd fix grammar in exercise 06 from section 03 (#248)
Add missing "to" preposition in first TODO comment
2025-01-19 11:42:03 +01:00
Luca Palmieri
3f60de3712 Avoid using a suffix (#239) 2024-12-18 17:38:05 +01:00
Luca Palmieri
36f6375c20 Change if-else exercise to require an if-else (#238) 2024-12-18 17:33:03 +01:00
Luca Palmieri
fb19005d5f Clarify Send-Sync relationship (#237) 2024-12-18 17:22:16 +01:00
Luca Palmieri
cc0092b2c6 Clarify that both crate and super are keywords (#236) 2024-12-18 17:13:27 +01:00
Luca Palmieri
d5e1c00108 Give a more structure hint for iteration exercises (#235) 2024-12-18 17:03:24 +01:00
Luca Palmieri
60947aaacd Showcase else-if (#234) 2024-12-18 16:53:14 +01:00
LukeMathWalker
fe40e6e2d0 Don't mark Rust code snippets as runnable 2024-12-18 16:48:57 +01:00
LukeMathWalker
7fb0910b39 Format all manifests 2024-12-18 16:39:16 +01:00
Luca Palmieri
468b74ba4d Ignore dead code warnings until visibility has been explained (#232) 2024-12-18 16:38:07 +01:00
LukeMathWalker
b0e1e5a1ec Link to the next tutored session in the methodology section 2024-12-18 11:38:21 +01:00
LukeMathWalker
93536fbcfd Formatting 2024-12-18 11:25:30 +01:00
LukeMathWalker
1993507236 Update redirects 2024-12-18 11:24:29 +01:00
LukeMathWalker
a1a2dc1588 Update aliases 2024-12-18 11:23:03 +01:00
Maor Levy
51cad6bdfe doc: update book 06_01_arrays (#195) 2024-12-18 11:12:50 +01:00
Daniel Wagner-Hall
ab1eb5d80c Warn about the risks of using catch-all patterns (#200) 2024-12-18 11:05:01 +01:00
Daniel Wagner-Hall
fd6a56fd84 Add install steps to the welcome page (#196) 2024-12-18 11:02:25 +01:00
Will Bush
0419e2e8b2 Fix typo in 03_leak.md (#220)
Corrected a confusing sentence with double negative.
2024-11-19 09:19:50 +01:00
dawe
4b02e92691 fix a small typo in 11_locks.md (#219) 2024-11-18 10:58:59 +01:00
dawe
eb2d858807 fix a superfluous word in a comment (#217) 2024-11-15 17:53:27 +01:00
Marco Otte-Witte
4194ee9998 Merge pull request #208 from mainmatter/gravity
run Gravity on online PDF
2024-11-12 12:50:23 +01:00
Marco Otte-Witte
9f5e4a0d76 debug 2024-11-12 12:43:03 +01:00
Marco Otte-Witte
da610ee79b run Gravity on online PDF 2024-11-12 12:29:08 +01:00
Marco Otte-Witte
f1a0eab4a6 Merge pull request #213 from mainmatter/fix-verbosity
switch off Pandoc verbosity
2024-11-12 11:58:47 +01:00
Marco Otte-Witte
3addd64dc2 switch off Pandoc verbosity 2024-11-12 11:51:00 +01:00
Marco Otte-Witte
a53e4f86a1 Merge pull request #212 from mainmatter/debug-build
Fix build
2024-11-12 11:46:58 +01:00
Marco Otte-Witte
5edddf102e fix reference to fallback font 2024-11-12 11:41:00 +01:00
Marco Otte-Witte
dab563a329 debug pandoc build 2024-11-12 11:34:52 +01:00
Marco Otte-Witte
c75ff98c6a format 2024-11-12 11:17:13 +01:00
Robertino
b60e021ab1 Update 11_clone.md (#205)
typo in code
2024-11-01 08:22:23 +01:00
52 changed files with 1398 additions and 877 deletions

View File

@@ -56,7 +56,7 @@ jobs:
echo "$PWD/pandoc-${PANDOC_VERSION}/bin" >> $GITHUB_PATH
shell: bash
- name: Setup TeX Live
uses: teatimeguest/setup-texlive-action@v3
uses: TeX-Live/setup-texlive-action@v3
with:
packages:
scheme-basic
@@ -111,9 +111,9 @@ jobs:
with:
fail: true
args: |
--exclude-loopback
--require-https
--no-progress
--exclude-loopback
--require-https
--no-progress
book/book/html/
# Upload the HTML book as an artifact
- uses: actions/upload-artifact@v4
@@ -146,6 +146,23 @@ jobs:
- run: |
git diff --exit-code site/_redirects
gravity:
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/download-artifact@v4
with:
path: book
pattern: online-pdf
- uses: pnpm/action-setup@v4
with:
version: 9
- run: ls -las ./book
- name: Run Gravity
run: pnpm dlx @gravityci/cli "./book/**/*"
env:
GRAVITY_TOKEN: ${{ secrets.GRAVITY_TOKEN }}
formatter:
runs-on: ubuntu-latest
steps:

1927
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,9 @@ after = ["exercise-linker"]
[output.html]
git-repository-url = "https://github.com/mainmatter/100-exercises-to-learn-rust"
[output.html.playground]
runnable = false
[output.pandoc]
optional = true
hosted-html = "https://rust-exercises.com/100-exercises/"
@@ -49,8 +52,8 @@ sansfontoptions = [
]
# You can get these fonts here: https://fonts.google.com/selection?query=noto+color+
monofont = "Noto Sans Mono"
mainfontfallback = ["Open Sans"]
sansfontfallback = ["Open Sans"]
mainfontfallback = ["Open Sans:style=Regular"]
sansfontfallback = ["Open Sans:style=Regular"]
monofontfallback = [
"Noto Color Emoji:mode=harf",
]
@@ -90,8 +93,8 @@ sansfontoptions = [
]
# You can get these fonts here: https://fonts.google.com/selection?query=noto+color+
monofont = "Noto Sans Mono"
mainfontfallback = ["Open Sans"]
sansfontfallback = ["Open Sans"]
mainfontfallback = ["Open Sans:style=Regular"]
sansfontfallback = ["Open Sans:style=Regular"]
monofontfallback = [
"Noto Color Emoji:mode=harf",
]
@@ -121,8 +124,8 @@ metadata-file = "metadata.yml"
[output.pandoc.profile.html.variables]
# You can get these fonts here: https://fonts.google.com/selection?query=noto+color+
monofont = "Noto Sans Mono"
mainfontfallback = ["Open Sans"]
sansfontfallback = ["Open Sans"]
mainfontfallback = ["Open Sans:style=Regular"]
sansfontfallback = ["Open Sans:style=Regular"]
monofontfallback = [
"Noto Color Emoji:mode=harf",
]

View File

@@ -1,5 +1,5 @@
{
"https://blog.acolyer.org/2019/05/28/cheri-abi/": "f2u",
"https://code.visualstudio.com": "f6c",
"https://crates.io": "f4q",
"https://crates.io/crates/cargo-modules": "f2n",
"https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-types": "ffr",
@@ -163,7 +163,9 @@
"https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/": "f4r",
"https://mainmatter.com/contact/": "ff2",
"https://mainmatter.com/rust-consulting/": "fff",
"https://mainmatter.github.io/rust-workshop-runner/": "fv2",
"https://marabos.nl/atomics/": "fxg",
"https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer": "f6a",
"https://nostarch.com/rust-rustaceans": "f6p",
"https://owasp.org/www-community/vulnerabilities/Doubly_freeing_memory": "f2k",
"https://owasp.org/www-community/vulnerabilities/Using_freed_memory": "f2s",
@@ -177,14 +179,18 @@
"https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case": "fze",
"https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_battles_buffered_streams.html": "f6w",
"https://ryhl.io/blog/async-what-is-blocking/": "f6v",
"https://ti.to/mainmatter/rust-from-scratch-jan-2025": "fvf",
"https://tokio.rs/tokio/tutorial/select": "f6n",
"https://valgrind.org/docs/manual/dh-manual.html": "f2t",
"https://veykril.github.io/tlborm/": "fz5",
"https://web.archive.org/web/20240517051950/https://blog.acolyer.org/2019/05/28/cheri-abi/": "f2u",
"https://without.boats/blog/the-scoped-task-trilemma/": "f67",
"https://www.amazon.com/dp/B0DJ14KQQG/": "f6g",
"https://www.jetbrains.com/rust/": "f6d",
"https://www.lpalmieri.com/": "ffv",
"https://www.lpalmieri.com/posts/2020-12-11-zero-to-production-6-domain-modelling/": "f4t",
"https://www.oreilly.com/library/view/programming-rust-2nd/9781492052586/": "f6y",
"https://www.rust-lang.org/tools/install": "f6j",
"https://www.youtube.com/playlist?list=PLqbS7AVVErFirH9armw8yXlE6dacF-A6z": "f6l",
"https://zero2prod.com": "ff8"
}

View File

@@ -24,12 +24,12 @@ It has been designed to be interactive and hands-on.
to be delivered in a classroom setting, over 4 days: each attendee advances
through the lessons at their own pace, with an experienced instructor providing
guidance, answering questions and diving deeper into the topics as needed.\
If you're interested in attending one of our training sessions, or if you'd like to
bring this course to your company, please [get in touch](https://mainmatter.com/contact/).
You can sign up for the next tutored session on [our website](https://ti.to/mainmatter/rust-from-scratch-jan-2025).
If you'd like to organise a private session for your company, please [get in touch](https://mainmatter.com/contact/).
You can also follow the course on your own, but we recommend you find a friend or
You can also take the courses on your own, but we recommend you find a friend or
a mentor to help you along the way should you get stuck. You can
also find solutions to all exercises in the
find solutions for all exercises in the
[`solutions` branch of the GitHub repository](https://github.com/mainmatter/100-exercises-to-learn-rust/tree/solutions).
## Formats
@@ -67,17 +67,23 @@ Each exercise is structured as a Rust package.
The package contains the exercise itself, instructions on what to do (in `src/lib.rs`), and a test suite to
automatically verify your solution.
### `wr`, the workshop runner
### Tools
To verify your solutions, we've provided a tool that will guide you through the course.
It is the `wr` CLI (short for "workshop runner").
Install it with:
To work through this course, you'll need:
```bash
cargo install --locked workshop-runner
```
- [**Rust**](https://www.rust-lang.org/tools/install).
If `rustup` is already installed on your system, run `rustup update` (or another appropriate command depending on how you installed Rust on your system) to ensure you're running on the latest stable version.
- _(Optional but recommended)_ An IDE with Rust autocompletion support.
We recommend one of the following:
- [RustRover](https://www.jetbrains.com/rust/);
- [Visual Studio Code](https://code.visualstudio.com) with the [`rust-analyzer`](https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer) extension.
In a new terminal, navigate back to the top-level folder of the repository.
### Workshop runner, `wr`
To verify your solutions, we've also provided a tool to guide you through the course: the `wr` CLI, short for "workshop runner".
Install `wr` by following the instructions on [its website](https://mainmatter.github.io/rust-workshop-runner/).
Once you have `wr` installed, open a new terminal and navigate to the top-level folder of the repository.
Run the `wr` command to start the course:
```bash

View File

@@ -36,6 +36,38 @@ if number < 5 {
}
```
### `else if` clauses
Your code drifts more and more to the right when you have multiple `if` expressions, one nested inside the other.
```rust
let number = 3;
if number < 5 {
println!("`number` is smaller than 5");
} else {
if number >= 3 {
println!("`number` is greater than or equal to 3, but smaller than 5");
} else {
println!("`number` is smaller than 3");
}
}
```
You can use the `else if` keyword to combine multiple `if` expressions into a single one:
```rust
let number = 3;
if number < 5 {
println!("`number` is smaller than 5");
} else if number >= 3 {
println!("`number` is greater than or equal to 3, but smaller than 5");
} else {
println!("`number` is smaller than 3");
}
```
## Booleans
The condition in an `if` expression must be of type `bool`, a **boolean**.\

View File

@@ -75,16 +75,14 @@ development,
therefore it sacrifices runtime performance in favor of faster compilation times and a better debugging experience.\
The `release` profile, instead, is optimized for runtime performance but incurs longer compilation times. You need
to explicitly request via the `--release` flag—e.g. `cargo build --release` or `cargo run --release`.
The `test` profile is the default profile used by `cargo test`. The `test` profile inherits the settings form the `dev` profile.
The `test` profile is the default profile used by `cargo test`. The `test` profile inherits the settings from the `dev` profile.
The `bench` profile is the default profile used by `cargo bench`. The `bench` profile inherits from the `release` profile.
Use `dev` for iterative development and debugging, `release` for optimized production builds,\
`test` for correctness testing, and `bench` for performance benchmarking.
> "Have you built your project in release mode?" is almost a meme in the Rust community.\
> It refers to developers who are not familiar with Rust and complain about its performance on
> social media (e.g. Reddit, Twitter, etc.) before realizing they haven't built their project in
> social media (e.g. Reddit, Twitter) before realizing they haven't built their project in
> release mode.
You can also define custom profiles or customize the built-in ones.

View File

@@ -85,6 +85,9 @@ You can compose the path in various ways:
- starting from the parent module, e.g. `super::my_function`
- starting from the current module, e.g. `sub_module_1::MyStruct`
Both `crate` and `super` are **keywords**.\
`crate` refers to the root of the current crate, while `super` refers to the parent of the current module.
Having to write the full path every time you want to refer to a type can be cumbersome.
To make your life easier, you can introduce a `use` statement to bring the entity into scope.

View File

@@ -137,6 +137,6 @@ or [a custom allocator](https://docs.rs/dhat/latest/dhat/)) to inspect the heap
Heap memory will be reserved when you push data into it for the first time.
[^equivalence]: The size of a pointer depends on the operating system too.
In certain environments, a pointer is **larger** than a memory address (e.g. [CHERI](https://blog.acolyer.org/2019/05/28/cheri-abi/)).
In certain environments, a pointer is **larger** than a memory address (e.g. [CHERI](https://web.archive.org/web/20240517051950/https://blog.acolyer.org/2019/05/28/cheri-abi/)).
Rust makes the simplifying assumption that pointers are the same size as memory addresses,
which is true for most modern systems you're likely to encounter.

View File

@@ -56,7 +56,7 @@ that to `consumer` instead.\
## In memory
Let's look at what happened in memory in the example above.
When `let mut s: String::from("hello");` is executed, the memory looks like this:
When `let mut s = String::from("hello");` is executed, the memory looks like this:
```text
s

View File

@@ -68,3 +68,11 @@ match status {
```
The `_` pattern matches anything that wasn't matched by the previous patterns.
<div class="warning">
By using this catch-all pattern, you _won't_ get the benefits of compiler-driven refactoring.
If you add a new enum variant, the compiler _won't_ tell you that you're not handling it.
If you're keen on correctness, avoid using catch-alls. Leverage the compiler to re-examine all matching sites and determine how new enum variants should be handled.
</div>

View File

@@ -64,7 +64,7 @@ match status {
println!("Assigned to: {}", assigned_to);
},
Status::ToDo | Status::Done => {
println!("Done");
println!("ToDo or Done");
}
}
```
@@ -82,7 +82,7 @@ match status {
println!("Assigned to: {}", person);
},
Status::ToDo | Status::Done => {
println!("Done");
println!("ToDo or Done");
}
}
```

View File

@@ -21,6 +21,15 @@ let numbers: [u32; 3] = [1, 2, 3];
This creates an array of 3 integers, initialized with the values `1`, `2`, and `3`.\
The type of the array is `[u32; 3]`, which reads as "an array of `u32`s with a length of 3".
If all array elements are the same, you can use a shorter syntax to initialize it:
```rust
// [ <value> ; <number of elements> ]
let numbers: [u32; 3] = [1; 3];
```
`[1; 3]` creates an array of three elements, all equal to `1`.
### Accessing elements
You can access elements of an array using square brackets:

View File

@@ -38,7 +38,7 @@ When the process exits, the operating system will reclaim that memory.
Keeping this in mind, it can be OK to leak memory when:
- The amount of memory you need to leak is not unbounded/known upfront, or
- The amount of memory you need to leak is bounded/known upfront, or
- Your process is short-lived and you're confident you won't exhaust
all the available memory before it exits

View File

@@ -27,7 +27,7 @@ Let's unpack what's happening.
## `scope`
The `std::thread::scope` function creates a new **scope**.\
`std::thread::scope` takes as input a closure, with a single argument: a `Scope` instance.
`std::thread::scope` takes a closure as input, with a single argument: a `Scope` instance.
## Scoped spawns

View File

@@ -58,7 +58,7 @@ drop(guard)
## Locking granularity
What should our `Mutex` wrap?\
The simplest option would be the wrap the entire `TicketStore` in a single `Mutex`.\
The simplest option would be to wrap the entire `TicketStore` in a single `Mutex`.\
This would work, but it would severely limit the system's performance: you wouldn't be able to read tickets in parallel,
because every read would have to wait for the lock to be released.\
This is known as **coarse-grained locking**.

View File

@@ -5,20 +5,20 @@ Before we wrap up this chapter, let's talk about another key trait in Rust's sta
`Sync` is an auto trait, just like `Send`.\
It is automatically implemented by all types that can be safely **shared** between threads.
In order words: `T: Sync` means that `&T` is `Send`.
In other words: `T` is Sync if `&T` is `Send`.
## `Sync` doesn't imply `Send`
## `T: Sync` doesn't imply `T: Send`
It's important to note that `Sync` doesn't imply `Send`.\
It's important to note that `T` can be `Sync` without being `Send`.\
For example: `MutexGuard` is not `Send`, but it is `Sync`.
It isn't `Send` because the lock must be released on the same thread that acquired it, therefore we don't
want `MutexGuard` to be dropped on a different thread.\
But it is `Sync`, because giving a `&MutexGuard` to another thread has no impact on where the lock is released.
## `Send` doesn't imply `Sync`
## `T: Send` doesn't imply `T: Sync`
The opposite is also true: `Send` doesn't imply `Sync`.\
The opposite is also true: `T` can be `Send` without being `Sync`.\
For example: `RefCell<T>` is `Send` (if `T` is `Send`), but it is not `Sync`.
`RefCell<T>` performs runtime borrow checking, but the counters it uses to track borrows are not thread-safe.

View File

@@ -26,7 +26,7 @@ at any given time.
### Multithreaded runtime
When using the multithreaded runtime, instead, there can up to `N` tasks running
When using the multithreaded runtime, instead, there can be up to `N` tasks running
_in parallel_ at any given time, where `N` is the number of threads used by the
runtime. By default, `N` matches the number of available CPU cores.

View File

@@ -2,3 +2,9 @@
name = "welcome_00"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "syntax"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "intro_01"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "integers"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -1,6 +1,7 @@
fn compute(a: u32, b: u32) -> u32 {
// TODO: change the line below to fix the compiler error and make the tests pass.
a + b * 4u8
let multiplier: u8 = 4;
a + b * multiplier
}
#[cfg(test)]

View File

@@ -2,3 +2,9 @@
name = "variables"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "if_else"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -1,24 +1,36 @@
/// Return `true` if `n` is even, `false` otherwise.
fn is_even(n: u32) -> bool {
/// Return `12` if `n` is even,
/// `13` if `n` is divisible by `3`,
/// `17` otherwise.
fn magic_number(n: u32) -> u32 {
todo!()
}
#[cfg(test)]
mod tests {
use crate::is_even;
use crate::magic_number;
#[test]
fn one() {
assert!(!is_even(1));
assert_eq!(magic_number(1), 17);
}
#[test]
fn two() {
assert!(is_even(2));
assert_eq!(magic_number(2), 12);
}
#[test]
fn six() {
assert_eq!(magic_number(6), 12);
}
#[test]
fn nine() {
assert_eq!(magic_number(9), 13);
}
#[test]
fn high() {
assert!(!is_even(231));
assert_eq!(magic_number(233), 17);
}
}

View File

@@ -2,3 +2,9 @@
name = "panics"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "factorial"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "while_"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "for_"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "overflow"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "saturating"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "as_cast"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "intro_02"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "struct_"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -5,3 +5,9 @@ edition = "2021"
[dev-dependencies]
common = { path = "../../../helpers/common" }
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -2,3 +2,9 @@
name = "modules"
version = "0.1.0"
edition = "2021"
[lints.rust]
# We silence dead code warnings for the time being in order to reduce
# compiler noise.
# We'll re-enable them again once we explain how visibility works in Rust.
dead_code = "allow"

View File

@@ -1,6 +1,6 @@
// TODO: based on what we just learned about ownership, it sounds like immutable references
// are a good fit for our accessor methods.
// Change the existing implementation of `Ticket`'s accessor methods take a reference
// Change the existing implementation of `Ticket`'s accessor methods to take a reference
// to `self` as an argument, rather than taking ownership of it.
pub struct Ticket {

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
thiserror = "1.0.59"
thiserror = "1.0.69"
[dev-dependencies]
common = { path = "../../../helpers/common" }

View File

@@ -5,6 +5,9 @@ use ticket_fields::{TicketDescription, TicketTitle};
// it contains using a `for` loop.
//
// Hint: you shouldn't have to implement the `Iterator` trait in this case.
// You want to *delegate* the iteration to the `Vec<Ticket>` field in `TicketStore`.
// Look at the standard library documentation for `Vec` to find the right type
// to return from `into_iter`.
#[derive(Clone)]
pub struct TicketStore {
tickets: Vec<Ticket>,

View File

@@ -1,6 +1,10 @@
use ticket_fields::{TicketDescription, TicketTitle};
// TODO: Provide an `iter` method that returns an iterator over `&Ticket` items.
//
// Hint: just like in the previous exercise, you want to delegate the iteration to
// the `Vec<Ticket>` field in `TicketStore`. Look at the standard library documentation
// for `Vec` to find the right type to return from `iter`.
#[derive(Clone)]
pub struct TicketStore {
tickets: Vec<Ticket>,

View File

@@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
thiserror = "1.0.59"
thiserror = "1.0.69"
ticket_fields = { path = "../../../helpers/ticket_fields" }

View File

@@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
thiserror = "1.0.60"
thiserror = "1.0.69"
ticket_fields = { path = "../../../helpers/ticket_fields" }

View File

@@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
thiserror = "1.0.60"
thiserror = "1.0.69"
ticket_fields = { path = "../../../helpers/ticket_fields" }

View File

@@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.83"
anyhow = "1.0.100"
tokio = { version = "1", features = ["full"] }

View File

@@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.83"
anyhow = "1.0.100"
tokio = { version = "1", features = ["full"] }

View File

@@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.83"
anyhow = "1.0.100"
tokio = { version = "1", features = ["full"] }

View File

@@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.83"
anyhow = "1.0.100"
tokio = { version = "1", features = ["full"] }

View File

@@ -4,8 +4,8 @@ version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.86"
clap = "4.5.4"
mdbook = "0.4.40"
semver = "1.0.23"
serde_json = "1.0.117"
anyhow = "1.0.100"
clap = "4.5.50"
mdbook = "0.4.52"
semver = "1.0.27"
serde_json = "1.0.145"

View File

@@ -4,12 +4,12 @@ version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.86"
anyhow = "1.0.100"
bimap = { version = "0.6.3", features = ["serde"] }
clap = { version = "4.5.4", features = ["derive"] }
clap = { version = "4.5.50", features = ["derive"] }
itertools = "0.13.0"
mdbook = "0.4.40"
pulldown-cmark = "0.11.0"
mdbook = "0.4.52"
pulldown-cmark = "0.11.3"
pulldown-cmark-to-cmark = "15"
semver = "1.0.23"
serde_json = "1.0.117"
semver = "1.0.27"
serde_json = "1.0.145"

View File

@@ -5,4 +5,4 @@ edition = "2021"
[dependencies]
common = { path = "../common" }
thiserror = "1.0.59"
thiserror = "1.0.69"

View File

@@ -1,4 +1,4 @@
/f2u https://blog.acolyer.org/2019/05/28/cheri-abi/
/f6c https://code.visualstudio.com
/f4q https://crates.io
/f2n https://crates.io/crates/cargo-modules
/ffr https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-types
@@ -162,7 +162,9 @@
/f4r https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/
/ff2 https://mainmatter.com/contact/
/fff https://mainmatter.com/rust-consulting/
/fv2 https://mainmatter.github.io/rust-workshop-runner/
/fxg https://marabos.nl/atomics/
/f6a https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer
/f6p https://nostarch.com/rust-rustaceans
/f2k https://owasp.org/www-community/vulnerabilities/Doubly_freeing_memory
/f2s https://owasp.org/www-community/vulnerabilities/Using_freed_memory
@@ -176,13 +178,17 @@
/fze https://rust-lang.github.io/api-guidelines/naming.html#casing-conforms-to-rfc-430-c-case
/f6w https://rust-lang.github.io/wg-async/vision/submitted_stories/status_quo/barbara_battles_buffered_streams.html
/f6v https://ryhl.io/blog/async-what-is-blocking/
/fvf https://ti.to/mainmatter/rust-from-scratch-jan-2025
/f6n https://tokio.rs/tokio/tutorial/select
/f2t https://valgrind.org/docs/manual/dh-manual.html
/fz5 https://veykril.github.io/tlborm/
/f2u https://web.archive.org/web/20240517051950/https://blog.acolyer.org/2019/05/28/cheri-abi/
/f67 https://without.boats/blog/the-scoped-task-trilemma/
/f6g https://www.amazon.com/dp/B0DJ14KQQG/
/f6d https://www.jetbrains.com/rust/
/ffv https://www.lpalmieri.com/
/f4t https://www.lpalmieri.com/posts/2020-12-11-zero-to-production-6-domain-modelling/
/f6y https://www.oreilly.com/library/view/programming-rust-2nd/9781492052586/
/f6j https://www.rust-lang.org/tools/install
/f6l https://www.youtube.com/playlist?list=PLqbS7AVVErFirH9armw8yXlE6dacF-A6z
/ff8 https://zero2prod.com