{"owner":"google","repo":"comprehensive-rust","hasSkills":true,"totalSkillsCount":8,"totalTokensCount":5686,"categories":["gemini-rule","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["GEMINI.md","src/references/dangling.md","src/references/exclusive.md","src/references/slices.md","src/references/shared.md","src/references/solution.md","src/references/exercise.md","src/references/strings.md"],"skills":{"GEMINI.md":"# Project Overview\n\nThis repository contains the source code for Comprehensive Rust, a family of\ncourses on Rust developed by Google, starting with Rust foundations, and\nincluding deep dives into specialized topics like Android, Chromium, bare-metal\ndevelopment, and concurrency. The project is a Rust workspace that leverages\n`mdbook` to generate a course website.\n\n## Key Technologies\n\n- **Rust:** The primary programming language for the course subject, custom\n  tools, and examples.\n- **mdbook:** A command-line tool to create books from Markdown files, used for\n  generating the course website.\n- **Custom mdbook Preprocessors:** `mdbook-course` and `mdbook-exerciser` are\n  Rust binaries that extend `mdbook`'s functionality, for example, to extract\n  exercise starter code.\n- **`cargo xtask`:** A custom binary within the workspace used for project\n  automation, simplifying common development tasks.\n\n# Building and Running\n\nThe project uses `cargo xtask` for project-specific automation, like builds,\ntests, and managing translations.\n\n## Setup\n\n1. **Install Rust:** Follow the instructions on\n   [https://rustup.rs/](https://rustup.rs/).\n2. **Clone Repository:**\n   ```bash\n   git clone https://github.com/google/comprehensive-rust/\n   cd comprehensive-rust\n   ```\n3. **Install Project Tools:**\n   ```bash\n   cargo xtask install-tools\n   ```\n   This is a necessary first step for working with this repository. It will\n   install the correct versions of all tools used by the project.\n\n## Commands\n\nAll commands are run using `cargo xtask`. Run `cargo xtask --help` for a full\nlist of options.\n\n- **Serve the Course Locally:** Starts a web server to view the course content.\n  ```bash\n  cargo xtask serve [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n  (e.g., `cargo xtask serve -l da` for the Danish translation)\n\n- **Build the Course:** Creates a static version of the course in the `book/`\n  directory.\n  ```bash\n  cargo xtask build [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n\n- **Run Rust Snippet Tests:** Tests all Rust code snippets included in the\n  course material.\n  ```bash\n  cargo xtask rust-tests\n  ```\n\n- **Run Web Driver Tests:** Executes web driver tests located in the `tests/`\n  directory.\n  ```bash\n  cargo xtask web-tests [--dir <book_html_directory>]\n  ```\n\n# Development Conventions\n\n- **Project Automation:** `cargo xtask` is the primary interface for common\n  development tasks.\n- **Course Content:** Markdown files in the `src/` directory, structured\n  according to `src/SUMMARY.md`.\n- **Code Formatting:** `dprint fmt` is used to format all source files according\n  to `rustfmt.toml` and `dprint.json`. Note that you must first install the\n  project tools with `cargo xtask install-tools`.\n- **Contributions:** Refer to `CONTRIBUTING.md` for guidelines on contributing\n  to the project.\n- **Style:** Refer to `STYLE.md` for style guidelines. When making changes to\n  Markdown files in `src/`, always first read `STYLE.md` and follow its\n  conventions.\n- **GitHub Actions:** The project uses composite GitHub Actions to simplify CI\n  workflows. These actions should be preferred over hand-written commands.\n  - **`apt-get-install`:** This action efficiently installs Debian packages. It\n    configures `dpkg` and `apt` to skip documentation and translations, and\n    ensures that `apt-get update` is run only once per job. This significantly\n    speeds up CI runs.\n  - **`install-mdbook`:** A composite action to install `mdbook` and its\n    dependencies, including `pandoc` and `texlive`.\n  - **`setup-rust-cache`:** A composite action that configures the\n    `Swatinem/rust-cache` action.\n\n## Developing Exercises\n\nExercises allow students to practice what they have learned. When adding or\nupdating exercises, follow these structural conventions:\n\n- **File Structure:**\n  - `exercise.md`: Contains the problem description and a code block with\n    placeholders.\n  - `exercise.rs`: Contains the full solution code, including a license header\n    and `ANCHOR` tags to delimit sections.\n  - `solution.md`: Includes the full solution code from `exercise.rs`.\n  - `Cargo.toml`: Must define a `[[bin]]` target pointing to `exercise.rs` so\n    that the solution code is compiled and tested.\n\n- **Content Inclusion:**\n  - Use `{{#include exercise.rs:anchor_name}}` in `exercise.md` to show specific\n    parts of the code (e.g., setup, main).\n  - Use `{{#include exercise.rs:solution}}` in `solution.md` to show the\n    solution code _without_ the license header. Ensure `exercise.rs` has a\n    `// ANCHOR: solution` line before the first line of the solution. It is\n    unnecessary to add a `// ANCHOR_END: solution` line at the bottom of the\n    file.\n\n- **Testing:**\n  - Run `cargo xtask rust-tests` to ensure the solution code compiles and runs\n    correctly.\n  - Run `cargo check -p <crate_name>` to verify the specific exercise crate.\n\n## Markdown Conventions\n\n- **Headings:**\n  - **H1 (`#`):** Used for the main title of each page. Each slide has exactly\n    one title.\n  - **H2 (`##`):** Used for major sections. Slides do not use H2 headings to\n    save vertical space; more slides are created instead.\n  - **H3 (`###`):** Used for sub-sections, but not on slides.\n\n- **Emphasis:**\n  - **Bold (`**...**`):** Used to highlight key terms, commands, and for notes\n    (e.g., `**Note:**`). The colon (`:`) is included inside the bold text for\n    notes.\n  - **Italic (`_..._`):** Used for general emphasis, titles of external\n    articles, and for terms being defined.\n\n- **Code:**\n  - **Inline Code (`` `...` ``):** Used for code snippets, file names, commands,\n    type names, and language keywords. Rust fragments are formatted as `rustfmt`\n    would.\n  - **Code Blocks (`` ```...``` ``):** Fenced code blocks are used for\n    multi-line code examples, annotated with a language identifier (e.g.,\n    `rust`, `c`, `ignore`).\n  - **Interactive Code Blocks:** Rust examples are made interactive with\n    `editable`. Examples that fail to compile are marked with `compile_fail` or\n    `should_panic`.\n  - **Diagrams:** The `bob` language identifier is used in code blocks to\n    generate ASCII art diagrams.\n  - **Formatting Control:** The `#[rustfmt::skip]` attribute is used to prevent\n    `rustfmt` from formatting specific code blocks, though it is used rarely.\n\n- **Lists:**\n  - **Bulleted Lists:** Unordered lists are the primary way to lay out key\n    points on slides.\n  - **Glossary Format:** The glossary uses a specific format with a colon and\n    backslash (`:\\`) after each term to create a hard line break for visual\n    formatting.\n\n- **Other Markdown Elements:**\n  - **Block Quotes (`> ...`):** Used sparingly for important notes, warnings, or\n    supplementary information to draw attention.\n  - **Links:** Both standard (`[text](url)`) and reference-style\n    (`[text][label]`) links are used.\n  - **Tables:** Markdown tables are used to present structured data.\n  - **Horizontal Rules (`---`):** Not used on slides.\n\n- **HTML Tags:**\n  - **`<details>`:** Used for collapsible \"speaker notes\".\n  - **`<kbd>`:** Used to denote keyboard keys. Each key in a combination must be\n    wrapped in its own tag, e.g., `<kbd>Ctrl</kbd> + <kbd>S</kbd>`.\n  - **`<style>`:** Used rarely for targeted custom CSS.\n  - **`<img>`:** Used to embed images.\n\n- **Project-Specific Conventions:**\n  - **mdbook Includes:** The `{{#include ...}}` helper is used to include\n    snippets from other files.\n  - **mdbook Segments:** The `{{%segment ...%}}` and `{{%session ...%}}` helpers\n    are used for course structuring.\n  - **Frontmatter:** Files start with YAML frontmatter (enclosed in `---`) to\n    provide metadata.\n  - **Doc Comments:** Standard Rust doc comments (`///`, `//!`) are used.\n    `/// # Safety` is used to document safety preconditions for `unsafe` code.\n  - **Comments:** HTML comments (`<!-- ... -->`) are used for editor/translator\n    instructions and content control (e.g., `mdbook-xgettext: skip`).\n\n# Project-Specific Technical Context\n\nThis section contains critical, non-obvious technical details about this\nproject's tooling and environment that an AI assistant needs to know to perform\nits tasks correctly.\n\n## `mdbook` Behavior\n\n- **Isolated Code Snippets:** `mdbook` treats each fenced Rust code block (e.g.,\n  `` ```rust ... ``` ``) as a separate compilation unit. When analyzing a code\n  snippet, treat it as a self-contained program. Do not assume it shares a scope\n  or context with other snippets in the same file unless the surrounding text\n  explicitly states otherwise.\n\n## Interacting with the `mdbook` Theme\n\nThe `mdbook` theme has several interactive elements. Here's how to interact with\nthem:\n\n- **Sidebar Toggle:** The sidebar can be opened and closed by clicking the\n  \"hamburger\" button in the top-left of the body text. This button has the ID\n  `sidebar-toggle`. You can use the following JavaScript to toggle the sidebar:\n\n  ```javascript\n  const button = document.getElementById(\"sidebar-toggle\");\n  button.click();\n  ```\n\n## WebdriverIO Testing\n\nThis project uses WebdriverIO for browser-based integration tests. Here are some\nkey findings about the test environment:\n\n### Test Environments\n\nThe `tests/` directory contains two primary configurations:\n\n- `npm test` (runs `wdio.conf.ts`): This is the standard for self-contained\n  integration tests. It uses `@wdio/static-server-service` to create a temporary\n  web server on port 8080.\n- `npm run test-mdbook` (runs `wdio.conf-mdbook.ts`): This is for testing\n  against a live `mdbook serve` instance, which typically runs on port 3000.\n\nIt is important to use the standard `npm test` command for most test development\nto ensure the tests are self-contained.\n\n### Writing Stable Tests\n\nTests can be flaky if they don't correctly handle the asynchronous nature of the\nweb browser and the test environment's state management.\n\n- **State Leakage Between Tests:** Despite what the WebdriverIO documentation\n  might suggest, `browser.url()` is not always sufficient to guarantee a clean\n  slate between tests. Lingering state, such as inline CSS styles applied by\n  JavaScript, can leak from one test into the next, causing unexpected failures.\n  The most effective solution found for this project is to add\n  `await browser.refresh();` to the `beforeEach` hook. This forces a full page\n  reload that properly clears the old state.\n\n- **Race Conditions with Dynamic Elements:** Many elements in this project are\n  created dynamically by JavaScript after the initial page load. If a test tries\n  to access an element immediately after navigation, it may fail because the\n  script hasn't finished running and the element doesn't exist in the DOM yet.\n  This creates a race condition. To prevent this, always use\n  `await element.waitForExist()` to ensure the element is present before trying\n  to interact with it or assert its state (e.g., `toBeDisplayed()`).\n\n### Handling Redirects\n\n`mdbook` uses a redirect map defined in `book.toml` under the\n`[output.html.redirect]` section. When writing tests, it is crucial to use the\nfinal, non-redirecting URL for navigation. Navigating to a URL that is a\nredirect will cause the browser to follow it, but this process can strip URL\nquery parameters, leading to test failures for features that depend on them.\n\n### Running and Debugging Tests\n\nTo run a single test file, use the `--spec` flag with the a string matching the\nfile name:\n\n```bash\nnpm test -- --spec redbox\n```\n\nTo check for flakiness, you can repeat a test multiple times using the\n`--repeat` flag:\n\n```bash\nnpm test -- --spec redbox --repeat 100\n```\n\nUse `--mochaOpts.grep` to run a single test within a file:\n\n```bash\nnpm test -- --spec redbox --mochaOpts.grep \"should be hidden by default\"\n```\n","src/references/dangling.md":"---\nminutes: 3\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Reference Validity\n\nRust enforces a number of rules for references that make them always safe to\nuse. One rule is that references can never be `null`, making them safe to use\nwithout `null` checks. The other rule we'll look at for now is that references\ncan't _outlive_ the data they point to.\n\n```rust,editable,compile_fail\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let x_ref = {\n        let x = 10;\n        &x\n    };\n    dbg!(x_ref);\n}\n```\n\n<details>\n\n- This slide gets students thinking about references as not simply being\n  pointers, since Rust has different rules for references than other languages.\n\n- We'll look at the rest of Rust's borrowing rules on day 3 when we talk about\n  Rust's ownership system.\n\n## More to Explore\n\n- Rust's equivalent of nullability is the `Option` type, which can be used to\n  make any type \"nullable\" (not just references/pointers). We haven't yet\n  introduced enums or pattern matching, though, so try not to go into too much\n  detail about this here.\n\n</details>\n","src/references/exclusive.md":"---\nminutes: 5\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exclusive References\n\nExclusive references, also known as mutable references, allow changing the value\nthey refer to. They have type `&mut T`.\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let mut point = (1, 2);\n    let x_coord = &mut point.0;\n    *x_coord = 20;\n    println!(\"point: {point:?}\");\n}\n```\n\n<details>\n\nKey points:\n\n- \"Exclusive\" means that only this reference can be used to access the value. No\n  other references (shared or exclusive) can exist at the same time, and the\n  referenced value cannot be accessed while the exclusive reference exists. Try\n  making an `&point.0` or changing `point.0` while `x_coord` is alive.\n\n- Be sure to note the difference between `let mut x_coord: &i32` and\n  `let x_coord: &mut i32`. The first one is a shared reference that can be bound\n  to different values, while the second is an exclusive reference to a mutable\n  value.\n\n</details>\n","src/references/slices.md":"---\nminutes: 7\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Slices\n\nA slice gives you a view into a larger collection:\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n    println!(\"a: {a:?}\");\n\n    let s: &[i32] = &a[2..4];\n    println!(\"s: {s:?}\");\n}\n```\n\n- Slices borrow data from the sliced type.\n\n<details>\n\n- We create a slice by borrowing `a` and specifying the starting and ending\n  indexes in brackets.\n\n- If the slice starts at index 0, Rust’s range syntax allows us to drop the\n  starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are\n  identical.\n\n- The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are\n  identical.\n\n- To easily create a slice of the full array, we can therefore use `&a[..]`.\n\n- `s` is a reference to a slice of `i32`s. Notice that the type of `s`\n  (`&[i32]`) no longer mentions the array length. This allows us to perform\n  computation on slices of different sizes.\n\n- Slices always borrow from another object. In this example, `a` has to remain\n  'alive' (in scope) for at least as long as our slice.\n\n- You can't \"grow\" a slice once it's created:\n  - You can't append elements of the slice, since it doesn't own the backing\n    buffer.\n  - You can't grow a slice to point to a larger section of the backing buffer. A\n    slice does not have information about the length of the underlying buffer\n    and so you can't know how large the slice can be grown.\n  - To get a larger slice you have to go back to the original buffer and create\n    a larger slice from there.\n\n</details>\n","src/references/shared.md":"---\nminutes: 7\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Shared References\n\nA reference provides a way to access another value without taking ownership of\nthe value, and is also called \"borrowing\". Shared references are read-only, and\nthe referenced data cannot change.\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a = 'A';\n    let b = 'B';\n\n    let mut r: &char = &a;\n    dbg!(r);\n\n    r = &b;\n    dbg!(r);\n}\n```\n\nA shared reference to a type `T` has type `&T`. A reference value is made with\nthe `&` operator. The `*` operator \"dereferences\" a reference, yielding its\nvalue.\n\n<details>\n\n- References can never be null in Rust, so null checking is not necessary.\n\n- A reference is said to \"borrow\" the value it refers to, and this is a good\n  model for students not familiar with pointers: code can use the reference to\n  access the value, but is still \"owned\" by the original variable. The course\n  will get into more detail on ownership in day 3.\n\n- References are implemented as pointers, and a key advantage is that they can\n  be much smaller than the thing they point to. Students familiar with C or C++\n  will recognize references as pointers. Later parts of the course will cover\n  how Rust prevents the memory-safety bugs that come from using raw pointers.\n\n- Explicit referencing with `&` is required, except when invoking methods, where\n  Rust performs automatic referencing and dereferencing.\n\n- Rust will auto-dereference in some cases, in particular when invoking methods\n  (try `r.is_ascii()`). There is no need for an `->` operator like in C++.\n\n- In this example, `r` is mutable so that it can be reassigned (`r = &b`). Note\n  that this re-binds `r`, so that it refers to something else. This is different\n  from C++, where assignment to a reference changes the referenced value.\n\n- A shared reference does not allow modifying the value it refers to, even if\n  that value was mutable. Try `*r = 'X'`.\n\n- Rust is tracking the lifetimes of all references to ensure they live long\n  enough. Dangling references cannot occur in safe Rust.\n\n- We will talk more about borrowing and preventing dangling references when we\n  get to ownership.\n\n</details>\n","src/references/solution.md":"<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Solution\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n{{#include exercise.rs:solution}}\n```\n\n<details>\n\n- Note that in `normalize` we were able to do `*item /= mag` to modify each\n  element. This is because we're iterating using a mutable reference to an\n  array, which causes the `for` loop to give mutable references to each element.\n\n- It is also possible to take slice references here, e.g.,\n  `fn\n  magnitude(vector: &[f64]) -> f64`. This makes the function more general,\n  at the cost of a runtime length check.\n\n</details>\n","src/references/exercise.md":"---\nminutes: 20\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exercise: Geometry\n\nWe will create a few utility functions for 3-dimensional geometry, representing\na point as `[f64;3]`. It is up to you to determine the function signatures.\n\n```rust,compile_fail,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n// Calculate the magnitude of a vector by summing the squares of its coordinates\n// and taking the square root. Use the `sqrt()` method to calculate the square\n// root, like `v.sqrt()`.\n\n{{#include exercise.rs:magnitude}}\nfn magnitude(...) -> f64 {\n    todo!()\n}\n\n// Normalize a vector by calculating its magnitude and dividing all of its\n// coordinates by that magnitude.\n\n{{#include exercise.rs:normalize}}\nfn normalize(...) {\n    todo!()\n}\n\n// Use the following `main` to test your work.\n\n{{#include exercise.rs:main}}\n```\n","src/references/strings.md":"---\nminutes: 10\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n<!-- NOTES:\nIncluding `&str` as a way of representing a slice of valid utf-8\n-->\n\n# Strings\n\nWe can now understand the two string types in Rust:\n\n- `&str` is a slice of UTF-8 encoded bytes, similar to `&[u8]`.\n- `String` is an owned buffer of UTF-8 encoded bytes, similar to `Vec<T>`.\n\n<!-- Avoid using fixed integers when slicing since this breaks\ntranslations. Using the length of s1 and s2 is safe. -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let s1: &str = \"World\";\n    println!(\"s1: {s1}\");\n\n    let mut s2: String = String::from(\"Hello \");\n    println!(\"s2: {s2}\");\n\n    s2.push_str(s1);\n    println!(\"s2: {s2}\");\n\n    let s3: &str = &s2[2..9];\n    println!(\"s3: {s3}\");\n}\n```\n\n<details>\n\n- `&str` introduces a string slice, which is an immutable reference to UTF-8\n  encoded string data stored in a block of memory. String literals (`\"Hello\"`),\n  are stored in the program’s binary.\n\n- Rust's `String` type is a wrapper around a vector of bytes. As with a\n  `Vec<T>`, it is owned.\n\n- As with many other types `String::from()` creates a string from a string\n  literal; `String::new()` creates a new empty string, to which string data can\n  be added using the `push()` and `push_str()` methods.\n\n- The `format!()` macro is a convenient way to generate an owned string from\n  dynamic values. It accepts the same format specification as `println!()`.\n\n- You can borrow `&str` slices from `String` via `&` and optionally range\n  selection. If you select a byte range that is not aligned to character\n  boundaries, the expression will panic. The `chars` iterator iterates over\n  characters and is preferred over trying to get character boundaries right.\n\n- For C++ programmers: think of `&str` as `std::string_view` from C++, but the\n  one that always points to a valid string in memory. Rust `String` is a rough\n  equivalent of `std::string` from C++ (main difference: it can only contain\n  UTF-8 encoded bytes and will never use a small-string optimization).\n\n- Byte strings literals allow you to create a `&[u8]` value directly:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(\"{:?}\", b\"abc\");\n      println!(\"{:?}\", &[97, 98, 99]);\n  }\n  ```\n\n- Raw strings allow you to create a `&str` value with escapes disabled:\n  `r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal amount of `#`\n  on either side of the quotes:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(r#\"<a href=\"link.html\">link</a>\"#);\n      println!(\"<a href=\\\"link.html\\\">link</a>\");\n  }\n  ```\n\n</details>\n"},"files":{"GEMINI.md":"# Project Overview\n\nThis repository contains the source code for Comprehensive Rust, a family of\ncourses on Rust developed by Google, starting with Rust foundations, and\nincluding deep dives into specialized topics like Android, Chromium, bare-metal\ndevelopment, and concurrency. The project is a Rust workspace that leverages\n`mdbook` to generate a course website.\n\n## Key Technologies\n\n- **Rust:** The primary programming language for the course subject, custom\n  tools, and examples.\n- **mdbook:** A command-line tool to create books from Markdown files, used for\n  generating the course website.\n- **Custom mdbook Preprocessors:** `mdbook-course` and `mdbook-exerciser` are\n  Rust binaries that extend `mdbook`'s functionality, for example, to extract\n  exercise starter code.\n- **`cargo xtask`:** A custom binary within the workspace used for project\n  automation, simplifying common development tasks.\n\n# Building and Running\n\nThe project uses `cargo xtask` for project-specific automation, like builds,\ntests, and managing translations.\n\n## Setup\n\n1. **Install Rust:** Follow the instructions on\n   [https://rustup.rs/](https://rustup.rs/).\n2. **Clone Repository:**\n   ```bash\n   git clone https://github.com/google/comprehensive-rust/\n   cd comprehensive-rust\n   ```\n3. **Install Project Tools:**\n   ```bash\n   cargo xtask install-tools\n   ```\n   This is a necessary first step for working with this repository. It will\n   install the correct versions of all tools used by the project.\n\n## Commands\n\nAll commands are run using `cargo xtask`. Run `cargo xtask --help` for a full\nlist of options.\n\n- **Serve the Course Locally:** Starts a web server to view the course content.\n  ```bash\n  cargo xtask serve [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n  (e.g., `cargo xtask serve -l da` for the Danish translation)\n\n- **Build the Course:** Creates a static version of the course in the `book/`\n  directory.\n  ```bash\n  cargo xtask build [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n\n- **Run Rust Snippet Tests:** Tests all Rust code snippets included in the\n  course material.\n  ```bash\n  cargo xtask rust-tests\n  ```\n\n- **Run Web Driver Tests:** Executes web driver tests located in the `tests/`\n  directory.\n  ```bash\n  cargo xtask web-tests [--dir <book_html_directory>]\n  ```\n\n# Development Conventions\n\n- **Project Automation:** `cargo xtask` is the primary interface for common\n  development tasks.\n- **Course Content:** Markdown files in the `src/` directory, structured\n  according to `src/SUMMARY.md`.\n- **Code Formatting:** `dprint fmt` is used to format all source files according\n  to `rustfmt.toml` and `dprint.json`. Note that you must first install the\n  project tools with `cargo xtask install-tools`.\n- **Contributions:** Refer to `CONTRIBUTING.md` for guidelines on contributing\n  to the project.\n- **Style:** Refer to `STYLE.md` for style guidelines. When making changes to\n  Markdown files in `src/`, always first read `STYLE.md` and follow its\n  conventions.\n- **GitHub Actions:** The project uses composite GitHub Actions to simplify CI\n  workflows. These actions should be preferred over hand-written commands.\n  - **`apt-get-install`:** This action efficiently installs Debian packages. It\n    configures `dpkg` and `apt` to skip documentation and translations, and\n    ensures that `apt-get update` is run only once per job. This significantly\n    speeds up CI runs.\n  - **`install-mdbook`:** A composite action to install `mdbook` and its\n    dependencies, including `pandoc` and `texlive`.\n  - **`setup-rust-cache`:** A composite action that configures the\n    `Swatinem/rust-cache` action.\n\n## Developing Exercises\n\nExercises allow students to practice what they have learned. When adding or\nupdating exercises, follow these structural conventions:\n\n- **File Structure:**\n  - `exercise.md`: Contains the problem description and a code block with\n    placeholders.\n  - `exercise.rs`: Contains the full solution code, including a license header\n    and `ANCHOR` tags to delimit sections.\n  - `solution.md`: Includes the full solution code from `exercise.rs`.\n  - `Cargo.toml`: Must define a `[[bin]]` target pointing to `exercise.rs` so\n    that the solution code is compiled and tested.\n\n- **Content Inclusion:**\n  - Use `{{#include exercise.rs:anchor_name}}` in `exercise.md` to show specific\n    parts of the code (e.g., setup, main).\n  - Use `{{#include exercise.rs:solution}}` in `solution.md` to show the\n    solution code _without_ the license header. Ensure `exercise.rs` has a\n    `// ANCHOR: solution` line before the first line of the solution. It is\n    unnecessary to add a `// ANCHOR_END: solution` line at the bottom of the\n    file.\n\n- **Testing:**\n  - Run `cargo xtask rust-tests` to ensure the solution code compiles and runs\n    correctly.\n  - Run `cargo check -p <crate_name>` to verify the specific exercise crate.\n\n## Markdown Conventions\n\n- **Headings:**\n  - **H1 (`#`):** Used for the main title of each page. Each slide has exactly\n    one title.\n  - **H2 (`##`):** Used for major sections. Slides do not use H2 headings to\n    save vertical space; more slides are created instead.\n  - **H3 (`###`):** Used for sub-sections, but not on slides.\n\n- **Emphasis:**\n  - **Bold (`**...**`):** Used to highlight key terms, commands, and for notes\n    (e.g., `**Note:**`). The colon (`:`) is included inside the bold text for\n    notes.\n  - **Italic (`_..._`):** Used for general emphasis, titles of external\n    articles, and for terms being defined.\n\n- **Code:**\n  - **Inline Code (`` `...` ``):** Used for code snippets, file names, commands,\n    type names, and language keywords. Rust fragments are formatted as `rustfmt`\n    would.\n  - **Code Blocks (`` ```...``` ``):** Fenced code blocks are used for\n    multi-line code examples, annotated with a language identifier (e.g.,\n    `rust`, `c`, `ignore`).\n  - **Interactive Code Blocks:** Rust examples are made interactive with\n    `editable`. Examples that fail to compile are marked with `compile_fail` or\n    `should_panic`.\n  - **Diagrams:** The `bob` language identifier is used in code blocks to\n    generate ASCII art diagrams.\n  - **Formatting Control:** The `#[rustfmt::skip]` attribute is used to prevent\n    `rustfmt` from formatting specific code blocks, though it is used rarely.\n\n- **Lists:**\n  - **Bulleted Lists:** Unordered lists are the primary way to lay out key\n    points on slides.\n  - **Glossary Format:** The glossary uses a specific format with a colon and\n    backslash (`:\\`) after each term to create a hard line break for visual\n    formatting.\n\n- **Other Markdown Elements:**\n  - **Block Quotes (`> ...`):** Used sparingly for important notes, warnings, or\n    supplementary information to draw attention.\n  - **Links:** Both standard (`[text](url)`) and reference-style\n    (`[text][label]`) links are used.\n  - **Tables:** Markdown tables are used to present structured data.\n  - **Horizontal Rules (`---`):** Not used on slides.\n\n- **HTML Tags:**\n  - **`<details>`:** Used for collapsible \"speaker notes\".\n  - **`<kbd>`:** Used to denote keyboard keys. Each key in a combination must be\n    wrapped in its own tag, e.g., `<kbd>Ctrl</kbd> + <kbd>S</kbd>`.\n  - **`<style>`:** Used rarely for targeted custom CSS.\n  - **`<img>`:** Used to embed images.\n\n- **Project-Specific Conventions:**\n  - **mdbook Includes:** The `{{#include ...}}` helper is used to include\n    snippets from other files.\n  - **mdbook Segments:** The `{{%segment ...%}}` and `{{%session ...%}}` helpers\n    are used for course structuring.\n  - **Frontmatter:** Files start with YAML frontmatter (enclosed in `---`) to\n    provide metadata.\n  - **Doc Comments:** Standard Rust doc comments (`///`, `//!`) are used.\n    `/// # Safety` is used to document safety preconditions for `unsafe` code.\n  - **Comments:** HTML comments (`<!-- ... -->`) are used for editor/translator\n    instructions and content control (e.g., `mdbook-xgettext: skip`).\n\n# Project-Specific Technical Context\n\nThis section contains critical, non-obvious technical details about this\nproject's tooling and environment that an AI assistant needs to know to perform\nits tasks correctly.\n\n## `mdbook` Behavior\n\n- **Isolated Code Snippets:** `mdbook` treats each fenced Rust code block (e.g.,\n  `` ```rust ... ``` ``) as a separate compilation unit. When analyzing a code\n  snippet, treat it as a self-contained program. Do not assume it shares a scope\n  or context with other snippets in the same file unless the surrounding text\n  explicitly states otherwise.\n\n## Interacting with the `mdbook` Theme\n\nThe `mdbook` theme has several interactive elements. Here's how to interact with\nthem:\n\n- **Sidebar Toggle:** The sidebar can be opened and closed by clicking the\n  \"hamburger\" button in the top-left of the body text. This button has the ID\n  `sidebar-toggle`. You can use the following JavaScript to toggle the sidebar:\n\n  ```javascript\n  const button = document.getElementById(\"sidebar-toggle\");\n  button.click();\n  ```\n\n## WebdriverIO Testing\n\nThis project uses WebdriverIO for browser-based integration tests. Here are some\nkey findings about the test environment:\n\n### Test Environments\n\nThe `tests/` directory contains two primary configurations:\n\n- `npm test` (runs `wdio.conf.ts`): This is the standard for self-contained\n  integration tests. It uses `@wdio/static-server-service` to create a temporary\n  web server on port 8080.\n- `npm run test-mdbook` (runs `wdio.conf-mdbook.ts`): This is for testing\n  against a live `mdbook serve` instance, which typically runs on port 3000.\n\nIt is important to use the standard `npm test` command for most test development\nto ensure the tests are self-contained.\n\n### Writing Stable Tests\n\nTests can be flaky if they don't correctly handle the asynchronous nature of the\nweb browser and the test environment's state management.\n\n- **State Leakage Between Tests:** Despite what the WebdriverIO documentation\n  might suggest, `browser.url()` is not always sufficient to guarantee a clean\n  slate between tests. Lingering state, such as inline CSS styles applied by\n  JavaScript, can leak from one test into the next, causing unexpected failures.\n  The most effective solution found for this project is to add\n  `await browser.refresh();` to the `beforeEach` hook. This forces a full page\n  reload that properly clears the old state.\n\n- **Race Conditions with Dynamic Elements:** Many elements in this project are\n  created dynamically by JavaScript after the initial page load. If a test tries\n  to access an element immediately after navigation, it may fail because the\n  script hasn't finished running and the element doesn't exist in the DOM yet.\n  This creates a race condition. To prevent this, always use\n  `await element.waitForExist()` to ensure the element is present before trying\n  to interact with it or assert its state (e.g., `toBeDisplayed()`).\n\n### Handling Redirects\n\n`mdbook` uses a redirect map defined in `book.toml` under the\n`[output.html.redirect]` section. When writing tests, it is crucial to use the\nfinal, non-redirecting URL for navigation. Navigating to a URL that is a\nredirect will cause the browser to follow it, but this process can strip URL\nquery parameters, leading to test failures for features that depend on them.\n\n### Running and Debugging Tests\n\nTo run a single test file, use the `--spec` flag with the a string matching the\nfile name:\n\n```bash\nnpm test -- --spec redbox\n```\n\nTo check for flakiness, you can repeat a test multiple times using the\n`--repeat` flag:\n\n```bash\nnpm test -- --spec redbox --repeat 100\n```\n\nUse `--mochaOpts.grep` to run a single test within a file:\n\n```bash\nnpm test -- --spec redbox --mochaOpts.grep \"should be hidden by default\"\n```\n","src/references/dangling.md":"---\nminutes: 3\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Reference Validity\n\nRust enforces a number of rules for references that make them always safe to\nuse. One rule is that references can never be `null`, making them safe to use\nwithout `null` checks. The other rule we'll look at for now is that references\ncan't _outlive_ the data they point to.\n\n```rust,editable,compile_fail\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let x_ref = {\n        let x = 10;\n        &x\n    };\n    dbg!(x_ref);\n}\n```\n\n<details>\n\n- This slide gets students thinking about references as not simply being\n  pointers, since Rust has different rules for references than other languages.\n\n- We'll look at the rest of Rust's borrowing rules on day 3 when we talk about\n  Rust's ownership system.\n\n## More to Explore\n\n- Rust's equivalent of nullability is the `Option` type, which can be used to\n  make any type \"nullable\" (not just references/pointers). We haven't yet\n  introduced enums or pattern matching, though, so try not to go into too much\n  detail about this here.\n\n</details>\n","src/references/exclusive.md":"---\nminutes: 5\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exclusive References\n\nExclusive references, also known as mutable references, allow changing the value\nthey refer to. They have type `&mut T`.\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let mut point = (1, 2);\n    let x_coord = &mut point.0;\n    *x_coord = 20;\n    println!(\"point: {point:?}\");\n}\n```\n\n<details>\n\nKey points:\n\n- \"Exclusive\" means that only this reference can be used to access the value. No\n  other references (shared or exclusive) can exist at the same time, and the\n  referenced value cannot be accessed while the exclusive reference exists. Try\n  making an `&point.0` or changing `point.0` while `x_coord` is alive.\n\n- Be sure to note the difference between `let mut x_coord: &i32` and\n  `let x_coord: &mut i32`. The first one is a shared reference that can be bound\n  to different values, while the second is an exclusive reference to a mutable\n  value.\n\n</details>\n","src/references/slices.md":"---\nminutes: 7\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Slices\n\nA slice gives you a view into a larger collection:\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n    println!(\"a: {a:?}\");\n\n    let s: &[i32] = &a[2..4];\n    println!(\"s: {s:?}\");\n}\n```\n\n- Slices borrow data from the sliced type.\n\n<details>\n\n- We create a slice by borrowing `a` and specifying the starting and ending\n  indexes in brackets.\n\n- If the slice starts at index 0, Rust’s range syntax allows us to drop the\n  starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are\n  identical.\n\n- The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are\n  identical.\n\n- To easily create a slice of the full array, we can therefore use `&a[..]`.\n\n- `s` is a reference to a slice of `i32`s. Notice that the type of `s`\n  (`&[i32]`) no longer mentions the array length. This allows us to perform\n  computation on slices of different sizes.\n\n- Slices always borrow from another object. In this example, `a` has to remain\n  'alive' (in scope) for at least as long as our slice.\n\n- You can't \"grow\" a slice once it's created:\n  - You can't append elements of the slice, since it doesn't own the backing\n    buffer.\n  - You can't grow a slice to point to a larger section of the backing buffer. A\n    slice does not have information about the length of the underlying buffer\n    and so you can't know how large the slice can be grown.\n  - To get a larger slice you have to go back to the original buffer and create\n    a larger slice from there.\n\n</details>\n","src/references/shared.md":"---\nminutes: 7\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Shared References\n\nA reference provides a way to access another value without taking ownership of\nthe value, and is also called \"borrowing\". Shared references are read-only, and\nthe referenced data cannot change.\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a = 'A';\n    let b = 'B';\n\n    let mut r: &char = &a;\n    dbg!(r);\n\n    r = &b;\n    dbg!(r);\n}\n```\n\nA shared reference to a type `T` has type `&T`. A reference value is made with\nthe `&` operator. The `*` operator \"dereferences\" a reference, yielding its\nvalue.\n\n<details>\n\n- References can never be null in Rust, so null checking is not necessary.\n\n- A reference is said to \"borrow\" the value it refers to, and this is a good\n  model for students not familiar with pointers: code can use the reference to\n  access the value, but is still \"owned\" by the original variable. The course\n  will get into more detail on ownership in day 3.\n\n- References are implemented as pointers, and a key advantage is that they can\n  be much smaller than the thing they point to. Students familiar with C or C++\n  will recognize references as pointers. Later parts of the course will cover\n  how Rust prevents the memory-safety bugs that come from using raw pointers.\n\n- Explicit referencing with `&` is required, except when invoking methods, where\n  Rust performs automatic referencing and dereferencing.\n\n- Rust will auto-dereference in some cases, in particular when invoking methods\n  (try `r.is_ascii()`). There is no need for an `->` operator like in C++.\n\n- In this example, `r` is mutable so that it can be reassigned (`r = &b`). Note\n  that this re-binds `r`, so that it refers to something else. This is different\n  from C++, where assignment to a reference changes the referenced value.\n\n- A shared reference does not allow modifying the value it refers to, even if\n  that value was mutable. Try `*r = 'X'`.\n\n- Rust is tracking the lifetimes of all references to ensure they live long\n  enough. Dangling references cannot occur in safe Rust.\n\n- We will talk more about borrowing and preventing dangling references when we\n  get to ownership.\n\n</details>\n","src/references/solution.md":"<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Solution\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n{{#include exercise.rs:solution}}\n```\n\n<details>\n\n- Note that in `normalize` we were able to do `*item /= mag` to modify each\n  element. This is because we're iterating using a mutable reference to an\n  array, which causes the `for` loop to give mutable references to each element.\n\n- It is also possible to take slice references here, e.g.,\n  `fn\n  magnitude(vector: &[f64]) -> f64`. This makes the function more general,\n  at the cost of a runtime length check.\n\n</details>\n","src/references/exercise.md":"---\nminutes: 20\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exercise: Geometry\n\nWe will create a few utility functions for 3-dimensional geometry, representing\na point as `[f64;3]`. It is up to you to determine the function signatures.\n\n```rust,compile_fail,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n// Calculate the magnitude of a vector by summing the squares of its coordinates\n// and taking the square root. Use the `sqrt()` method to calculate the square\n// root, like `v.sqrt()`.\n\n{{#include exercise.rs:magnitude}}\nfn magnitude(...) -> f64 {\n    todo!()\n}\n\n// Normalize a vector by calculating its magnitude and dividing all of its\n// coordinates by that magnitude.\n\n{{#include exercise.rs:normalize}}\nfn normalize(...) {\n    todo!()\n}\n\n// Use the following `main` to test your work.\n\n{{#include exercise.rs:main}}\n```\n","src/references/strings.md":"---\nminutes: 10\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n<!-- NOTES:\nIncluding `&str` as a way of representing a slice of valid utf-8\n-->\n\n# Strings\n\nWe can now understand the two string types in Rust:\n\n- `&str` is a slice of UTF-8 encoded bytes, similar to `&[u8]`.\n- `String` is an owned buffer of UTF-8 encoded bytes, similar to `Vec<T>`.\n\n<!-- Avoid using fixed integers when slicing since this breaks\ntranslations. Using the length of s1 and s2 is safe. -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let s1: &str = \"World\";\n    println!(\"s1: {s1}\");\n\n    let mut s2: String = String::from(\"Hello \");\n    println!(\"s2: {s2}\");\n\n    s2.push_str(s1);\n    println!(\"s2: {s2}\");\n\n    let s3: &str = &s2[2..9];\n    println!(\"s3: {s3}\");\n}\n```\n\n<details>\n\n- `&str` introduces a string slice, which is an immutable reference to UTF-8\n  encoded string data stored in a block of memory. String literals (`\"Hello\"`),\n  are stored in the program’s binary.\n\n- Rust's `String` type is a wrapper around a vector of bytes. As with a\n  `Vec<T>`, it is owned.\n\n- As with many other types `String::from()` creates a string from a string\n  literal; `String::new()` creates a new empty string, to which string data can\n  be added using the `push()` and `push_str()` methods.\n\n- The `format!()` macro is a convenient way to generate an owned string from\n  dynamic values. It accepts the same format specification as `println!()`.\n\n- You can borrow `&str` slices from `String` via `&` and optionally range\n  selection. If you select a byte range that is not aligned to character\n  boundaries, the expression will panic. The `chars` iterator iterates over\n  characters and is preferred over trying to get character boundaries right.\n\n- For C++ programmers: think of `&str` as `std::string_view` from C++, but the\n  one that always points to a valid string in memory. Rust `String` is a rough\n  equivalent of `std::string` from C++ (main difference: it can only contain\n  UTF-8 encoded bytes and will never use a small-string optimization).\n\n- Byte strings literals allow you to create a `&[u8]` value directly:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(\"{:?}\", b\"abc\");\n      println!(\"{:?}\", &[97, 98, 99]);\n  }\n  ```\n\n- Raw strings allow you to create a `&str` value with escapes disabled:\n  `r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal amount of `#`\n  on either side of the quotes:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(r#\"<a href=\"link.html\">link</a>\"#);\n      println!(\"<a href=\\\"link.html\\\">link</a>\");\n  }\n  ```\n\n</details>\n"},"items":[{"name":"dangling.md","path":"src/references/dangling.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/src/references/dangling.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"---\nminutes: 3\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Reference Validity\n\nRust enforces a number of rules for references that make them always safe to\nuse. One rule is that references can never be `null`, making them safe to use\nwithout `null` checks. The other rule we'll look at for now is that references\ncan't _outlive_ the data they point to.\n\n```rust,editable,compile_fail\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let x_ref = {\n        let x = 10;\n        &x\n    };\n    dbg!(x_ref);\n}\n```\n\n<details>\n\n- This slide gets students thinking about references as not simply being\n  pointers, since Rust has different rules for references than other languages.\n\n- We'll look at the rest of Rust's borrowing rules on day 3 when we talk about\n  Rust's ownership system.\n\n## More to Explore\n\n- Rust's equivalent of nullability is the `Option` type, which can be used to\n  make any type \"nullable\" (not just references/pointers). We haven't yet\n  introduced enums or pattern matching, though, so try not to go into too much\n  detail about this here.\n\n</details>\n","frontmatter":{"minutes":3},"isInternal":false,"tokens":292,"sizeBytes":1145},{"name":"exclusive.md","path":"src/references/exclusive.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/src/references/exclusive.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"---\nminutes: 5\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exclusive References\n\nExclusive references, also known as mutable references, allow changing the value\nthey refer to. They have type `&mut T`.\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let mut point = (1, 2);\n    let x_coord = &mut point.0;\n    *x_coord = 20;\n    println!(\"point: {point:?}\");\n}\n```\n\n<details>\n\nKey points:\n\n- \"Exclusive\" means that only this reference can be used to access the value. No\n  other references (shared or exclusive) can exist at the same time, and the\n  referenced value cannot be accessed while the exclusive reference exists. Try\n  making an `&point.0` or changing `point.0` while `x_coord` is alive.\n\n- Be sure to note the difference between `let mut x_coord: &i32` and\n  `let x_coord: &mut i32`. The first one is a shared reference that can be bound\n  to different values, while the second is an exclusive reference to a mutable\n  value.\n\n</details>\n","frontmatter":{"minutes":5},"isInternal":false,"tokens":286,"sizeBytes":1076},{"name":"exercise.md","path":"src/references/exercise.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/src/references/exercise.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"---\nminutes: 20\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exercise: Geometry\n\nWe will create a few utility functions for 3-dimensional geometry, representing\na point as `[f64;3]`. It is up to you to determine the function signatures.\n\n```rust,compile_fail,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n// Calculate the magnitude of a vector by summing the squares of its coordinates\n// and taking the square root. Use the `sqrt()` method to calculate the square\n// root, like `v.sqrt()`.\n\n{{#include exercise.rs:magnitude}}\nfn magnitude(...) -> f64 {\n    todo!()\n}\n\n// Normalize a vector by calculating its magnitude and dividing all of its\n// coordinates by that magnitude.\n\n{{#include exercise.rs:normalize}}\nfn normalize(...) {\n    todo!()\n}\n\n// Use the following `main` to test your work.\n\n{{#include exercise.rs:main}}\n```\n","frontmatter":{"minutes":20},"isInternal":false,"tokens":222,"sizeBytes":901},{"name":"shared.md","path":"src/references/shared.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/src/references/shared.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"---\nminutes: 7\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Shared References\n\nA reference provides a way to access another value without taking ownership of\nthe value, and is also called \"borrowing\". Shared references are read-only, and\nthe referenced data cannot change.\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a = 'A';\n    let b = 'B';\n\n    let mut r: &char = &a;\n    dbg!(r);\n\n    r = &b;\n    dbg!(r);\n}\n```\n\nA shared reference to a type `T` has type `&T`. A reference value is made with\nthe `&` operator. The `*` operator \"dereferences\" a reference, yielding its\nvalue.\n\n<details>\n\n- References can never be null in Rust, so null checking is not necessary.\n\n- A reference is said to \"borrow\" the value it refers to, and this is a good\n  model for students not familiar with pointers: code can use the reference to\n  access the value, but is still \"owned\" by the original variable. The course\n  will get into more detail on ownership in day 3.\n\n- References are implemented as pointers, and a key advantage is that they can\n  be much smaller than the thing they point to. Students familiar with C or C++\n  will recognize references as pointers. Later parts of the course will cover\n  how Rust prevents the memory-safety bugs that come from using raw pointers.\n\n- Explicit referencing with `&` is required, except when invoking methods, where\n  Rust performs automatic referencing and dereferencing.\n\n- Rust will auto-dereference in some cases, in particular when invoking methods\n  (try `r.is_ascii()`). There is no need for an `->` operator like in C++.\n\n- In this example, `r` is mutable so that it can be reassigned (`r = &b`). Note\n  that this re-binds `r`, so that it refers to something else. This is different\n  from C++, where assignment to a reference changes the referenced value.\n\n- A shared reference does not allow modifying the value it refers to, even if\n  that value was mutable. Try `*r = 'X'`.\n\n- Rust is tracking the lifetimes of all references to ensure they live long\n  enough. Dangling references cannot occur in safe Rust.\n\n- We will talk more about borrowing and preventing dangling references when we\n  get to ownership.\n\n</details>\n","frontmatter":{"minutes":7},"isInternal":false,"tokens":555,"sizeBytes":2267},{"name":"slices.md","path":"src/references/slices.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/src/references/slices.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"---\nminutes: 7\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Slices\n\nA slice gives you a view into a larger collection:\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n    println!(\"a: {a:?}\");\n\n    let s: &[i32] = &a[2..4];\n    println!(\"s: {s:?}\");\n}\n```\n\n- Slices borrow data from the sliced type.\n\n<details>\n\n- We create a slice by borrowing `a` and specifying the starting and ending\n  indexes in brackets.\n\n- If the slice starts at index 0, Rust’s range syntax allows us to drop the\n  starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are\n  identical.\n\n- The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are\n  identical.\n\n- To easily create a slice of the full array, we can therefore use `&a[..]`.\n\n- `s` is a reference to a slice of `i32`s. Notice that the type of `s`\n  (`&[i32]`) no longer mentions the array length. This allows us to perform\n  computation on slices of different sizes.\n\n- Slices always borrow from another object. In this example, `a` has to remain\n  'alive' (in scope) for at least as long as our slice.\n\n- You can't \"grow\" a slice once it's created:\n  - You can't append elements of the slice, since it doesn't own the backing\n    buffer.\n  - You can't grow a slice to point to a larger section of the backing buffer. A\n    slice does not have information about the length of the underlying buffer\n    and so you can't know how large the slice can be grown.\n  - To get a larger slice you have to go back to the original buffer and create\n    a larger slice from there.\n\n</details>\n","frontmatter":{"minutes":7},"isInternal":false,"tokens":496,"sizeBytes":1719},{"name":"solution.md","path":"src/references/solution.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/src/references/solution.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Solution\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n{{#include exercise.rs:solution}}\n```\n\n<details>\n\n- Note that in `normalize` we were able to do `*item /= mag` to modify each\n  element. This is because we're iterating using a mutable reference to an\n  array, which causes the `for` loop to give mutable references to each element.\n\n- It is also possible to take slice references here, e.g.,\n  `fn\n  magnitude(vector: &[f64]) -> f64`. This makes the function more general,\n  at the cost of a runtime length check.\n\n</details>\n","isInternal":false,"tokens":171,"sizeBytes":650},{"name":"strings.md","path":"src/references/strings.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/src/references/strings.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"---\nminutes: 10\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n<!-- NOTES:\nIncluding `&str` as a way of representing a slice of valid utf-8\n-->\n\n# Strings\n\nWe can now understand the two string types in Rust:\n\n- `&str` is a slice of UTF-8 encoded bytes, similar to `&[u8]`.\n- `String` is an owned buffer of UTF-8 encoded bytes, similar to `Vec<T>`.\n\n<!-- Avoid using fixed integers when slicing since this breaks\ntranslations. Using the length of s1 and s2 is safe. -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let s1: &str = \"World\";\n    println!(\"s1: {s1}\");\n\n    let mut s2: String = String::from(\"Hello \");\n    println!(\"s2: {s2}\");\n\n    s2.push_str(s1);\n    println!(\"s2: {s2}\");\n\n    let s3: &str = &s2[2..9];\n    println!(\"s3: {s3}\");\n}\n```\n\n<details>\n\n- `&str` introduces a string slice, which is an immutable reference to UTF-8\n  encoded string data stored in a block of memory. String literals (`\"Hello\"`),\n  are stored in the program’s binary.\n\n- Rust's `String` type is a wrapper around a vector of bytes. As with a\n  `Vec<T>`, it is owned.\n\n- As with many other types `String::from()` creates a string from a string\n  literal; `String::new()` creates a new empty string, to which string data can\n  be added using the `push()` and `push_str()` methods.\n\n- The `format!()` macro is a convenient way to generate an owned string from\n  dynamic values. It accepts the same format specification as `println!()`.\n\n- You can borrow `&str` slices from `String` via `&` and optionally range\n  selection. If you select a byte range that is not aligned to character\n  boundaries, the expression will panic. The `chars` iterator iterates over\n  characters and is preferred over trying to get character boundaries right.\n\n- For C++ programmers: think of `&str` as `std::string_view` from C++, but the\n  one that always points to a valid string in memory. Rust `String` is a rough\n  equivalent of `std::string` from C++ (main difference: it can only contain\n  UTF-8 encoded bytes and will never use a small-string optimization).\n\n- Byte strings literals allow you to create a `&[u8]` value directly:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(\"{:?}\", b\"abc\");\n      println!(\"{:?}\", &[97, 98, 99]);\n  }\n  ```\n\n- Raw strings allow you to create a `&str` value with escapes disabled:\n  `r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal amount of `#`\n  on either side of the quotes:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(r#\"<a href=\"link.html\">link</a>\"#);\n      println!(\"<a href=\\\"link.html\\\">link</a>\");\n  }\n  ```\n\n</details>\n","frontmatter":{"minutes":10},"isInternal":false,"tokens":802,"sizeBytes":2878},{"name":"GEMINI.md","path":"GEMINI.md","rawUrl":"https://raw.githubusercontent.com/google/comprehensive-rust/HEAD/GEMINI.md","title":"Gemini Agent & Antigravity Instructions","category":"gemini-rule","format":"markdown","content":"# Project Overview\n\nThis repository contains the source code for Comprehensive Rust, a family of\ncourses on Rust developed by Google, starting with Rust foundations, and\nincluding deep dives into specialized topics like Android, Chromium, bare-metal\ndevelopment, and concurrency. The project is a Rust workspace that leverages\n`mdbook` to generate a course website.\n\n## Key Technologies\n\n- **Rust:** The primary programming language for the course subject, custom\n  tools, and examples.\n- **mdbook:** A command-line tool to create books from Markdown files, used for\n  generating the course website.\n- **Custom mdbook Preprocessors:** `mdbook-course` and `mdbook-exerciser` are\n  Rust binaries that extend `mdbook`'s functionality, for example, to extract\n  exercise starter code.\n- **`cargo xtask`:** A custom binary within the workspace used for project\n  automation, simplifying common development tasks.\n\n# Building and Running\n\nThe project uses `cargo xtask` for project-specific automation, like builds,\ntests, and managing translations.\n\n## Setup\n\n1. **Install Rust:** Follow the instructions on\n   [https://rustup.rs/](https://rustup.rs/).\n2. **Clone Repository:**\n   ```bash\n   git clone https://github.com/google/comprehensive-rust/\n   cd comprehensive-rust\n   ```\n3. **Install Project Tools:**\n   ```bash\n   cargo xtask install-tools\n   ```\n   This is a necessary first step for working with this repository. It will\n   install the correct versions of all tools used by the project.\n\n## Commands\n\nAll commands are run using `cargo xtask`. Run `cargo xtask --help` for a full\nlist of options.\n\n- **Serve the Course Locally:** Starts a web server to view the course content.\n  ```bash\n  cargo xtask serve [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n  (e.g., `cargo xtask serve -l da` for the Danish translation)\n\n- **Build the Course:** Creates a static version of the course in the `book/`\n  directory.\n  ```bash\n  cargo xtask build [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n\n- **Run Rust Snippet Tests:** Tests all Rust code snippets included in the\n  course material.\n  ```bash\n  cargo xtask rust-tests\n  ```\n\n- **Run Web Driver Tests:** Executes web driver tests located in the `tests/`\n  directory.\n  ```bash\n  cargo xtask web-tests [--dir <book_html_directory>]\n  ```\n\n# Development Conventions\n\n- **Project Automation:** `cargo xtask` is the primary interface for common\n  development tasks.\n- **Course Content:** Markdown files in the `src/` directory, structured\n  according to `src/SUMMARY.md`.\n- **Code Formatting:** `dprint fmt` is used to format all source files according\n  to `rustfmt.toml` and `dprint.json`. Note that you must first install the\n  project tools with `cargo xtask install-tools`.\n- **Contributions:** Refer to `CONTRIBUTING.md` for guidelines on contributing\n  to the project.\n- **Style:** Refer to `STYLE.md` for style guidelines. When making changes to\n  Markdown files in `src/`, always first read `STYLE.md` and follow its\n  conventions.\n- **GitHub Actions:** The project uses composite GitHub Actions to simplify CI\n  workflows. These actions should be preferred over hand-written commands.\n  - **`apt-get-install`:** This action efficiently installs Debian packages. It\n    configures `dpkg` and `apt` to skip documentation and translations, and\n    ensures that `apt-get update` is run only once per job. This significantly\n    speeds up CI runs.\n  - **`install-mdbook`:** A composite action to install `mdbook` and its\n    dependencies, including `pandoc` and `texlive`.\n  - **`setup-rust-cache`:** A composite action that configures the\n    `Swatinem/rust-cache` action.\n\n## Developing Exercises\n\nExercises allow students to practice what they have learned. When adding or\nupdating exercises, follow these structural conventions:\n\n- **File Structure:**\n  - `exercise.md`: Contains the problem description and a code block with\n    placeholders.\n  - `exercise.rs`: Contains the full solution code, including a license header\n    and `ANCHOR` tags to delimit sections.\n  - `solution.md`: Includes the full solution code from `exercise.rs`.\n  - `Cargo.toml`: Must define a `[[bin]]` target pointing to `exercise.rs` so\n    that the solution code is compiled and tested.\n\n- **Content Inclusion:**\n  - Use `{{#include exercise.rs:anchor_name}}` in `exercise.md` to show specific\n    parts of the code (e.g., setup, main).\n  - Use `{{#include exercise.rs:solution}}` in `solution.md` to show the\n    solution code _without_ the license header. Ensure `exercise.rs` has a\n    `// ANCHOR: solution` line before the first line of the solution. It is\n    unnecessary to add a `// ANCHOR_END: solution` line at the bottom of the\n    file.\n\n- **Testing:**\n  - Run `cargo xtask rust-tests` to ensure the solution code compiles and runs\n    correctly.\n  - Run `cargo check -p <crate_name>` to verify the specific exercise crate.\n\n## Markdown Conventions\n\n- **Headings:**\n  - **H1 (`#`):** Used for the main title of each page. Each slide has exactly\n    one title.\n  - **H2 (`##`):** Used for major sections. Slides do not use H2 headings to\n    save vertical space; more slides are created instead.\n  - **H3 (`###`):** Used for sub-sections, but not on slides.\n\n- **Emphasis:**\n  - **Bold (`**...**`):** Used to highlight key terms, commands, and for notes\n    (e.g., `**Note:**`). The colon (`:`) is included inside the bold text for\n    notes.\n  - **Italic (`_..._`):** Used for general emphasis, titles of external\n    articles, and for terms being defined.\n\n- **Code:**\n  - **Inline Code (`` `...` ``):** Used for code snippets, file names, commands,\n    type names, and language keywords. Rust fragments are formatted as `rustfmt`\n    would.\n  - **Code Blocks (`` ```...``` ``):** Fenced code blocks are used for\n    multi-line code examples, annotated with a language identifier (e.g.,\n    `rust`, `c`, `ignore`).\n  - **Interactive Code Blocks:** Rust examples are made interactive with\n    `editable`. Examples that fail to compile are marked with `compile_fail` or\n    `should_panic`.\n  - **Diagrams:** The `bob` language identifier is used in code blocks to\n    generate ASCII art diagrams.\n  - **Formatting Control:** The `#[rustfmt::skip]` attribute is used to prevent\n    `rustfmt` from formatting specific code blocks, though it is used rarely.\n\n- **Lists:**\n  - **Bulleted Lists:** Unordered lists are the primary way to lay out key\n    points on slides.\n  - **Glossary Format:** The glossary uses a specific format with a colon and\n    backslash (`:\\`) after each term to create a hard line break for visual\n    formatting.\n\n- **Other Markdown Elements:**\n  - **Block Quotes (`> ...`):** Used sparingly for important notes, warnings, or\n    supplementary information to draw attention.\n  - **Links:** Both standard (`[text](url)`) and reference-style\n    (`[text][label]`) links are used.\n  - **Tables:** Markdown tables are used to present structured data.\n  - **Horizontal Rules (`---`):** Not used on slides.\n\n- **HTML Tags:**\n  - **`<details>`:** Used for collapsible \"speaker notes\".\n  - **`<kbd>`:** Used to denote keyboard keys. Each key in a combination must be\n    wrapped in its own tag, e.g., `<kbd>Ctrl</kbd> + <kbd>S</kbd>`.\n  - **`<style>`:** Used rarely for targeted custom CSS.\n  - **`<img>`:** Used to embed images.\n\n- **Project-Specific Conventions:**\n  - **mdbook Includes:** The `{{#include ...}}` helper is used to include\n    snippets from other files.\n  - **mdbook Segments:** The `{{%segment ...%}}` and `{{%session ...%}}` helpers\n    are used for course structuring.\n  - **Frontmatter:** Files start with YAML frontmatter (enclosed in `---`) to\n    provide metadata.\n  - **Doc Comments:** Standard Rust doc comments (`///`, `//!`) are used.\n    `/// # Safety` is used to document safety preconditions for `unsafe` code.\n  - **Comments:** HTML comments (`<!-- ... -->`) are used for editor/translator\n    instructions and content control (e.g., `mdbook-xgettext: skip`).\n\n# Project-Specific Technical Context\n\nThis section contains critical, non-obvious technical details about this\nproject's tooling and environment that an AI assistant needs to know to perform\nits tasks correctly.\n\n## `mdbook` Behavior\n\n- **Isolated Code Snippets:** `mdbook` treats each fenced Rust code block (e.g.,\n  `` ```rust ... ``` ``) as a separate compilation unit. When analyzing a code\n  snippet, treat it as a self-contained program. Do not assume it shares a scope\n  or context with other snippets in the same file unless the surrounding text\n  explicitly states otherwise.\n\n## Interacting with the `mdbook` Theme\n\nThe `mdbook` theme has several interactive elements. Here's how to interact with\nthem:\n\n- **Sidebar Toggle:** The sidebar can be opened and closed by clicking the\n  \"hamburger\" button in the top-left of the body text. This button has the ID\n  `sidebar-toggle`. You can use the following JavaScript to toggle the sidebar:\n\n  ```javascript\n  const button = document.getElementById(\"sidebar-toggle\");\n  button.click();\n  ```\n\n## WebdriverIO Testing\n\nThis project uses WebdriverIO for browser-based integration tests. Here are some\nkey findings about the test environment:\n\n### Test Environments\n\nThe `tests/` directory contains two primary configurations:\n\n- `npm test` (runs `wdio.conf.ts`): This is the standard for self-contained\n  integration tests. It uses `@wdio/static-server-service` to create a temporary\n  web server on port 8080.\n- `npm run test-mdbook` (runs `wdio.conf-mdbook.ts`): This is for testing\n  against a live `mdbook serve` instance, which typically runs on port 3000.\n\nIt is important to use the standard `npm test` command for most test development\nto ensure the tests are self-contained.\n\n### Writing Stable Tests\n\nTests can be flaky if they don't correctly handle the asynchronous nature of the\nweb browser and the test environment's state management.\n\n- **State Leakage Between Tests:** Despite what the WebdriverIO documentation\n  might suggest, `browser.url()` is not always sufficient to guarantee a clean\n  slate between tests. Lingering state, such as inline CSS styles applied by\n  JavaScript, can leak from one test into the next, causing unexpected failures.\n  The most effective solution found for this project is to add\n  `await browser.refresh();` to the `beforeEach` hook. This forces a full page\n  reload that properly clears the old state.\n\n- **Race Conditions with Dynamic Elements:** Many elements in this project are\n  created dynamically by JavaScript after the initial page load. If a test tries\n  to access an element immediately after navigation, it may fail because the\n  script hasn't finished running and the element doesn't exist in the DOM yet.\n  This creates a race condition. To prevent this, always use\n  `await element.waitForExist()` to ensure the element is present before trying\n  to interact with it or assert its state (e.g., `toBeDisplayed()`).\n\n### Handling Redirects\n\n`mdbook` uses a redirect map defined in `book.toml` under the\n`[output.html.redirect]` section. When writing tests, it is crucial to use the\nfinal, non-redirecting URL for navigation. Navigating to a URL that is a\nredirect will cause the browser to follow it, but this process can strip URL\nquery parameters, leading to test failures for features that depend on them.\n\n### Running and Debugging Tests\n\nTo run a single test file, use the `--spec` flag with the a string matching the\nfile name:\n\n```bash\nnpm test -- --spec redbox\n```\n\nTo check for flakiness, you can repeat a test multiple times using the\n`--repeat` flag:\n\n```bash\nnpm test -- --spec redbox --repeat 100\n```\n\nUse `--mochaOpts.grep` to run a single test within a file:\n\n```bash\nnpm test -- --spec redbox --mochaOpts.grep \"should be hidden by default\"\n```\n","isInternal":false,"tokens":2862,"sizeBytes":11785}],"systemPromptSnippet":"<yakaai_skills repo=\"google/comprehensive-rust\">\n<!-- File: src/references/dangling.md (Tokens: ~292 | Category: anthropic-skill) -->\n---\nminutes: 3\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Reference Validity\n\nRust enforces a number of rules for references that make them always safe to\nuse. One rule is that references can never be `null`, making them safe to use\nwithout `null` checks. The other rule we'll look at for now is that references\ncan't _outlive_ the data they point to.\n\n```rust,editable,compile_fail\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let x_ref = {\n        let x = 10;\n        &x\n    };\n    dbg!(x_ref);\n}\n```\n\n<details>\n\n- This slide gets students thinking about references as not simply being\n  pointers, since Rust has different rules for references than other languages.\n\n- We'll look at the rest of Rust's borrowing rules on day 3 when we talk about\n  Rust's ownership system.\n\n## More to Explore\n\n- Rust's equivalent of nullability is the `Option` type, which can be used to\n  make any type \"nullable\" (not just references/pointers). We haven't yet\n  introduced enums or pattern matching, though, so try not to go into too much\n  detail about this here.\n\n</details>\n\n<!-- File: src/references/exclusive.md (Tokens: ~286 | Category: anthropic-skill) -->\n---\nminutes: 5\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exclusive References\n\nExclusive references, also known as mutable references, allow changing the value\nthey refer to. They have type `&mut T`.\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let mut point = (1, 2);\n    let x_coord = &mut point.0;\n    *x_coord = 20;\n    println!(\"point: {point:?}\");\n}\n```\n\n<details>\n\nKey points:\n\n- \"Exclusive\" means that only this reference can be used to access the value. No\n  other references (shared or exclusive) can exist at the same time, and the\n  referenced value cannot be accessed while the exclusive reference exists. Try\n  making an `&point.0` or changing `point.0` while `x_coord` is alive.\n\n- Be sure to note the difference between `let mut x_coord: &i32` and\n  `let x_coord: &mut i32`. The first one is a shared reference that can be bound\n  to different values, while the second is an exclusive reference to a mutable\n  value.\n\n</details>\n\n<!-- File: src/references/exercise.md (Tokens: ~222 | Category: anthropic-skill) -->\n---\nminutes: 20\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Exercise: Geometry\n\nWe will create a few utility functions for 3-dimensional geometry, representing\na point as `[f64;3]`. It is up to you to determine the function signatures.\n\n```rust,compile_fail,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n// Calculate the magnitude of a vector by summing the squares of its coordinates\n// and taking the square root. Use the `sqrt()` method to calculate the square\n// root, like `v.sqrt()`.\n\n{{#include exercise.rs:magnitude}}\nfn magnitude(...) -> f64 {\n    todo!()\n}\n\n// Normalize a vector by calculating its magnitude and dividing all of its\n// coordinates by that magnitude.\n\n{{#include exercise.rs:normalize}}\nfn normalize(...) {\n    todo!()\n}\n\n// Use the following `main` to test your work.\n\n{{#include exercise.rs:main}}\n```\n\n<!-- File: src/references/shared.md (Tokens: ~555 | Category: anthropic-skill) -->\n---\nminutes: 7\n---\n\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Shared References\n\nA reference provides a way to access another value without taking ownership of\nthe value, and is also called \"borrowing\". Shared references are read-only, and\nthe referenced data cannot change.\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a = 'A';\n    let b = 'B';\n\n    let mut r: &char = &a;\n    dbg!(r);\n\n    r = &b;\n    dbg!(r);\n}\n```\n\nA shared reference to a type `T` has type `&T`. A reference value is made with\nthe `&` operator. The `*` operator \"dereferences\" a reference, yielding its\nvalue.\n\n<details>\n\n- References can never be null in Rust, so null checking is not necessary.\n\n- A reference is said to \"borrow\" the value it refers to, and this is a good\n  model for students not familiar with pointers: code can use the reference to\n  access the value, but is still \"owned\" by the original variable. The course\n  will get into more detail on ownership in day 3.\n\n- References are implemented as pointers, and a key advantage is that they can\n  be much smaller than the thing they point to. Students familiar with C or C++\n  will recognize references as pointers. Later parts of the course will cover\n  how Rust prevents the memory-safety bugs that come from using raw pointers.\n\n- Explicit referencing with `&` is required, except when invoking methods, where\n  Rust performs automatic referencing and dereferencing.\n\n- Rust will auto-dereference in some cases, in particular when invoking methods\n  (try `r.is_ascii()`). There is no need for an `->` operator like in C++.\n\n- In this example, `r` is mutable so that it can be reassigned (`r = &b`). Note\n  that this re-binds `r`, so that it refers to something else. This is different\n  from C++, where assignment to a reference changes the referenced value.\n\n- A shared reference does not allow modifying the value it refers to, even if\n  that value was mutable. Try `*r = 'X'`.\n\n- Rust is tracking the lifetimes of all references to ensure they live long\n  enough. Dangling references cannot occur in safe Rust.\n\n- We will talk more about borrowing and preventing dangling references when we\n  get to ownership.\n\n</details>\n\n<!-- File: src/references/slices.md (Tokens: ~496 | Category: anthropic-skill) -->\n---\nminutes: 7\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Slices\n\nA slice gives you a view into a larger collection:\n\n<!-- mdbook-xgettext: skip -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let a: [i32; 6] = [10, 20, 30, 40, 50, 60];\n    println!(\"a: {a:?}\");\n\n    let s: &[i32] = &a[2..4];\n    println!(\"s: {s:?}\");\n}\n```\n\n- Slices borrow data from the sliced type.\n\n<details>\n\n- We create a slice by borrowing `a` and specifying the starting and ending\n  indexes in brackets.\n\n- If the slice starts at index 0, Rust’s range syntax allows us to drop the\n  starting index, meaning that `&a[0..a.len()]` and `&a[..a.len()]` are\n  identical.\n\n- The same is true for the last index, so `&a[2..a.len()]` and `&a[2..]` are\n  identical.\n\n- To easily create a slice of the full array, we can therefore use `&a[..]`.\n\n- `s` is a reference to a slice of `i32`s. Notice that the type of `s`\n  (`&[i32]`) no longer mentions the array length. This allows us to perform\n  computation on slices of different sizes.\n\n- Slices always borrow from another object. In this example, `a` has to remain\n  'alive' (in scope) for at least as long as our slice.\n\n- You can't \"grow\" a slice once it's created:\n  - You can't append elements of the slice, since it doesn't own the backing\n    buffer.\n  - You can't grow a slice to point to a larger section of the backing buffer. A\n    slice does not have information about the length of the underlying buffer\n    and so you can't know how large the slice can be grown.\n  - To get a larger slice you have to go back to the original buffer and create\n    a larger slice from there.\n\n</details>\n\n<!-- File: src/references/solution.md (Tokens: ~171 | Category: anthropic-skill) -->\n<!--\nCopyright 2023 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n# Solution\n\n```rust,editable\n# // Copyright 2023 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\n{{#include exercise.rs:solution}}\n```\n\n<details>\n\n- Note that in `normalize` we were able to do `*item /= mag` to modify each\n  element. This is because we're iterating using a mutable reference to an\n  array, which causes the `for` loop to give mutable references to each element.\n\n- It is also possible to take slice references here, e.g.,\n  `fn\n  magnitude(vector: &[f64]) -> f64`. This makes the function more general,\n  at the cost of a runtime length check.\n\n</details>\n\n<!-- File: src/references/strings.md (Tokens: ~802 | Category: anthropic-skill) -->\n---\nminutes: 10\n---\n\n<!--\nCopyright 2024 Google LLC\nSPDX-License-Identifier: CC-BY-4.0\n-->\n\n<!-- NOTES:\nIncluding `&str` as a way of representing a slice of valid utf-8\n-->\n\n# Strings\n\nWe can now understand the two string types in Rust:\n\n- `&str` is a slice of UTF-8 encoded bytes, similar to `&[u8]`.\n- `String` is an owned buffer of UTF-8 encoded bytes, similar to `Vec<T>`.\n\n<!-- Avoid using fixed integers when slicing since this breaks\ntranslations. Using the length of s1 and s2 is safe. -->\n\n```rust,editable\n# // Copyright 2024 Google LLC\n# // SPDX-License-Identifier: Apache-2.0\n#\nfn main() {\n    let s1: &str = \"World\";\n    println!(\"s1: {s1}\");\n\n    let mut s2: String = String::from(\"Hello \");\n    println!(\"s2: {s2}\");\n\n    s2.push_str(s1);\n    println!(\"s2: {s2}\");\n\n    let s3: &str = &s2[2..9];\n    println!(\"s3: {s3}\");\n}\n```\n\n<details>\n\n- `&str` introduces a string slice, which is an immutable reference to UTF-8\n  encoded string data stored in a block of memory. String literals (`\"Hello\"`),\n  are stored in the program’s binary.\n\n- Rust's `String` type is a wrapper around a vector of bytes. As with a\n  `Vec<T>`, it is owned.\n\n- As with many other types `String::from()` creates a string from a string\n  literal; `String::new()` creates a new empty string, to which string data can\n  be added using the `push()` and `push_str()` methods.\n\n- The `format!()` macro is a convenient way to generate an owned string from\n  dynamic values. It accepts the same format specification as `println!()`.\n\n- You can borrow `&str` slices from `String` via `&` and optionally range\n  selection. If you select a byte range that is not aligned to character\n  boundaries, the expression will panic. The `chars` iterator iterates over\n  characters and is preferred over trying to get character boundaries right.\n\n- For C++ programmers: think of `&str` as `std::string_view` from C++, but the\n  one that always points to a valid string in memory. Rust `String` is a rough\n  equivalent of `std::string` from C++ (main difference: it can only contain\n  UTF-8 encoded bytes and will never use a small-string optimization).\n\n- Byte strings literals allow you to create a `&[u8]` value directly:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(\"{:?}\", b\"abc\");\n      println!(\"{:?}\", &[97, 98, 99]);\n  }\n  ```\n\n- Raw strings allow you to create a `&str` value with escapes disabled:\n  `r\"\\n\" == \"\\\\n\"`. You can embed double-quotes by using an equal amount of `#`\n  on either side of the quotes:\n\n  <!-- mdbook-xgettext: skip -->\n  ```rust,editable\n  # // Copyright 2024 Google LLC\n  # // SPDX-License-Identifier: Apache-2.0\n  #\n  fn main() {\n      println!(r#\"<a href=\"link.html\">link</a>\"#);\n      println!(\"<a href=\\\"link.html\\\">link</a>\");\n  }\n  ```\n\n</details>\n\n<!-- File: GEMINI.md (Tokens: ~2862 | Category: gemini-rule) -->\n# Project Overview\n\nThis repository contains the source code for Comprehensive Rust, a family of\ncourses on Rust developed by Google, starting with Rust foundations, and\nincluding deep dives into specialized topics like Android, Chromium, bare-metal\ndevelopment, and concurrency. The project is a Rust workspace that leverages\n`mdbook` to generate a course website.\n\n## Key Technologies\n\n- **Rust:** The primary programming language for the course subject, custom\n  tools, and examples.\n- **mdbook:** A command-line tool to create books from Markdown files, used for\n  generating the course website.\n- **Custom mdbook Preprocessors:** `mdbook-course` and `mdbook-exerciser` are\n  Rust binaries that extend `mdbook`'s functionality, for example, to extract\n  exercise starter code.\n- **`cargo xtask`:** A custom binary within the workspace used for project\n  automation, simplifying common development tasks.\n\n# Building and Running\n\nThe project uses `cargo xtask` for project-specific automation, like builds,\ntests, and managing translations.\n\n## Setup\n\n1. **Install Rust:** Follow the instructions on\n   [https://rustup.rs/](https://rustup.rs/).\n2. **Clone Repository:**\n   ```bash\n   git clone https://github.com/google/comprehensive-rust/\n   cd comprehensive-rust\n   ```\n3. **Install Project Tools:**\n   ```bash\n   cargo xtask install-tools\n   ```\n   This is a necessary first step for working with this repository. It will\n   install the correct versions of all tools used by the project.\n\n## Commands\n\nAll commands are run using `cargo xtask`. Run `cargo xtask --help` for a full\nlist of options.\n\n- **Serve the Course Locally:** Starts a web server to view the course content.\n  ```bash\n  cargo xtask serve [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n  (e.g., `cargo xtask serve -l da` for the Danish translation)\n\n- **Build the Course:** Creates a static version of the course in the `book/`\n  directory.\n  ```bash\n  cargo xtask build [--language <ISO_639_language_code>] [--output <output_directory>]\n  ```\n\n- **Run Rust Snippet Tests:** Tests all Rust code snippets included in the\n  course material.\n  ```bash\n  cargo xtask rust-tests\n  ```\n\n- **Run Web Driver Tests:** Executes web driver tests located in the `tests/`\n  directory.\n  ```bash\n  cargo xtask web-tests [--dir <book_html_directory>]\n  ```\n\n# Development Conventions\n\n- **Project Automation:** `cargo xtask` is the primary interface for common\n  development tasks.\n- **Course Content:** Markdown files in the `src/` directory, structured\n  according to `src/SUMMARY.md`.\n- **Code Formatting:** `dprint fmt` is used to format all source files according\n  to `rustfmt.toml` and `dprint.json`. Note that you must first install the\n  project tools with `cargo xtask install-tools`.\n- **Contributions:** Refer to `CONTRIBUTING.md` for guidelines on contributing\n  to the project.\n- **Style:** Refer to `STYLE.md` for style guidelines. When making changes to\n  Markdown files in `src/`, always first read `STYLE.md` and follow its\n  conventions.\n- **GitHub Actions:** The project uses composite GitHub Actions to simplify CI\n  workflows. These actions should be preferred over hand-written commands.\n  - **`apt-get-install`:** This action efficiently installs Debian packages. It\n    configures `dpkg` and `apt` to skip documentation and translations, and\n    ensures that `apt-get update` is run only once per job. This significantly\n    speeds up CI runs.\n  - **`install-mdbook`:** A composite action to install `mdbook` and its\n    dependencies, including `pandoc` and `texlive`.\n  - **`setup-rust-cache`:** A composite action that configures the\n    `Swatinem/rust-cache` action.\n\n## Developing Exercises\n\nExercises allow students to practice what they have learned. When adding or\nupdating exercises, follow these structural conventions:\n\n- **File Structure:**\n  - `exercise.md`: Contains the problem description and a code block with\n    placeholders.\n  - `exercise.rs`: Contains the full solution code, including a license header\n    and `ANCHOR` tags to delimit sections.\n  - `solution.md`: Includes the full solution code from `exercise.rs`.\n  - `Cargo.toml`: Must define a `[[bin]]` target pointing to `exercise.rs` so\n    that the solution code is compiled and tested.\n\n- **Content Inclusion:**\n  - Use `{{#include exercise.rs:anchor_name}}` in `exercise.md` to show specific\n    parts of the code (e.g., setup, main).\n  - Use `{{#include exercise.rs:solution}}` in `solution.md` to show the\n    solution code _without_ the license header. Ensure `exercise.rs` has a\n    `// ANCHOR: solution` line before the first line of the solution. It is\n    unnecessary to add a `// ANCHOR_END: solution` line at the bottom of the\n    file.\n\n- **Testing:**\n  - Run `cargo xtask rust-tests` to ensure the solution code compiles and runs\n    correctly.\n  - Run `cargo check -p <crate_name>` to verify the specific exercise crate.\n\n## Markdown Conventions\n\n- **Headings:**\n  - **H1 (`#`):** Used for the main title of each page. Each slide has exactly\n    one title.\n  - **H2 (`##`):** Used for major sections. Slides do not use H2 headings to\n    save vertical space; more slides are created instead.\n  - **H3 (`###`):** Used for sub-sections, but not on slides.\n\n- **Emphasis:**\n  - **Bold (`**...**`):** Used to highlight key terms, commands, and for notes\n    (e.g., `**Note:**`). The colon (`:`) is included inside the bold text for\n    notes.\n  - **Italic (`_..._`):** Used for general emphasis, titles of external\n    articles, and for terms being defined.\n\n- **Code:**\n  - **Inline Code (`` `...` ``):** Used for code snippets, file names, commands,\n    type names, and language keywords. Rust fragments are formatted as `rustfmt`\n    would.\n  - **Code Blocks (`` ```...``` ``):** Fenced code blocks are used for\n    multi-line code examples, annotated with a language identifier (e.g.,\n    `rust`, `c`, `ignore`).\n  - **Interactive Code Blocks:** Rust examples are made interactive with\n    `editable`. Examples that fail to compile are marked with `compile_fail` or\n    `should_panic`.\n  - **Diagrams:** The `bob` language identifier is used in code blocks to\n    generate ASCII art diagrams.\n  - **Formatting Control:** The `#[rustfmt::skip]` attribute is used to prevent\n    `rustfmt` from formatting specific code blocks, though it is used rarely.\n\n- **Lists:**\n  - **Bulleted Lists:** Unordered lists are the primary way to lay out key\n    points on slides.\n  - **Glossary Format:** The glossary uses a specific format with a colon and\n    backslash (`:\\`) after each term to create a hard line break for visual\n    formatting.\n\n- **Other Markdown Elements:**\n  - **Block Quotes (`> ...`):** Used sparingly for important notes, warnings, or\n    supplementary information to draw attention.\n  - **Links:** Both standard (`[text](url)`) and reference-style\n    (`[text][label]`) links are used.\n  - **Tables:** Markdown tables are used to present structured data.\n  - **Horizontal Rules (`---`):** Not used on slides.\n\n- **HTML Tags:**\n  - **`<details>`:** Used for collapsible \"speaker notes\".\n  - **`<kbd>`:** Used to denote keyboard keys. Each key in a combination must be\n    wrapped in its own tag, e.g., `<kbd>Ctrl</kbd> + <kbd>S</kbd>`.\n  - **`<style>`:** Used rarely for targeted custom CSS.\n  - **`<img>`:** Used to embed images.\n\n- **Project-Specific Conventions:**\n  - **mdbook Includes:** The `{{#include ...}}` helper is used to include\n    snippets from other files.\n  - **mdbook Segments:** The `{{%segment ...%}}` and `{{%session ...%}}` helpers\n    are used for course structuring.\n  - **Frontmatter:** Files start with YAML frontmatter (enclosed in `---`) to\n    provide metadata.\n  - **Doc Comments:** Standard Rust doc comments (`///`, `//!`) are used.\n    `/// # Safety` is used to document safety preconditions for `unsafe` code.\n  - **Comments:** HTML comments (`<!-- ... -->`) are used for editor/translator\n    instructions and content control (e.g., `mdbook-xgettext: skip`).\n\n# Project-Specific Technical Context\n\nThis section contains critical, non-obvious technical details about this\nproject's tooling and environment that an AI assistant needs to know to perform\nits tasks correctly.\n\n## `mdbook` Behavior\n\n- **Isolated Code Snippets:** `mdbook` treats each fenced Rust code block (e.g.,\n  `` ```rust ... ``` ``) as a separate compilation unit. When analyzing a code\n  snippet, treat it as a self-contained program. Do not assume it shares a scope\n  or context with other snippets in the same file unless the surrounding text\n  explicitly states otherwise.\n\n## Interacting with the `mdbook` Theme\n\nThe `mdbook` theme has several interactive elements. Here's how to interact with\nthem:\n\n- **Sidebar Toggle:** The sidebar can be opened and closed by clicking the\n  \"hamburger\" button in the top-left of the body text. This button has the ID\n  `sidebar-toggle`. You can use the following JavaScript to toggle the sidebar:\n\n  ```javascript\n  const button = document.getElementById(\"sidebar-toggle\");\n  button.click();\n  ```\n\n## WebdriverIO Testing\n\nThis project uses WebdriverIO for browser-based integration tests. Here are some\nkey findings about the test environment:\n\n### Test Environments\n\nThe `tests/` directory contains two primary configurations:\n\n- `npm test` (runs `wdio.conf.ts`): This is the standard for self-contained\n  integration tests. It uses `@wdio/static-server-service` to create a temporary\n  web server on port 8080.\n- `npm run test-mdbook` (runs `wdio.conf-mdbook.ts`): This is for testing\n  against a live `mdbook serve` instance, which typically runs on port 3000.\n\nIt is important to use the standard `npm test` command for most test development\nto ensure the tests are self-contained.\n\n### Writing Stable Tests\n\nTests can be flaky if they don't correctly handle the asynchronous nature of the\nweb browser and the test environment's state management.\n\n- **State Leakage Between Tests:** Despite what the WebdriverIO documentation\n  might suggest, `browser.url()` is not always sufficient to guarantee a clean\n  slate between tests. Lingering state, such as inline CSS styles applied by\n  JavaScript, can leak from one test into the next, causing unexpected failures.\n  The most effective solution found for this project is to add\n  `await browser.refresh();` to the `beforeEach` hook. This forces a full page\n  reload that properly clears the old state.\n\n- **Race Conditions with Dynamic Elements:** Many elements in this project are\n  created dynamically by JavaScript after the initial page load. If a test tries\n  to access an element immediately after navigation, it may fail because the\n  script hasn't finished running and the element doesn't exist in the DOM yet.\n  This creates a race condition. To prevent this, always use\n  `await element.waitForExist()` to ensure the element is present before trying\n  to interact with it or assert its state (e.g., `toBeDisplayed()`).\n\n### Handling Redirects\n\n`mdbook` uses a redirect map defined in `book.toml` under the\n`[output.html.redirect]` section. When writing tests, it is crucial to use the\nfinal, non-redirecting URL for navigation. Navigating to a URL that is a\nredirect will cause the browser to follow it, but this process can strip URL\nquery parameters, leading to test failures for features that depend on them.\n\n### Running and Debugging Tests\n\nTo run a single test file, use the `--spec` flag with the a string matching the\nfile name:\n\n```bash\nnpm test -- --spec redbox\n```\n\nTo check for flakiness, you can repeat a test multiple times using the\n`--repeat` flag:\n\n```bash\nnpm test -- --spec redbox --repeat 100\n```\n\nUse `--mochaOpts.grep` to run a single test within a file:\n\n```bash\nnpm test -- --spec redbox --mochaOpts.grep \"should be hidden by default\"\n```\n</yakaai_skills>"}