You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-10-09 19:12:06 +02:00
Merge branch 'main' into raii
This commit is contained in:
@@ -1,12 +1,5 @@
|
|||||||
[alias]
|
[alias]
|
||||||
# WARNING: Using the `xtask` alias is deprecated and will be unsupported in a
|
|
||||||
# future version of Cargo. See https://github.com/rust-lang/cargo/issues/10049.
|
|
||||||
xtask = "run --package xtask --"
|
xtask = "run --package xtask --"
|
||||||
install-tools = "run --package xtask -- install-tools"
|
|
||||||
web-tests = "run --package xtask -- web-tests"
|
|
||||||
rust-tests = "run --package xtask -- rust-tests"
|
|
||||||
serve = "run --package xtask -- serve"
|
|
||||||
build-book = "run --package xtask -- build"
|
|
||||||
|
|
||||||
[env]
|
[env]
|
||||||
# To provide an anchor to the root of the workspace when working with paths.
|
# To provide an anchor to the root of the workspace when working with paths.
|
||||||
|
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -14,7 +14,7 @@ po/pl.po @jkotur @dyeroshenko
|
|||||||
po/pt-BR.po @rastringer @hugojacob @henrif75 @joaovicmendes @azevedoalice
|
po/pt-BR.po @rastringer @hugojacob @henrif75 @joaovicmendes @azevedoalice
|
||||||
po/ro.po @AlexandraImbrisca @razvanm
|
po/ro.po @AlexandraImbrisca @razvanm
|
||||||
po/ru.po @istolga @baltuky @zvonden @dyeroshenko
|
po/ru.po @istolga @baltuky @zvonden @dyeroshenko
|
||||||
po/tr.po @alerque @Enes1313
|
po/tr.po @alerque @Enes1313 @rexoplans1
|
||||||
po/uk.po @dyeroshenko
|
po/uk.po @dyeroshenko
|
||||||
po/vi.po @daivinhtran @qu-ngx
|
po/vi.po @daivinhtran @qu-ngx
|
||||||
po/zh-CN.po @wnghl @anlunx @kongy @noahdragon @superwhd @emmali01 @candysonya @AgainstEntropy
|
po/zh-CN.po @wnghl @anlunx @kongy @noahdragon @superwhd @emmali01 @candysonya @AgainstEntropy
|
||||||
|
44
.github/workflows/apt-get-install/action.yml
vendored
Normal file
44
.github/workflows/apt-get-install/action.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
name: Setup Apt and Install Packages
|
||||||
|
description: Configures apt, runs update once per job, and installs packages.
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
description: A space-separated list of packages to install.
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- name: Configure dpkg and apt for CI
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# Avoid time-consuming man-db updates.
|
||||||
|
sudo tee /etc/dpkg/dpkg.cfg.d/99-no-doc > /dev/null <<EOF
|
||||||
|
path-exclude /usr/share/doc/*
|
||||||
|
path-exclude /usr/share/man/*
|
||||||
|
path-exclude /usr/share/info/*
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Exclude translations.
|
||||||
|
sudo tee /etc/apt/apt.conf.d/99-no-translations > /dev/null <<EOF
|
||||||
|
Acquire::Languages "none";
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Exclude command-not-found utility.
|
||||||
|
sudo rm -f /etc/apt/apt.conf.d/50command-not-found
|
||||||
|
|
||||||
|
# Remove unnecessary repository lists (we don't install Azure
|
||||||
|
# utilities)
|
||||||
|
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.* /etc/apt/sources.list.d/azure-cli.*
|
||||||
|
|
||||||
|
- name: Run apt-get update
|
||||||
|
if: env.APT_UPDATED != 'true'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
echo "APT_UPDATED=true" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Installing ${{ inputs.packages }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo apt-get install --quiet --yes ${{ inputs.packages }}
|
54
.github/workflows/build.yml
vendored
54
.github/workflows/build.yml
vendored
@@ -11,36 +11,6 @@ env:
|
|||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
format:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install formatting dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install gettext yapf3
|
|
||||||
|
|
||||||
- name: Install nightly rustfmt
|
|
||||||
run: |
|
|
||||||
rustup default nightly
|
|
||||||
rustup component add rustfmt
|
|
||||||
|
|
||||||
- name: Check formatting
|
|
||||||
uses: dprint/check@v2.3
|
|
||||||
|
|
||||||
typos:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Check for typos
|
|
||||||
uses: crate-ci/typos@v1.34.0
|
|
||||||
with:
|
|
||||||
config: ./.github/typos.toml
|
|
||||||
|
|
||||||
cargo:
|
cargo:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -50,7 +20,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Update Rust
|
- name: Update Rust
|
||||||
run: rustup update
|
run: rustup update
|
||||||
@@ -81,7 +51,7 @@ jobs:
|
|||||||
target: aarch64-unknown-none
|
target: aarch64-unknown-none
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Install toolchain
|
- name: Install toolchain
|
||||||
run: |
|
run: |
|
||||||
@@ -92,9 +62,9 @@ jobs:
|
|||||||
uses: ./.github/workflows/setup-rust-cache
|
uses: ./.github/workflows/setup-rust-cache
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
uses: ./.github/workflows/apt-get-install
|
||||||
sudo apt update
|
with:
|
||||||
sudo apt install gcc-aarch64-linux-gnu
|
packages: gcc-aarch64-linux-gnu
|
||||||
|
|
||||||
- name: Build Rust code
|
- name: Build Rust code
|
||||||
working-directory: ${{ matrix.directory }}
|
working-directory: ${{ matrix.directory }}
|
||||||
@@ -106,7 +76,7 @@ jobs:
|
|||||||
languages: ${{ steps.find-languages.outputs.languages }}
|
languages: ${{ steps.find-languages.outputs.languages }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Find languages
|
- name: Find languages
|
||||||
id: find-languages
|
id: find-languages
|
||||||
@@ -131,7 +101,7 @@ jobs:
|
|||||||
LINK_CHECKED_LANGUAGES: '["en", "fa"]'
|
LINK_CHECKED_LANGUAGES: '["en", "fa"]'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # We need the full history for build.sh below.
|
fetch-depth: 0 # We need the full history for build.sh below.
|
||||||
|
|
||||||
@@ -143,10 +113,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
key: ${{ contains(fromJSON(env.LINK_CHECKED_LANGUAGES), matrix.language) }}
|
key: ${{ contains(fromJSON(env.LINK_CHECKED_LANGUAGES), matrix.language) }}
|
||||||
|
|
||||||
- name: Install Gettext
|
- name: Install dependencies
|
||||||
run: |
|
uses: ./.github/workflows/apt-get-install
|
||||||
sudo apt update
|
with:
|
||||||
sudo apt install gettext
|
packages: gettext
|
||||||
|
|
||||||
- name: Install mdbook
|
- name: Install mdbook
|
||||||
uses: ./.github/workflows/install-mdbook
|
uses: ./.github/workflows/install-mdbook
|
||||||
@@ -202,7 +172,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
2
.github/workflows/check-msgid-changes.yml
vendored
2
.github/workflows/check-msgid-changes.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
14
.github/workflows/install-mdbook/action.yml
vendored
14
.github/workflows/install-mdbook/action.yml
vendored
@@ -5,14 +5,20 @@ description: Install mdbook with the dependencies we need.
|
|||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
|
- name: Ensure cargo-binstall is installed
|
||||||
|
uses: cargo-bins/cargo-binstall@main
|
||||||
|
|
||||||
- name: Install mdbook
|
- name: Install mdbook
|
||||||
run: cargo xtask install-tools
|
run: cargo xtask install-tools --binstall
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Install dependencies for mdbook-pandoc
|
- name: Install mdbook-pandoc dependencies
|
||||||
|
uses: ./.github/workflows/apt-get-install
|
||||||
|
with:
|
||||||
|
packages: texlive texlive-luatex texlive-lang-cjk texlive-lang-arabic librsvg2-bin fonts-noto
|
||||||
|
|
||||||
|
- name: Install mdbook-pandoc
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y texlive texlive-luatex texlive-lang-cjk texlive-lang-arabic librsvg2-bin fonts-noto
|
|
||||||
curl -LsSf https://github.com/jgm/pandoc/releases/download/3.7.0.1/pandoc-3.7.0.1-linux-amd64.tar.gz | tar zxf -
|
curl -LsSf https://github.com/jgm/pandoc/releases/download/3.7.0.1/pandoc-3.7.0.1-linux-amd64.tar.gz | tar zxf -
|
||||||
echo "$PWD/pandoc-3.7.0.1/bin" >> $GITHUB_PATH
|
echo "$PWD/pandoc-3.7.0.1/bin" >> $GITHUB_PATH
|
||||||
shell: bash
|
shell: bash
|
||||||
|
55
.github/workflows/lint.yml
vendored
Normal file
55
.github/workflows/lint.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
name: Lint
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
clippy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Setup Rust cache
|
||||||
|
uses: ./.github/workflows/setup-rust-cache
|
||||||
|
|
||||||
|
- name: Clippy
|
||||||
|
run: cargo clippy -- -Dwarnings
|
||||||
|
|
||||||
|
format:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
NIGHTLY_VERSION: nightly-2025-09-01
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Install formatting dependencies
|
||||||
|
uses: ./.github/workflows/apt-get-install
|
||||||
|
with:
|
||||||
|
packages: gettext yapf3
|
||||||
|
|
||||||
|
- name: Install pinned nightly for rustfmt
|
||||||
|
run: |
|
||||||
|
rustup toolchain install --profile minimal "$NIGHTLY_VERSION"
|
||||||
|
rustup component add rustfmt --toolchain "$NIGHTLY_VERSION"
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
uses: dprint/check@v2.3
|
||||||
|
|
||||||
|
typos:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Check for typos
|
||||||
|
uses: crate-ci/typos@v1.35.7
|
||||||
|
with:
|
||||||
|
config: ./.github/typos.toml
|
10
.github/workflows/publish.yml
vendored
10
.github/workflows/publish.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # We need the full history for build.sh below.
|
fetch-depth: 0 # We need the full history for build.sh below.
|
||||||
|
|
||||||
@@ -42,9 +42,9 @@ jobs:
|
|||||||
uses: ./.github/workflows/setup-rust-cache
|
uses: ./.github/workflows/setup-rust-cache
|
||||||
|
|
||||||
- name: Install Gettext
|
- name: Install Gettext
|
||||||
run: |
|
uses: ./.github/workflows/apt-get-install
|
||||||
sudo apt update
|
with:
|
||||||
sudo apt install gettext
|
packages: gettext
|
||||||
|
|
||||||
- name: Install mdbook
|
- name: Install mdbook
|
||||||
uses: ./.github/workflows/install-mdbook
|
uses: ./.github/workflows/install-mdbook
|
||||||
@@ -73,7 +73,7 @@ jobs:
|
|||||||
uses: actions/configure-pages@v5
|
uses: actions/configure-pages@v5
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v3
|
uses: actions/upload-pages-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: book/html
|
path: book/html
|
||||||
|
|
||||||
|
@@ -3,8 +3,10 @@
|
|||||||
We'd love to accept your patches and contributions to this project. There are
|
We'd love to accept your patches and contributions to this project. There are
|
||||||
just a few small guidelines you need to follow.
|
just a few small guidelines you need to follow.
|
||||||
|
|
||||||
Make sure you can build the book, and that `mdbook serve` works. Please follow
|
Make sure you can build the book with `mdbook build`, that `mdbook serve` works,
|
||||||
the [instructions in the README].
|
and that `dprint fmt` formats the code. Please use `cargo xtask install-tools`
|
||||||
|
to install the necessary dependencies, following the
|
||||||
|
[instructions in the README].
|
||||||
|
|
||||||
[instructions in the README]: README.md#building
|
[instructions in the README]: README.md#building
|
||||||
|
|
||||||
@@ -53,6 +55,16 @@ this:
|
|||||||
|
|
||||||
Run `dprint fmt` to automatically format all files.
|
Run `dprint fmt` to automatically format all files.
|
||||||
|
|
||||||
|
**Note:** To make sure you have the correct version of `rustfmt` installed,
|
||||||
|
please run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo xtask install-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
This will install the pinned nightly toolchain and add the `rustfmt` component,
|
||||||
|
so your local formatting will match the CI.
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
Install `dprint` using their
|
Install `dprint` using their
|
||||||
|
1890
Cargo.lock
generated
1890
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
173
GEMINI.md
Normal file
173
GEMINI.md
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
# Project Overview
|
||||||
|
|
||||||
|
This repository contains the source code for Comprehensive Rust, a family of
|
||||||
|
courses on Rust developed by Google, starting with Rust foundations, and
|
||||||
|
including deep dives into specialized topics like Android, Chromium, bare-metal
|
||||||
|
development, and concurrency. The project is a Rust workspace that leverages
|
||||||
|
`mdbook` to generate a course website.
|
||||||
|
|
||||||
|
## Key Technologies
|
||||||
|
|
||||||
|
- **Rust:** The primary programming language for the course subject, custom
|
||||||
|
tools, and examples.
|
||||||
|
- **mdbook:** A command-line tool to create books from Markdown files, used for
|
||||||
|
generating the course website.
|
||||||
|
- **Custom mdbook Preprocessors:** `mdbook-course` and `mdbook-exerciser` are
|
||||||
|
Rust binaries that extend `mdbook`'s functionality, for example, to extract
|
||||||
|
exercise starter code.
|
||||||
|
- **`cargo xtask`:** A custom binary within the workspace used for project
|
||||||
|
automation, simplifying common development tasks.
|
||||||
|
|
||||||
|
# Building and Running
|
||||||
|
|
||||||
|
The project uses `cargo xtask` for project-specific automation, like builds,
|
||||||
|
tests, and managing translations.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. **Install Rust:** Follow the instructions on
|
||||||
|
[https://rustup.rs/](https://rustup.rs/).
|
||||||
|
2. **Clone Repository:**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/google/comprehensive-rust/
|
||||||
|
cd comprehensive-rust
|
||||||
|
```
|
||||||
|
3. **Install Project Tools:**
|
||||||
|
```bash
|
||||||
|
cargo xtask install-tools
|
||||||
|
```
|
||||||
|
This is a necessary first step for working with this repository. It will
|
||||||
|
install the correct versions of all tools used by the project.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
All commands are run using `cargo xtask`. Run `cargo xtask --help` for a full
|
||||||
|
list of options.
|
||||||
|
|
||||||
|
- **Serve the Course Locally:** Starts a web server to view the course content.
|
||||||
|
```bash
|
||||||
|
cargo xtask serve [--language <ISO_639_language_code>] [--output <output_directory>]
|
||||||
|
```
|
||||||
|
(e.g., `cargo xtask serve -l da` for the Danish translation)
|
||||||
|
|
||||||
|
- **Build the Course:** Creates a static version of the course in the `book/`
|
||||||
|
directory.
|
||||||
|
```bash
|
||||||
|
cargo xtask build [--language <ISO_639_language_code>] [--output <output_directory>]
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Run Rust Snippet Tests:** Tests all Rust code snippets included in the
|
||||||
|
course material.
|
||||||
|
```bash
|
||||||
|
cargo xtask rust-tests
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Run Web Driver Tests:** Executes web driver tests located in the `tests/`
|
||||||
|
directory.
|
||||||
|
```bash
|
||||||
|
cargo xtask web-tests [--dir <book_html_directory>]
|
||||||
|
```
|
||||||
|
|
||||||
|
# Development Conventions
|
||||||
|
|
||||||
|
- **Project Automation:** `cargo xtask` is the primary interface for common
|
||||||
|
development tasks.
|
||||||
|
- **Course Content:** Markdown files in the `src/` directory, structured
|
||||||
|
according to `src/SUMMARY.md`.
|
||||||
|
- **Code Formatting:** `dprint fmt` is used to format all source files according
|
||||||
|
to `rustfmt.toml` and `dprint.json`. Note that you must first install the
|
||||||
|
project tools with `cargo xtask install-tools`.
|
||||||
|
- **Contributions:** Refer to `CONTRIBUTING.md` for guidelines on contributing
|
||||||
|
to the project.
|
||||||
|
- **Style:** Refer to `STYLE.md` for style guidelines. When making changes to
|
||||||
|
Markdown files in `src/`, always first read `STYLE.md` and follow its
|
||||||
|
conventions.
|
||||||
|
- **GitHub Actions:** The project uses composite GitHub Actions to simplify CI
|
||||||
|
workflows. These actions should be preferred over hand-written commands.
|
||||||
|
- **`apt-get-install`:** This action efficiently installs Debian packages. It
|
||||||
|
configures `dpkg` and `apt` to skip documentation and translations, and
|
||||||
|
ensures that `apt-get update` is run only once per job. This significantly
|
||||||
|
speeds up CI runs.
|
||||||
|
- **`install-mdbook`:** A composite action to install `mdbook` and its
|
||||||
|
dependencies, including `pandoc` and `texlive`.
|
||||||
|
- **`setup-rust-cache`:** A composite action that configures the
|
||||||
|
`Swatinem/rust-cache` action.
|
||||||
|
|
||||||
|
## Markdown Conventions
|
||||||
|
|
||||||
|
- **Headings:**
|
||||||
|
- **H1 (`#`):** Used for the main title of each page. Each slide has exactly
|
||||||
|
one title.
|
||||||
|
- **H2 (`##`):** Used for major sections. Slides do not use H2 headings to
|
||||||
|
save vertical space; more slides are created instead.
|
||||||
|
- **H3 (`###`):** Used for sub-sections, but not on slides.
|
||||||
|
|
||||||
|
- **Emphasis:**
|
||||||
|
- **Bold (`**...**`):** Used to highlight key terms, commands, and for notes
|
||||||
|
(e.g., `**Note:**`). The colon (`:`) is included inside the bold text for
|
||||||
|
notes.
|
||||||
|
- **Italic (`_..._`):** Used for general emphasis, titles of external
|
||||||
|
articles, and for terms being defined.
|
||||||
|
|
||||||
|
- **Code:**
|
||||||
|
- **Inline Code (`` `...` ``):** Used for code snippets, file names, commands,
|
||||||
|
type names, and language keywords. Rust fragments are formatted as `rustfmt`
|
||||||
|
would.
|
||||||
|
- **Code Blocks (`` ```...``` ``):** Fenced code blocks are used for
|
||||||
|
multi-line code examples, annotated with a language identifier (e.g.,
|
||||||
|
`rust`, `c`, `ignore`).
|
||||||
|
- **Interactive Code Blocks:** Rust examples are made interactive with
|
||||||
|
`editable`. Examples that fail to compile are marked with `compile_fail` or
|
||||||
|
`should_panic`.
|
||||||
|
- **Diagrams:** The `bob` language identifier is used in code blocks to
|
||||||
|
generate ASCII art diagrams.
|
||||||
|
- **Formatting Control:** The `#[rustfmt::skip]` attribute is used to prevent
|
||||||
|
`rustfmt` from formatting specific code blocks, though it is used rarely.
|
||||||
|
|
||||||
|
- **Lists:**
|
||||||
|
- **Bulleted Lists:** Unordered lists are the primary way to lay out key
|
||||||
|
points on slides.
|
||||||
|
- **Glossary Format:** The glossary uses a specific format with a colon and
|
||||||
|
backslash (`:\`) after each term to create a hard line break for visual
|
||||||
|
formatting.
|
||||||
|
|
||||||
|
- **Other Markdown Elements:**
|
||||||
|
- **Block Quotes (`> ...`):** Used sparingly for important notes, warnings, or
|
||||||
|
supplementary information to draw attention.
|
||||||
|
- **Links:** Both standard (`[text](url)`) and reference-style
|
||||||
|
(`[text][label]`) links are used.
|
||||||
|
- **Tables:** Markdown tables are used to present structured data.
|
||||||
|
- **Horizontal Rules (`---`):** Not used on slides.
|
||||||
|
|
||||||
|
- **HTML Tags:**
|
||||||
|
- **`<details>`:** Used for collapsible "speaker notes".
|
||||||
|
- **`<kbd>`:** Used to denote keyboard keys. Each key in a combination must be
|
||||||
|
wrapped in its own tag, e.g., `<kbd>Ctrl</kbd> + <kbd>S</kbd>`.
|
||||||
|
- **`<style>`:** Used rarely for targeted custom CSS.
|
||||||
|
- **`<img>`:** Used to embed images.
|
||||||
|
|
||||||
|
- **Project-Specific Conventions:**
|
||||||
|
- **mdbook Includes:** The `{{#include ...}}` helper is used to include
|
||||||
|
snippets from other files.
|
||||||
|
- **mdbook Segments:** The `{{%segment ...%}}` and `{{%session ...%}}` helpers
|
||||||
|
are used for course structuring.
|
||||||
|
- **Frontmatter:** Files start with YAML frontmatter (enclosed in `---`) to
|
||||||
|
provide metadata.
|
||||||
|
- **Doc Comments:** Standard Rust doc comments (`///`, `//!`) are used.
|
||||||
|
`/// # Safety` is used to document safety preconditions for `unsafe` code.
|
||||||
|
- **Comments:** HTML comments (`<!-- ... -->`) are used for editor/translator
|
||||||
|
instructions and content control (e.g., `mdbook-xgettext: skip`).
|
||||||
|
|
||||||
|
# Project-Specific Technical Context
|
||||||
|
|
||||||
|
This section contains critical, non-obvious technical details about this
|
||||||
|
project's tooling and environment that an AI assistant needs to know to perform
|
||||||
|
its tasks correctly.
|
||||||
|
|
||||||
|
## `mdbook` Behavior
|
||||||
|
|
||||||
|
- **Isolated Code Snippets:** `mdbook` treats each fenced Rust code block (e.g.,
|
||||||
|
`` ```rust ... ``` ``) as a separate compilation unit. When analyzing a code
|
||||||
|
snippet, treat it as a self-contained program. Do not assume it shares a scope
|
||||||
|
or context with other snippets in the same file unless the surrounding text
|
||||||
|
explicitly states otherwise.
|
59
README.md
59
README.md
@@ -18,14 +18,14 @@ Read the course at **https://google.github.io/comprehensive-rust/**.
|
|||||||
|
|
||||||
## Course Format and Target Audience
|
## Course Format and Target Audience
|
||||||
|
|
||||||
The course is used internally at Google when teaching Rust to experienced
|
The course is used internally at Google to teach Rust to experienced software
|
||||||
software engineers. They typically have a background in C++ or Java.
|
engineers, typically with a background in C++ or Java.
|
||||||
|
|
||||||
The course is taught in a classroom setting and we hope it will be useful for
|
The course is taught in a classroom setting, and we hope it will be useful for
|
||||||
others who want to teach Rust to their team. The course will be less useful for
|
others who want to teach Rust to their team. The course is less ideal for
|
||||||
self-study since you miss out on the discussions happening in the classroom. You
|
self-study, since you would miss out on classroom discussions. You would not see
|
||||||
don't see the questions and answers and you don't see the compiler errors we
|
the questions and answers, nor the compiler errors we trigger when going through
|
||||||
trigger when going through the code samples. We hope to improve on this via
|
the code samples. We hope to improve the self-study experience via
|
||||||
[speaker notes](https://github.com/google/comprehensive-rust/issues/53) and by
|
[speaker notes](https://github.com/google/comprehensive-rust/issues/53) and by
|
||||||
[publishing videos](https://github.com/google/comprehensive-rust/issues/52).
|
[publishing videos](https://github.com/google/comprehensive-rust/issues/52).
|
||||||
|
|
||||||
@@ -40,11 +40,11 @@ Articles and blog posts from around the web which cover Comprehensive Rust:
|
|||||||
_[Scaling Rust Adoption Through Training](https://security.googleblog.com/2023/09/scaling-rust-adoption-through-training.html)_.
|
_[Scaling Rust Adoption Through Training](https://security.googleblog.com/2023/09/scaling-rust-adoption-through-training.html)_.
|
||||||
We published a blog post with details on the development of the course.
|
We published a blog post with details on the development of the course.
|
||||||
- 2023-10-02:
|
- 2023-10-02:
|
||||||
_[In Search of Rust Developers, Companies Turn to In-House Training](https://www.darkreading.com/application-security/google-microsoft-take-refuge-in-rust-languages-better-security)_.
|
_[In Search of Rust Developers, Companies Turn to In-House Training](https://www.darkreading.com/application-security/seeking-rust-developers-in-house-training)_.
|
||||||
About how Microsoft, Google, and others are training people in Rust.
|
About how Microsoft, Google, and others are training people in Rust.
|
||||||
- 2024-10-18:
|
- 2024-10-18:
|
||||||
_[Rust Training at Scale | Rust Global @ RustConf 2024](https://youtu.be/7h5KyMqt2-Q?si=4M99HdWWxMaqN8Zr)_.
|
_[Rust Training at Scale | Rust Global @ RustConf 2024](https://youtu.be/7h5KyMqt2-Q?si=4M99HdWWxMaqN8Zr)_.
|
||||||
What Google learnt from teaching Comprehensive Rust for more than two years.
|
What Google learned from teaching Comprehensive Rust for more than two years.
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ The course is built using a few tools:
|
|||||||
- [mdbook-course](mdbook-course/)
|
- [mdbook-course](mdbook-course/)
|
||||||
- [mdbook-linkcheck2](https://github.com/marxin/mdbook-linkcheck2)
|
- [mdbook-linkcheck2](https://github.com/marxin/mdbook-linkcheck2)
|
||||||
|
|
||||||
First install Rust by following the instructions on https://rustup.rs/. Then
|
First, install Rust by following the instructions on https://rustup.rs/. Then
|
||||||
clone this repository:
|
clone this repository:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
@@ -65,45 +65,36 @@ git clone https://github.com/google/comprehensive-rust/
|
|||||||
cd comprehensive-rust
|
cd comprehensive-rust
|
||||||
```
|
```
|
||||||
|
|
||||||
Then install these tools with:
|
Then run the following command to install the correct versions of all tools
|
||||||
|
mentioned above:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
cargo xtask install-tools
|
cargo xtask install-tools
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This uses `cargo install` to install the tools, so you will find them in your
|
||||||
|
`~/.cargo/bin/` directory afterwards.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
Here is a summary of the various commands you can run in the project.
|
Here are some of the commonly used commands you can run in the project. Run
|
||||||
|
`cargo xtask` to view all available commands.
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `cargo install-tools` | Install all the tools the project depends on. |
|
| `cargo xtask install-tools` | Install all the tools the project depends on. |
|
||||||
| `cargo serve` | Start a web server with the course. You'll find the content on http://localhost:3000. |
|
| `cargo xtask serve` | Start a web server with the course. You'll find the content on http://localhost:3000. To serve any of the translated versions of the course, add the language flag (--language or -l) followed by xx, where xx is the ISO 639 language code (e.g. cargo xtask serve -l da for the Danish translation). |
|
||||||
| `cargo rust-tests` | Test the included Rust snippets. |
|
| `cargo xtask rust-tests` | Test the included Rust snippets. |
|
||||||
| `cargo web-tests` | Run the web driver tests in the tests directory. |
|
| `cargo xtask web-tests` | Run the web driver tests in the tests directory. |
|
||||||
| `cargo build-book` | Create a static version of the course in the `book/` directory. Note that you have to separately build and zip exercises and add them to book/html. To build any of the translated versions of the course, run MDBOOK_BOOK__LANGUAGE=xx mdbook build -d book/xx where xx is the ISO 639 language code (e.g. da for the Danish translation). [TRANSLATIONS.md](TRANSLATIONS.md) contains further instructions. |
|
| `cargo xtask build` | Create a static version of the course in the `book/` directory. Note that you have to separately build and zip exercises and add them to book/html. To build any of the translated versions of the course, add the language flag (--language or -l) followed by xx, where xx is the ISO 639 language code (e.g. cargo xtask build -l da for the Danish translation). [TRANSLATIONS.md](TRANSLATIONS.md) contains further instructions. |
|
||||||
|
|
||||||
> **Note** On Windows, you need to enable symlinks
|
> **Note** On Windows, you need to enable symlinks
|
||||||
> (`git config --global core.symlinks true`) and Developer Mode.
|
> (`git config --global core.symlinks true`) and Developer Mode.
|
||||||
|
|
||||||
> **Note** Previous versions this README recommended that you use
|
|
||||||
> `cargo xtool <tool>`, i.e. `cargo xtool install-tools`. This causes issues
|
|
||||||
> with pre-existing installations of `cargo-xtool` and is now deprecated.
|
|
||||||
>
|
|
||||||
> The new syntax is almost a 1:1 mapping, although `cargo xtool build` has
|
|
||||||
> become `cargo build-book` to avoid conflicting with the built-in Cargo
|
|
||||||
> subcommand.
|
|
||||||
>
|
|
||||||
> - `cargo xtool build` -> `cargo build-book`
|
|
||||||
> - `cargo xtool install-tools` -> `cargo install-tools`
|
|
||||||
> - `cargo xtool serve` -> `cargo serve`
|
|
||||||
> - `cargo xtool run-tests` -> `cargo run-tests`
|
|
||||||
> - `cargo xtool web-tests` -> `cargo web-tests`
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We would like to receive your contributions. Please see
|
We welcome contributions. Please see [CONTRIBUTING.md](CONTRIBUTING.md) for
|
||||||
[CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
details.
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
||||||
|
284
STYLE.md
284
STYLE.md
@@ -4,6 +4,91 @@ The course has been expanded and improved by tons of volunteers like you! Thank
|
|||||||
you for that! To help ensure a consistent style throughout the course, we have
|
you for that! To help ensure a consistent style throughout the course, we have
|
||||||
written down some guidelines for you to follow.
|
written down some guidelines for you to follow.
|
||||||
|
|
||||||
|
## Course Philosophy and Design
|
||||||
|
|
||||||
|
To contribute effectively, it's helpful to understand the core design principles
|
||||||
|
of Comprehensive Rust. This is not a self-study book; it is a set of slides and
|
||||||
|
notes for an **instructor-led course**.
|
||||||
|
|
||||||
|
### Target Audience
|
||||||
|
|
||||||
|
The course is designed for an audience of experienced software engineers who are
|
||||||
|
new to Rust. We assume they have 2-3 years of experience in an imperative
|
||||||
|
language like C, C++11+, Java 7+, Python, or Go.
|
||||||
|
|
||||||
|
We **do not** assume familiarity with functional programming concepts or
|
||||||
|
features from more modern languages like Swift or Kotlin. Course material should
|
||||||
|
build upon the concepts that are likely to be familiar to this audience.
|
||||||
|
|
||||||
|
### Goals
|
||||||
|
|
||||||
|
The goal of the course is to provide a solid foundation in Rust within a bounded
|
||||||
|
time frame. This prepares students to continue learning effectively as they
|
||||||
|
begin to apply their new skills on the job.
|
||||||
|
|
||||||
|
### Pedagogical Principles
|
||||||
|
|
||||||
|
We follow a few key principles to make the material effective for learning:
|
||||||
|
|
||||||
|
- **Build on a Foundation:** New Rust concepts should be connected to what a
|
||||||
|
learner already knows, either from their prior language experience or from
|
||||||
|
earlier parts of this course.
|
||||||
|
- **Provide a Working Mental Model (The "No Magic" Rule):** As much as possible,
|
||||||
|
avoid telling students to accept syntax or behavior that will be explained
|
||||||
|
later. For everything that appears on the slides or in exercises, we must
|
||||||
|
provide a working mental model that allows the student to understand and use
|
||||||
|
the concept.
|
||||||
|
- **Use a [Spiral Approach](https://en.wikipedia.org/wiki/Spiral_approach):** To
|
||||||
|
avoid overwhelming the learner, it is highly encouraged to introduce a concept
|
||||||
|
by first providing basic facts and a simplified mental model. The topic can
|
||||||
|
then be revisited later to provide more detail. For example, very early in the
|
||||||
|
course we explain the basics of `println!`, mention that it is a macro so the
|
||||||
|
usage syntax is a bit unusual, but we don't go into details of format strings
|
||||||
|
or macros. We explain details of format strings later, once we have covered
|
||||||
|
traits and can mention the `Debug` and `Display` traits.
|
||||||
|
- **Live, Interactive Instruction:** The instructor is expected to run and
|
||||||
|
modify the code on the slides, and use compiler errors as a teaching tool. The
|
||||||
|
audience is expected to frequently interrupt with questions, and the
|
||||||
|
instructor would often experiment with the code on the slide to illustrate the
|
||||||
|
answer.
|
||||||
|
|
||||||
|
### Pacing and Structure
|
||||||
|
|
||||||
|
The course is designed for approximately 5 hours of teaching per day, typically
|
||||||
|
split into a 3-hour morning session and a 2-hour afternoon session.
|
||||||
|
|
||||||
|
This pacing is important context for contributors. Material should be structured
|
||||||
|
to fit this rhythm, with clear sections that can be taught in roughly 45-50
|
||||||
|
minute blocks to accommodate short breaks and Q&A.
|
||||||
|
|
||||||
|
Each slide must include a `minutes` field in its frontmatter, which specifies
|
||||||
|
the estimated teaching time for that slide. This helps ensure the overall pacing
|
||||||
|
of the course remains consistent.
|
||||||
|
|
||||||
|
### Course Structure
|
||||||
|
|
||||||
|
The course starts with a core **Rust Fundamentals** curriculum, followed by a
|
||||||
|
collection of specialized **deep dives**. All students take the Fundamentals
|
||||||
|
course and can then opt into any deep dives that are relevant to them.
|
||||||
|
|
||||||
|
#### The Rust Fundamentals Course
|
||||||
|
|
||||||
|
The **Rust Fundamentals** course provides a solid foundation in a strictly
|
||||||
|
bounded, four-day time frame. This duration is firm, and its scope is carefully
|
||||||
|
managed to focus on the most essential concepts for new Rust programmers.
|
||||||
|
|
||||||
|
The overall progression of the course starts with the parts of the Rust language
|
||||||
|
that should be conceptually familiar to most students from other languages. Then
|
||||||
|
we move on to more difficult parts (for example, enums with payloads and
|
||||||
|
generics), and parts that are unique to Rust (lifetimes and the borrow checker).
|
||||||
|
|
||||||
|
Contributors should keep this structure in mind. The four-day schedule for the
|
||||||
|
Fundamentals course is completely full, leaving no time slack for new topics.
|
||||||
|
Proposals to add material to the Rust Fundamentals course must also include a
|
||||||
|
plan to shorten or remove existing content. Refinements to existing topics are
|
||||||
|
always welcome. Topics that are not essential for all new Rust programmers
|
||||||
|
should be proposed as new deep dives.
|
||||||
|
|
||||||
## Course Slides
|
## Course Slides
|
||||||
|
|
||||||
Please take the following into account when updating the course material.
|
Please take the following into account when updating the course material.
|
||||||
@@ -26,23 +111,90 @@ Use the rectangle as a rough guide for how much you can fit on a single slide.
|
|||||||
If you find yourself adding too much detail, move the details to the speaker
|
If you find yourself adding too much detail, move the details to the speaker
|
||||||
notes (see below).
|
notes (see below).
|
||||||
|
|
||||||
### Rust Code
|
### One Core Idea Per Slide
|
||||||
|
|
||||||
When showing Rust code, please use the same spacing as `rustfmt`: `3 * x`
|
Ideally, each slide should focus on a single, clear takeaway. If a slide
|
||||||
instead of `3*x`. However, feel free to remove newlines when it can make the
|
introduces a core concept and then explores an important but distinct tangent
|
||||||
code more compact and easier to understand, e.g., you can use
|
(e.g., a limitation or an advanced use case), that tangent should be moved to
|
||||||
|
its own slide. This keeps the presentation focused and easier to follow.
|
||||||
|
|
||||||
<!-- dprint-ignore-start -->
|
Consider the instructor's workflow. If the speaker notes require a long or
|
||||||
|
complex series of live edits, it can be difficult for the instructor to execute
|
||||||
|
well every time. It may be better to add a new slide that presents the desired
|
||||||
|
state of the code.
|
||||||
|
|
||||||
```rust
|
### Pedagogical Flow
|
||||||
struct Person { name: String }
|
|
||||||
```
|
|
||||||
|
|
||||||
<!-- dprint-ignore-end -->
|
When introducing a new concept, start with a simple, relatable, and concrete
|
||||||
|
example. A good opening example grounds the concept for the learner and provides
|
||||||
|
motivation for the more detailed explanation that will follow.
|
||||||
|
|
||||||
if the `Person` struct is not important for your example. Please use this
|
### Use Meaningful Examples
|
||||||
sparingly: enclose the code block in `<!-- dprint-ignore-start -->` and
|
|
||||||
`<!-- dprint-ignore-end -->` to suppress warnings about the formatting.
|
Code samples on the slides should be short and do something meaningful. Avoid
|
||||||
|
using generic placeholders like `Foo`, `Bar`, and `Baz`. Using descriptive names
|
||||||
|
from a real-world, even if simplified, domain makes the code easier to
|
||||||
|
understand and relate to.
|
||||||
|
|
||||||
|
### Plan Interactive Code Snippets
|
||||||
|
|
||||||
|
All Rust code blocks in the course are not static text but are live, editable
|
||||||
|
playgrounds. An important teaching method is for the instructor to edit these
|
||||||
|
snippets live to demonstrate concepts, introduce and fix errors, and explore
|
||||||
|
variations based on student questions.
|
||||||
|
|
||||||
|
Contributors should design their slides with this interactivity in mind. The
|
||||||
|
initial state of the code should be a good starting point for a live
|
||||||
|
demonstration.
|
||||||
|
|
||||||
|
### `mdbook` and `mdbook-course` Conventions
|
||||||
|
|
||||||
|
The project uses `mdbook` features in specific ways, as well as a custom
|
||||||
|
preprocessor, `mdbook-course`. The following conventions are mandatory:
|
||||||
|
|
||||||
|
- **YAML Frontmatter:** Every slide file **must** include YAML frontmatter at
|
||||||
|
the top. At a minimum, this must include the `minutes` field to specify the
|
||||||
|
estimated teaching time.
|
||||||
|
- **Outline Helpers:** Pages that serve as an index for a session or segment
|
||||||
|
**must** use the `{{%session outline%}}` or `{{%segment outline%}}` helpers.
|
||||||
|
- **File Includes:** Code for exercises and their solutions **must** be included
|
||||||
|
from external files using the standard `mdbook` `{{#include ...}}` helper.
|
||||||
|
- **Translation Directives:** To prevent an element (such as a paragraph, code
|
||||||
|
block, or list item) from being translated, place a
|
||||||
|
`<!-- mdbook-xgettext: skip -->` comment on a line by itself, followed by a
|
||||||
|
blank line, immediately before the element.
|
||||||
|
|
||||||
|
For a complete explanation of the custom helpers and all available frontmatter
|
||||||
|
fields, please refer to the [`mdbook-course` README](mdbook-course/README.md).
|
||||||
|
|
||||||
|
### Language and Tone
|
||||||
|
|
||||||
|
The courses are written in American English, so write "initialize", not
|
||||||
|
"initialise".
|
||||||
|
|
||||||
|
Use an informal, friendly, and concise tone. Remember that the courses are meant
|
||||||
|
to be taught by an experienced programmer to other experienced programmers. When
|
||||||
|
possible, prefer terminology used in
|
||||||
|
[the official Rust Book](https://doc.rust-lang.org/book/). If a less common but
|
||||||
|
necessary term is used, provide a brief definition.
|
||||||
|
|
||||||
|
## Exercises
|
||||||
|
|
||||||
|
At the end of some sections, learners will actively engage with the material by
|
||||||
|
completing a small exercise. The goal of an exercise is to provide hands-on
|
||||||
|
practice with the concepts just taught.
|
||||||
|
|
||||||
|
Please keep the following principles in mind when creating or updating
|
||||||
|
exercises:
|
||||||
|
|
||||||
|
- **Focused Scope:** An exercise should focus on the topic of the preceding
|
||||||
|
section. It should not require knowledge of concepts that have not yet been
|
||||||
|
taught.
|
||||||
|
- **Short Duration:** An exercise should be solvable by the target audience in
|
||||||
|
approximately 10-15 minutes. The goal is a quick, successful application of
|
||||||
|
knowledge, not a complex project.
|
||||||
|
- **Clear Instructions:** The problem description should be clear and
|
||||||
|
unambiguous.
|
||||||
|
|
||||||
## Speaker Notes
|
## Speaker Notes
|
||||||
|
|
||||||
@@ -50,19 +202,57 @@ We have extended `mdbook` with support for speaker notes: content added between
|
|||||||
`<details> ... </details>` tags is rendered in a special box that can be
|
`<details> ... </details>` tags is rendered in a special box that can be
|
||||||
collapsed or removed entirely from the slide.
|
collapsed or removed entirely from the slide.
|
||||||
|
|
||||||
|
- Speaker notes suggest a narrative structure for the instructor.
|
||||||
|
|
||||||
- The speaker notes should expand on the topic of the slide. Use them to provide
|
- The speaker notes should expand on the topic of the slide. Use them to provide
|
||||||
interesting background information for both the instructor and for students
|
interesting background information for both the instructor and for students
|
||||||
who look at the material outside of a class. Remember that many more people
|
who look at the material outside of a class. Remember that many more people
|
||||||
will read the course by themselves, so make the notes complete and useful even
|
will read the course by themselves, so make the notes complete and useful even
|
||||||
when there is no Rust expert around.
|
when there is no Rust expert around.
|
||||||
|
|
||||||
- Avoid using speaker notes as a script for the instructor. When teaching the
|
- For slides with evolving code examples, the notes provide a clear,
|
||||||
course, instructors will only have time to glance at the notes so it is not
|
step-by-step flow for how the code is modified and presented. This is a
|
||||||
useful to include full paragraphs which the instructor should read out loud.
|
suggested flow for the instructor's live-coding session within the slide's
|
||||||
|
interactive playground. This includes:
|
||||||
|
|
||||||
|
- The order in which to introduce concepts, how to motivate them.
|
||||||
|
|
||||||
|
- Framing of the code example: the problem it tries to solve, if not obvious.
|
||||||
|
|
||||||
|
- How to demonstrate variations of the code example (e.g., code that does not
|
||||||
|
compile or illustrates a bug).
|
||||||
|
|
||||||
|
- How to change the code on the slide to illustrate the concepts being taught.
|
||||||
|
|
||||||
|
- Where to pause and engage the class with questions.
|
||||||
|
|
||||||
|
- Speaker notes should serve as a quick reference for instructors, not a
|
||||||
|
verbatim script. Because instructors have limited time to glance at notes, the
|
||||||
|
content should be concise and easy to scan.
|
||||||
|
|
||||||
|
**Avoid** long, narrative paragraphs meant to be read aloud:
|
||||||
|
> **Bad:** _"In this example, we define a trait named `StrExt`. This trait has
|
||||||
|
> a single method, `is_palindrome`, which takes a `&self` receiver and returns
|
||||||
|
> a boolean value indicating if the string is the same forwards and
|
||||||
|
> backwards..."_
|
||||||
|
|
||||||
|
**Instead, prefer** bullet points with background information or actionable
|
||||||
|
**teaching prompts**:
|
||||||
|
> **Good:**
|
||||||
|
>
|
||||||
|
> - Note: The `Ext` suffix is a common convention.
|
||||||
|
> - Ask: What happens if the `use` statement is removed?
|
||||||
|
> - Demo: Comment out the `use` statement to show the compiler error.
|
||||||
|
|
||||||
|
- Nevertheless, include all of the necessary teaching prompts for the instructor
|
||||||
|
in the speaker notes. Unlike the main content, the speaker notes don't have to
|
||||||
|
fit on a single slide.
|
||||||
|
|
||||||
### More to Explore
|
### More to Explore
|
||||||
|
|
||||||
Move extended explanations in the notes to a "More to Explore" section:
|
Use the "More to Explore" section for valuable topics that are outside the main
|
||||||
|
scope of the class. The content should be placed within the `<details>` block as
|
||||||
|
shown below:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
<details>
|
<details>
|
||||||
@@ -76,7 +266,61 @@ Move extended explanations in the notes to a "More to Explore" section:
|
|||||||
</details>
|
</details>
|
||||||
```
|
```
|
||||||
|
|
||||||
The material there is outside the scope of the regular class.
|
This section can contain a deeper explanation of a concept or provide specific
|
||||||
|
pointers to external resources. A link should be accompanied by a brief
|
||||||
|
explanation of what the resource contains and why it is relevant. A vague
|
||||||
|
reference is not helpful, but a specific one can be a great tool for
|
||||||
|
self-learners.
|
||||||
|
|
||||||
|
## Code Blocks Mechanics
|
||||||
|
|
||||||
|
Code blocks are a critical part of the course. To ensure they are consistent and
|
||||||
|
behave as expected, please follow these conventions.
|
||||||
|
|
||||||
|
### Language Identifiers
|
||||||
|
|
||||||
|
Use the following language identifiers for fenced code blocks:
|
||||||
|
|
||||||
|
- **`rust`**: For Rust code examples.
|
||||||
|
- **`shell`**: For shell commands. Use a `$` prompt for consistency. Omit the
|
||||||
|
prompt for multi-line commands or when the output is shown.
|
||||||
|
- **`bob`**: For ASCII art diagrams generated by `mdbook-bob`.
|
||||||
|
- **`ignore`**: For code snippets that are not complete, self-contained programs
|
||||||
|
or are for illustrative purposes only and should not be compiled.
|
||||||
|
|
||||||
|
### mdbook Annotations
|
||||||
|
|
||||||
|
You can add annotations to Rust code blocks to control how they are tested and
|
||||||
|
displayed:
|
||||||
|
|
||||||
|
- **`editable`**: Makes the code block an interactive playground where users can
|
||||||
|
edit and run the code. This should be used for most Rust examples.
|
||||||
|
- **`compile_fail`**: Indicates that the code is expected to fail compilation.
|
||||||
|
This is used to demonstrate specific compiler errors.
|
||||||
|
- **`should_panic`**: Indicates that the code is expected to panic when run.
|
||||||
|
- **`warnunused`**: Re-enables `unused` lints for a code block. By default, the
|
||||||
|
course's test runner disables lints for unused variables, imports, etc., to
|
||||||
|
avoid distracting warnings. Use this annotation only when a warning is part of
|
||||||
|
the lesson.
|
||||||
|
|
||||||
|
### Rust Code Formatting
|
||||||
|
|
||||||
|
When showing Rust code inline, please use the same spacing as `rustfmt`: `3 * x`
|
||||||
|
instead of `3*x`. However, feel free to remove newlines when it can make the
|
||||||
|
code more compact and easier to understand, e.g., you can define a struct on one
|
||||||
|
line if it is not the focus of your example:
|
||||||
|
|
||||||
|
<!-- dprint-ignore-start -->
|
||||||
|
|
||||||
|
```rust
|
||||||
|
struct Person { name: String }
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- dprint-ignore-end -->
|
||||||
|
|
||||||
|
Enclose the code block in `<!-- dprint-ignore-start -->` and
|
||||||
|
`<!-- dprint-ignore-end -->` to suppress the automatic formatting. Please use
|
||||||
|
this sparingly.
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
|
|
||||||
@@ -100,6 +344,6 @@ When translating the course, please take the following into account:
|
|||||||
and `**strong emphasis**` like in the original.
|
and `**strong emphasis**` like in the original.
|
||||||
|
|
||||||
- If you find mistakes or things that sound awkward in the original English
|
- If you find mistakes or things that sound awkward in the original English
|
||||||
text, please submit PRs to fix them! Fixing typos in the translation is great,
|
text, please submit PRs to fix them in the English text! Fixing typos in the
|
||||||
but we want everybody to benefit from the fixes and that is why we need the
|
translation is great, but we want everybody to benefit from the fixes and that
|
||||||
fix to be made in the English text too.
|
is why we need the fix to be made in the English text too.
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"command": "yapf3",
|
"command": "yapf3",
|
||||||
"exts": ["py"]
|
"exts": ["py"]
|
||||||
}, {
|
}, {
|
||||||
"command": "rustup run stable rustfmt --edition 2024",
|
"command": "rustup run nightly-2025-09-01 rustfmt --edition 2024",
|
||||||
"exts": ["rs"]
|
"exts": ["rs"]
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
@@ -9,14 +9,14 @@ repository = "https://github.com/google/comprehensive-rust"
|
|||||||
description = "An mdbook preprocessor for comprehensive-rust."
|
description = "An mdbook preprocessor for comprehensive-rust."
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.99"
|
||||||
clap = "4.5.40"
|
clap = "4.5.46"
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
matter = "0.1.0-alpha4"
|
matter = "0.1.0-alpha4"
|
||||||
mdbook = "0.4.51"
|
mdbook = "0.4.52"
|
||||||
pretty_env_logger = "0.5.0"
|
pretty_env_logger = "0.5.0"
|
||||||
regex = "1.11"
|
regex = "1.11"
|
||||||
serde = "1.0.219"
|
serde = "1.0.219"
|
||||||
serde_json = "1.0.140"
|
serde_json = "1.0.143"
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.9"
|
||||||
|
@@ -48,7 +48,7 @@ fn timediff(actual: u64, target: u64, slop: u64) -> String {
|
|||||||
} else if actual + slop < target {
|
} else if actual + slop < target {
|
||||||
format!("{}: ({} short)", duration(actual), duration(target - actual),)
|
format!("{}: ({} short)", duration(actual), duration(target - actual),)
|
||||||
} else {
|
} else {
|
||||||
format!("{}", duration(actual))
|
duration(actual).to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ fn main() {
|
|||||||
);
|
);
|
||||||
let matches = app.get_matches();
|
let matches = app.get_matches();
|
||||||
|
|
||||||
if let Some(_) = matches.subcommand_matches("supports") {
|
if matches.subcommand_matches("supports").is_some() {
|
||||||
// Support all renderers.
|
// Support all renderers.
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
}
|
}
|
||||||
|
@@ -156,7 +156,7 @@ impl Courses {
|
|||||||
fn course_mut(&mut self, name: impl AsRef<str>) -> &mut Course {
|
fn course_mut(&mut self, name: impl AsRef<str>) -> &mut Course {
|
||||||
let name = name.as_ref();
|
let name = name.as_ref();
|
||||||
if let Some(found_idx) =
|
if let Some(found_idx) =
|
||||||
self.courses.iter().position(|course| &course.name == name)
|
self.courses.iter().position(|course| course.name == name)
|
||||||
{
|
{
|
||||||
return &mut self.courses[found_idx];
|
return &mut self.courses[found_idx];
|
||||||
}
|
}
|
||||||
@@ -177,9 +177,7 @@ impl Courses {
|
|||||||
&self,
|
&self,
|
||||||
chapter: &Chapter,
|
chapter: &Chapter,
|
||||||
) -> Option<(&Course, &Session, &Segment, &Slide)> {
|
) -> Option<(&Course, &Session, &Segment, &Slide)> {
|
||||||
let Some(ref source_path) = chapter.source_path else {
|
let source_path = chapter.source_path.as_ref()?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
for course in self {
|
for course in self {
|
||||||
for session in course {
|
for session in course {
|
||||||
@@ -193,7 +191,7 @@ impl Courses {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return None;
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +200,7 @@ impl<'a> IntoIterator for &'a Courses {
|
|||||||
type IntoIter = std::slice::Iter<'a, Course>;
|
type IntoIter = std::slice::Iter<'a, Course>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
(&self.courses).into_iter()
|
self.courses.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +214,7 @@ impl Course {
|
|||||||
fn session_mut(&mut self, name: impl AsRef<str>) -> &mut Session {
|
fn session_mut(&mut self, name: impl AsRef<str>) -> &mut Session {
|
||||||
let name = name.as_ref();
|
let name = name.as_ref();
|
||||||
if let Some(found_idx) =
|
if let Some(found_idx) =
|
||||||
self.sessions.iter().position(|session| &session.name == name)
|
self.sessions.iter().position(|session| session.name == name)
|
||||||
{
|
{
|
||||||
return &mut self.sessions[found_idx];
|
return &mut self.sessions[found_idx];
|
||||||
}
|
}
|
||||||
@@ -275,7 +273,7 @@ impl<'a> IntoIterator for &'a Course {
|
|||||||
type IntoIter = std::slice::Iter<'a, Session>;
|
type IntoIter = std::slice::Iter<'a, Session>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
(&self.sessions).into_iter()
|
self.sessions.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +346,7 @@ impl<'a> IntoIterator for &'a Session {
|
|||||||
type IntoIter = std::slice::Iter<'a, Segment>;
|
type IntoIter = std::slice::Iter<'a, Segment>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
(&self.segments).into_iter()
|
self.segments.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +399,7 @@ impl<'a> IntoIterator for &'a Segment {
|
|||||||
type IntoIter = std::slice::Iter<'a, Slide>;
|
type IntoIter = std::slice::Iter<'a, Slide>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
(&self.slides).into_iter()
|
self.slides.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,7 +447,7 @@ impl Slide {
|
|||||||
pub fn is_sub_chapter(&self, chapter: &Chapter) -> bool {
|
pub fn is_sub_chapter(&self, chapter: &Chapter) -> bool {
|
||||||
// The first `source_path` in the slide is the "parent" chapter, so anything
|
// The first `source_path` in the slide is the "parent" chapter, so anything
|
||||||
// else is a sub-chapter.
|
// else is a sub-chapter.
|
||||||
chapter.source_path.as_ref() != self.source_paths.get(0)
|
chapter.source_path.as_ref() != self.source_paths.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the total duration of this slide.
|
/// Return the total duration of this slide.
|
||||||
|
@@ -83,7 +83,7 @@ impl<const N: usize> Table<N> {
|
|||||||
for cell in iter {
|
for cell in iter {
|
||||||
write!(f, " {} |", cell)?;
|
write!(f, " {} |", cell)?;
|
||||||
}
|
}
|
||||||
write!(f, "\n")
|
writeln!(f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,7 +51,7 @@ pub fn replace(
|
|||||||
["course", "outline", course_name @ ..] => {
|
["course", "outline", course_name @ ..] => {
|
||||||
let course_name = course_name.join(" ");
|
let course_name = course_name.join(" ");
|
||||||
let Some(course) = courses.find_course(course_name) else {
|
let Some(course) = courses.find_course(course_name) else {
|
||||||
return format!("not found - {}", captures[0].to_string());
|
return format!("not found - {}", &captures[0]);
|
||||||
};
|
};
|
||||||
course.schedule()
|
course.schedule()
|
||||||
}
|
}
|
||||||
|
@@ -8,8 +8,8 @@ repository = "https://github.com/google/comprehensive-rust"
|
|||||||
description = "A tool for extracting starter code for exercises from Markdown files."
|
description = "A tool for extracting starter code for exercises from Markdown files."
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.99"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
mdbook = "0.4.51"
|
mdbook = "0.4.52"
|
||||||
pretty_env_logger = "0.5.0"
|
pretty_env_logger = "0.5.0"
|
||||||
pulldown-cmark = { version = "0.13.0", default-features = false }
|
pulldown-cmark = { version = "0.13.0", default-features = false }
|
||||||
|
63
po/es.po
63
po/es.po
@@ -13653,34 +13653,32 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "Testing in Android"
|
msgid "Testing in Android"
|
||||||
msgstr "Rust en Android"
|
msgstr "Pruebas en Android"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
msgid ""
|
msgid ""
|
||||||
"Building on [Testing](../testing.md), we will now look at how unit tests "
|
"Building on [Testing](../testing.md), we will now look at how unit tests "
|
||||||
"work in AOSP. Use the `rust_test` module for your unit tests:"
|
"work in AOSP. Use the `rust_test` module for your unit tests:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Basándonos en [Pruebas](../testing.md), ahora veremos cómo funcionan las pruebas "
|
||||||
|
"unitarias en AOSP. Usa el módulo `rust_test` para tus pruebas unitarias:"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "_testing/Android.bp_:"
|
msgid "_testing/Android.bp_:"
|
||||||
msgstr "_hello_rust/Android.bp_:"
|
msgstr "_testing/Android.bp_:"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "\"libleftpad\""
|
msgid "\"libleftpad\""
|
||||||
msgstr "\"libtextwrap\""
|
msgstr "\"libleftpad\""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
msgid "\"leftpad\""
|
msgid "\"leftpad\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "\"libleftpad_test\""
|
msgid "\"libleftpad_test\""
|
||||||
msgstr "\"libbirthday_bindgen_test\""
|
msgstr "\"libleftpad_test\""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
msgid "\"leftpad_test\""
|
msgid "\"leftpad_test\""
|
||||||
@@ -13691,43 +13689,36 @@ msgid "\"general-tests\""
|
|||||||
msgstr "\"general-tests\""
|
msgstr "\"general-tests\""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "_testing/src/lib.rs_:"
|
msgid "_testing/src/lib.rs_:"
|
||||||
msgstr "_hello_rust/src/lib.rs_:"
|
msgstr "_testing/src/lib.rs_:"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "//! Left-padding library.\n"
|
msgid "//! Left-padding library.\n"
|
||||||
msgstr "//! Biblioteca de saludos.\n"
|
msgstr "//! Biblioteca de relleno a la izquierda.\n"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
msgid "/// Left-pad `s` to `width`.\n"
|
msgid "/// Left-pad `s` to `width`.\n"
|
||||||
msgstr ""
|
msgstr "/// Rellena `s` a la izquierda hasta `width`.\n"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "\"{s:>width$}\""
|
msgid "\"{s:>width$}\""
|
||||||
msgstr "\"|{:^width$}|\""
|
msgstr "\"{s:>width$}\""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "\" foo\""
|
msgid "\" foo\""
|
||||||
msgstr "\"foo\""
|
msgstr "\" foo\""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "\"foobar\""
|
msgid "\"foobar\""
|
||||||
msgstr "\"foo\""
|
msgstr "\"foobar\""
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "You can now run the test with"
|
msgid "You can now run the test with"
|
||||||
msgstr "Ahora puedes generar automáticamente los enlaces:"
|
msgstr "Ahora puedes ejecutar la prueba con"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
#, fuzzy
|
|
||||||
msgid "The output looks like this:"
|
msgid "The output looks like this:"
|
||||||
msgstr "El enfoque general es el siguiente:"
|
msgstr "La salida se ve así:"
|
||||||
|
|
||||||
#: src/android/testing.md
|
#: src/android/testing.md
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -13748,15 +13739,16 @@ msgid ""
|
|||||||
"Notice how you only mention the root of the library crate. Tests are found "
|
"Notice how you only mention the root of the library crate. Tests are found "
|
||||||
"recursively in nested modules."
|
"recursively in nested modules."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Observa que solo mencionas la raíz del crate de la biblioteca. Las pruebas se "
|
||||||
|
"encuentran de forma recursiva en módulos anidados."
|
||||||
|
|
||||||
#: src/android/testing/googletest.md
|
#: src/android/testing/googletest.md
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The [GoogleTest](https://docs.rs/googletest/) crate allows for flexible test "
|
"The [GoogleTest](https://docs.rs/googletest/) crate allows for flexible test "
|
||||||
"assertions using _matchers_:"
|
"assertions using _matchers_:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"[googletest](https://docs.rs/googletest): biblioteca completa de aserción de "
|
"El crate [GoogleTest](https://docs.rs/googletest/) permite realizar aserciones de "
|
||||||
"pruebas en la tradición de GoogleTest para C++."
|
"prueba flexibles utilizando _matchers_:"
|
||||||
|
|
||||||
#: src/android/testing/googletest.md
|
#: src/android/testing/googletest.md
|
||||||
msgid "\"baz\""
|
msgid "\"baz\""
|
||||||
@@ -13804,13 +13796,12 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/android/testing/googletest.md
|
#: src/android/testing/googletest.md
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"A particularly nice feature is that mismatches in multi-line strings are "
|
"A particularly nice feature is that mismatches in multi-line strings are "
|
||||||
"shown as a diff:"
|
"shown as a diff:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Una característica muy interesante es que las discrepancias en las cadenas "
|
"Una característica especialmente útil es que las discrepancias en cadenas de "
|
||||||
"que contienen varias líneas se muestran como un diff:"
|
"varias líneas se muestran como un diff:"
|
||||||
|
|
||||||
#: src/android/testing/googletest.md
|
#: src/android/testing/googletest.md
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -13855,7 +13846,6 @@ msgstr ""
|
|||||||
"podrás hacer simulaciones:"
|
"podrás hacer simulaciones:"
|
||||||
|
|
||||||
#: src/android/testing/mocking.md
|
#: src/android/testing/mocking.md
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Mockall is the recommended mocking library in Android (AOSP). There are "
|
"Mockall is the recommended mocking library in Android (AOSP). There are "
|
||||||
"other [mocking libraries available on crates.io](https://crates.io/keywords/"
|
"other [mocking libraries available on crates.io](https://crates.io/keywords/"
|
||||||
@@ -13863,13 +13853,12 @@ msgid ""
|
|||||||
"libraries work in a similar fashion as Mockall, meaning that they make it "
|
"libraries work in a similar fashion as Mockall, meaning that they make it "
|
||||||
"easy to get a mock implementation of a given trait."
|
"easy to get a mock implementation of a given trait."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Estos consejos son útiles para Android (AOSP), donde Mockall es la "
|
"Mockall es la biblioteca de simulación recomendada en Android (AOSP). Hay "
|
||||||
"biblioteca de simulaciones recomendada. Hay otras [bibliotecas de simulación "
|
"otras [bibliotecas de simulación disponibles en crates.io](https://crates.io/keywords/mock), "
|
||||||
"disponibles en crates.io](https://crates.io/keywords/mock), especialmente en "
|
"particularmente en el área de simulación de servicios HTTP. Las demás "
|
||||||
"el área de servicios de simulación de HTTP. Las demás bibliotecas de "
|
"bibliotecas de simulación funcionan de manera similar a Mockall, lo que "
|
||||||
"simulación funcionan de forma similar a Mockall, lo que significa que "
|
"significa que facilitan la obtención de una implementación simulada de un "
|
||||||
"facilitan la obtención de una implementación simulada de un trait "
|
"trait determinado."
|
||||||
"determinado."
|
|
||||||
|
|
||||||
#: src/android/testing/mocking.md
|
#: src/android/testing/mocking.md
|
||||||
msgid ""
|
msgid ""
|
||||||
|
6
po/fa.po
6
po/fa.po
@@ -1712,7 +1712,7 @@ msgstr "۴۰ دقیقه"
|
|||||||
|
|
||||||
#: src/running-the-course/course-structure.md
|
#: src/running-the-course/course-structure.md
|
||||||
msgid "Day 1 Afternoon (2 hours and 35 minutes, including breaks)"
|
msgid "Day 1 Afternoon (2 hours and 35 minutes, including breaks)"
|
||||||
msgstr "روز ۱ بعد از ظهر (۲ ساعت و ۳۵ دقیقه،شامل وقت استراحت)"
|
msgstr "روز ۱ بعد از ظهر (۲ ساعت و ۳۵ دقیقه، شامل وقت استراحت)"
|
||||||
|
|
||||||
#: src/running-the-course/course-structure.md src/welcome-day-1-afternoon.md
|
#: src/running-the-course/course-structure.md src/welcome-day-1-afternoon.md
|
||||||
msgid "35 minutes"
|
msgid "35 minutes"
|
||||||
@@ -1818,7 +1818,7 @@ msgstr ""
|
|||||||
"شما نیاز دارید که یک نسخه از [مخزن ASOP](https://source.android.com/docs/"
|
"شما نیاز دارید که یک نسخه از [مخزن ASOP](https://source.android.com/docs/"
|
||||||
"setup/download/downloading) بگیرید, همچنین یک نسخه از [مخزن دوره](https://"
|
"setup/download/downloading) بگیرید, همچنین یک نسخه از [مخزن دوره](https://"
|
||||||
"github.com/google/comprehensive-rust) بگیرید و روی همون ماشین در مسیر `src/"
|
"github.com/google/comprehensive-rust) بگیرید و روی همون ماشین در مسیر `src/"
|
||||||
"android/`مخزن ASOP قرار دهید. با این کار طمینان حاصل میکنید که سیستم build "
|
"android/`مخزن ASOP قرار دهید. با این کار اطمینان حاصل میکنید که سیستم build "
|
||||||
"اندروید فایل های `Android.bp` را در `src/android/` میبینید."
|
"اندروید فایل های `Android.bp` را در `src/android/` میبینید."
|
||||||
|
|
||||||
#: src/running-the-course/course-structure.md
|
#: src/running-the-course/course-structure.md
|
||||||
@@ -1909,7 +1909,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/running-the-course/course-structure.md
|
#: src/running-the-course/course-structure.md
|
||||||
msgid "Morning (3 hours and 20 minutes, including breaks)"
|
msgid "Morning (3 hours and 20 minutes, including breaks)"
|
||||||
msgstr "صبح (۳ ساعت و ۲۰ دقیقه، شامل وقت اسراحت)"
|
msgstr "صبح (۳ ساعت و ۲۰ دقیقه، شامل وقت استراحت)"
|
||||||
|
|
||||||
#: src/running-the-course/course-structure.md src/pattern-matching.md
|
#: src/running-the-course/course-structure.md src/pattern-matching.md
|
||||||
#: src/std-traits.md src/smart-pointers.md src/lifetimes.md src/iterators.md
|
#: src/std-traits.md src/smart-pointers.md src/lifetimes.md src/iterators.md
|
||||||
|
79
po/ko.po
79
po/ko.po
@@ -188,7 +188,7 @@ msgstr "튜플"
|
|||||||
#: src/SUMMARY.md src/tuples-and-arrays/iteration.md
|
#: src/SUMMARY.md src/tuples-and-arrays/iteration.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Array Iteration"
|
msgid "Array Iteration"
|
||||||
msgstr "배열 반복"
|
msgstr "배열 순회"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/tuples-and-arrays/destructuring.md
|
#: src/SUMMARY.md src/tuples-and-arrays/destructuring.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -216,7 +216,7 @@ msgstr "허상(dangling) 참조"
|
|||||||
#: src/SUMMARY.md src/references/exercise.md
|
#: src/SUMMARY.md src/references/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: Geometry"
|
msgid "Exercise: Geometry"
|
||||||
msgstr "연습문제: 도형"
|
msgstr "연습문제: 기하"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/user-defined-types.md
|
#: src/SUMMARY.md src/user-defined-types.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -275,7 +275,7 @@ msgstr "흐름 제어"
|
|||||||
|
|
||||||
#: src/SUMMARY.md src/pattern-matching/exercise.md
|
#: src/SUMMARY.md src/pattern-matching/exercise.md
|
||||||
msgid "Exercise: Expression Evaluation"
|
msgid "Exercise: Expression Evaluation"
|
||||||
msgstr "연습문제: 표현식 평가"
|
msgstr "연습문제: 수식 계산"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/methods-and-traits.md
|
#: src/SUMMARY.md src/methods-and-traits.md
|
||||||
msgid "Methods and Traits"
|
msgid "Methods and Traits"
|
||||||
@@ -312,7 +312,7 @@ msgstr "트레잇 상속하기"
|
|||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: Generic Logger"
|
msgid "Exercise: Generic Logger"
|
||||||
msgstr "연습문제: 일반 `min`"
|
msgstr "연습문제: 범용 로거"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/generics.md
|
#: src/SUMMARY.md src/generics.md
|
||||||
msgid "Generics"
|
msgid "Generics"
|
||||||
@@ -343,7 +343,7 @@ msgstr "트레잇 구현하기(`impl Trait`)"
|
|||||||
#: src/SUMMARY.md src/generics/exercise.md
|
#: src/SUMMARY.md src/generics/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: Generic `min`"
|
msgid "Exercise: Generic `min`"
|
||||||
msgstr "연습문제: 일반 `min`"
|
msgstr "연습문제: 범용 `min`"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
msgid "Day 2: Afternoon"
|
msgid "Day 2: Afternoon"
|
||||||
@@ -352,7 +352,7 @@ msgstr "2일차 오후"
|
|||||||
#: src/SUMMARY.md src/std-types.md
|
#: src/SUMMARY.md src/std-types.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Standard Library Types"
|
msgid "Standard Library Types"
|
||||||
msgstr "표준 라이브러리"
|
msgstr "표준 라이브러리 타입"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/std-types/std.md
|
#: src/SUMMARY.md src/std-types/std.md
|
||||||
msgid "Standard Library"
|
msgid "Standard Library"
|
||||||
@@ -394,7 +394,7 @@ msgstr "연습문제: 카운터"
|
|||||||
#: src/SUMMARY.md src/std-traits.md
|
#: src/SUMMARY.md src/std-traits.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Standard Library Traits"
|
msgid "Standard Library Traits"
|
||||||
msgstr "표준 라이브러리"
|
msgstr "표준 라이브러리 트레잇"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/std-traits/comparisons.md src/async.md
|
#: src/SUMMARY.md src/std-traits/comparisons.md src/async.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -430,7 +430,7 @@ msgstr "클로저(Closure)"
|
|||||||
#: src/SUMMARY.md src/std-traits/exercise.md
|
#: src/SUMMARY.md src/std-traits/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: ROT13"
|
msgid "Exercise: ROT13"
|
||||||
msgstr "연습문제: 바이너리 트리"
|
msgstr "연습문제: ROT13"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
msgid "Day 3: Morning"
|
msgid "Day 3: Morning"
|
||||||
@@ -474,7 +474,7 @@ msgstr "Drop"
|
|||||||
#: src/SUMMARY.md src/memory-management/exercise.md
|
#: src/SUMMARY.md src/memory-management/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: Builder Type"
|
msgid "Exercise: Builder Type"
|
||||||
msgstr "연습문제: 빌드 타입"
|
msgstr "연습문제: Builder 타입"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/smart-pointers.md
|
#: src/SUMMARY.md src/smart-pointers.md
|
||||||
msgid "Smart Pointers"
|
msgid "Smart Pointers"
|
||||||
@@ -505,17 +505,17 @@ msgstr "3일차 오후"
|
|||||||
|
|
||||||
#: src/SUMMARY.md src/borrowing.md
|
#: src/SUMMARY.md src/borrowing.md
|
||||||
msgid "Borrowing"
|
msgid "Borrowing"
|
||||||
msgstr "빌림"
|
msgstr "대여"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/borrowing/shared.md
|
#: src/SUMMARY.md src/borrowing/shared.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Borrowing a Value"
|
msgid "Borrowing a Value"
|
||||||
msgstr "빌림"
|
msgstr "값 대여"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/borrowing/borrowck.md
|
#: src/SUMMARY.md src/borrowing/borrowck.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Borrow Checking"
|
msgid "Borrow Checking"
|
||||||
msgstr "빌림"
|
msgstr "대여 검증"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/borrowing/interior-mutability.md
|
#: src/SUMMARY.md src/borrowing/interior-mutability.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -525,12 +525,12 @@ msgstr "상호운용성"
|
|||||||
#: src/SUMMARY.md src/borrowing/exercise.md
|
#: src/SUMMARY.md src/borrowing/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: Health Statistics"
|
msgid "Exercise: Health Statistics"
|
||||||
msgstr "연습문제: 엘리베이터 이벤트"
|
msgstr "연습문제: 건강검진"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/slices-and-lifetimes.md
|
#: src/SUMMARY.md src/slices-and-lifetimes.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Slices and Lifetimes"
|
msgid "Slices and Lifetimes"
|
||||||
msgstr "수명"
|
msgstr "슬라이스와 수명"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -540,7 +540,7 @@ msgstr "슬라이스"
|
|||||||
#: src/SUMMARY.md src/slices-and-lifetimes/str.md
|
#: src/SUMMARY.md src/slices-and-lifetimes/str.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "String References"
|
msgid "String References"
|
||||||
msgstr "허상(dangling) 참조"
|
msgstr "문자열 레퍼런스"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/slices-and-lifetimes/lifetime-annotations.md
|
#: src/SUMMARY.md src/slices-and-lifetimes/lifetime-annotations.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -550,12 +550,12 @@ msgstr "함수 호출에서의 수명"
|
|||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Lifetime Elision"
|
msgid "Lifetime Elision"
|
||||||
msgstr "수명"
|
msgstr "수명 표기의 생략"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Struct Lifetimes"
|
msgid "Struct Lifetimes"
|
||||||
msgstr "수명"
|
msgstr "구조체의 수명"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/slices-and-lifetimes/exercise.md
|
#: src/SUMMARY.md src/slices-and-lifetimes/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -565,7 +565,7 @@ msgstr "연습문제: Protobuf 파싱"
|
|||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Day 4: Morning"
|
msgid "Day 4: Morning"
|
||||||
msgstr "1일차 오전"
|
msgstr "4일차 오전"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/iterators.md
|
#: src/SUMMARY.md src/iterators.md
|
||||||
msgid "Iterators"
|
msgid "Iterators"
|
||||||
@@ -587,7 +587,7 @@ msgstr "FromIterator"
|
|||||||
#: src/SUMMARY.md src/iterators/exercise.md
|
#: src/SUMMARY.md src/iterators/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: Iterator Method Chaining"
|
msgid "Exercise: Iterator Method Chaining"
|
||||||
msgstr "연습문제: 반복자 메서드 체이닝"
|
msgstr "연습문제: Iterator 메서드 체이닝"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/modules.md src/modules/modules.md
|
#: src/SUMMARY.md src/modules.md src/modules/modules.md
|
||||||
msgid "Modules"
|
msgid "Modules"
|
||||||
@@ -608,7 +608,7 @@ msgstr "`use`, `super`, `self`"
|
|||||||
#: src/SUMMARY.md src/modules/exercise.md
|
#: src/SUMMARY.md src/modules/exercise.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Exercise: Modules for a GUI Library"
|
msgid "Exercise: Modules for a GUI Library"
|
||||||
msgstr "연습문제: GUI 라이브러리 모듈"
|
msgstr "연습문제: GUI 라이브러리 모듈 만들기"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/testing.md src/chromium/testing.md
|
#: src/SUMMARY.md src/testing.md src/chromium/testing.md
|
||||||
msgid "Testing"
|
msgid "Testing"
|
||||||
@@ -621,7 +621,7 @@ msgstr "테스트 모듈"
|
|||||||
#: src/SUMMARY.md src/testing/other.md
|
#: src/SUMMARY.md src/testing/other.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Other Types of Tests"
|
msgid "Other Types of Tests"
|
||||||
msgstr "다른 프로젝트"
|
msgstr "다른 테스트 프로젝트 타입"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/testing/lints.md
|
#: src/SUMMARY.md src/testing/lints.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -636,7 +636,7 @@ msgstr "룬 알고리즘"
|
|||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Day 4: Afternoon"
|
msgid "Day 4: Afternoon"
|
||||||
msgstr "1일차 오후"
|
msgstr "4일차 오후"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/error-handling.md
|
#: src/SUMMARY.md src/error-handling.md
|
||||||
msgid "Error Handling"
|
msgid "Error Handling"
|
||||||
@@ -659,7 +659,7 @@ msgstr "묵시적 형변환"
|
|||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "`Error` Trait"
|
msgid "`Error` Trait"
|
||||||
msgstr "`Error`"
|
msgstr "`Error` 트레잇"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/error-handling/thiserror-and-anyhow.md
|
#: src/SUMMARY.md src/error-handling/thiserror-and-anyhow.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -741,12 +741,12 @@ msgstr "AIDL 인터페이스"
|
|||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
msgid "Service API"
|
msgid "Service API"
|
||||||
msgstr ""
|
msgstr "서비스 API"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Service"
|
msgid "Service"
|
||||||
msgstr "AIDL 서버"
|
msgstr "AIDL 서비스"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
msgid "Server"
|
msgid "Server"
|
||||||
@@ -767,16 +767,16 @@ msgstr "API 수정"
|
|||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Updating Implementations"
|
msgid "Updating Implementations"
|
||||||
msgstr "서비스 구현"
|
msgstr "구헌체 업데이트"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "AIDL Types"
|
msgid "AIDL Types"
|
||||||
msgstr "타입"
|
msgstr "AIDL 타입"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/android/aidl/types/primitives.md
|
#: src/SUMMARY.md src/android/aidl/types/primitives.md
|
||||||
msgid "Primitive Types"
|
msgid "Primitive Types"
|
||||||
msgstr ""
|
msgstr "원시 타입"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/android/aidl/types/arrays.md
|
#: src/SUMMARY.md src/android/aidl/types/arrays.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -832,7 +832,7 @@ msgstr "C++와의 상호운용성"
|
|||||||
#: src/SUMMARY.md src/android/interoperability/cpp/bridge.md
|
#: src/SUMMARY.md src/android/interoperability/cpp/bridge.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "The Bridge Module"
|
msgid "The Bridge Module"
|
||||||
msgstr "테스트 모듈"
|
msgstr "브리지 모듈"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
msgid "Rust Bridge"
|
msgid "Rust Bridge"
|
||||||
@@ -859,12 +859,12 @@ msgstr "공유 Enum"
|
|||||||
#: src/SUMMARY.md src/android/interoperability/cpp/rust-result.md
|
#: src/SUMMARY.md src/android/interoperability/cpp/rust-result.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Rust Error Handling"
|
msgid "Rust Error Handling"
|
||||||
msgstr "오류처리"
|
msgstr "Rust 오류처리"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/android/interoperability/cpp/cpp-exception.md
|
#: src/SUMMARY.md src/android/interoperability/cpp/cpp-exception.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "C++ Error Handling"
|
msgid "C++ Error Handling"
|
||||||
msgstr "오류처리"
|
msgstr "C++ 오류처리"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/android/interoperability/cpp/type-mapping.md
|
#: src/SUMMARY.md src/android/interoperability/cpp/type-mapping.md
|
||||||
msgid "Additional Types"
|
msgid "Additional Types"
|
||||||
@@ -909,12 +909,12 @@ msgstr "정책"
|
|||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Unsafe Code"
|
msgid "Unsafe Code"
|
||||||
msgstr "안전하지 않은 러스트"
|
msgstr "안전하지 않은 코드"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/chromium/build-rules/depending.md
|
#: src/SUMMARY.md src/chromium/build-rules/depending.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Depending on Rust Code from Chromium C++"
|
msgid "Depending on Rust Code from Chromium C++"
|
||||||
msgstr "Chromium C++의 Rust 코드에 의존"
|
msgstr "Chromium C++에 의존하는 Rust 코드"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/chromium/build-rules/vscode.md
|
#: src/SUMMARY.md src/chromium/build-rules/vscode.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -941,7 +941,7 @@ msgstr ""
|
|||||||
#: src/SUMMARY.md src/chromium/interoperability-with-cpp.md
|
#: src/SUMMARY.md src/chromium/interoperability-with-cpp.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Interoperability with C++"
|
msgid "Interoperability with C++"
|
||||||
msgstr "C와의 상호운용성"
|
msgstr "C++와의 상호운용성"
|
||||||
|
|
||||||
#: src/SUMMARY.md src/chromium/interoperability-with-cpp/example-bindings.md
|
#: src/SUMMARY.md src/chromium/interoperability-with-cpp/example-bindings.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -955,17 +955,17 @@ msgstr "CXX 제한사항"
|
|||||||
#: src/SUMMARY.md src/chromium/interoperability-with-cpp/error-handling.md
|
#: src/SUMMARY.md src/chromium/interoperability-with-cpp/error-handling.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "CXX Error Handling"
|
msgid "CXX Error Handling"
|
||||||
msgstr "오류처리"
|
msgstr "CXX에서의 오류처리"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Error Handling: QR Example"
|
msgid "Error Handling: QR Example"
|
||||||
msgstr "오류처리"
|
msgstr "오류처리 예제: QR"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Error Handling: PNG Example"
|
msgid "Error Handling: PNG Example"
|
||||||
msgstr "오류처리"
|
msgstr "오류처리 예제: PNG"
|
||||||
|
|
||||||
#: src/SUMMARY.md
|
#: src/SUMMARY.md
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -1440,7 +1440,7 @@ msgid ""
|
|||||||
"based browsers. This includes interoperability with C++ and how to include "
|
"based browsers. This includes interoperability with C++ and how to include "
|
||||||
"third-party crates in Chromium."
|
"third-party crates in Chromium."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"[Chromium의 Rust](../chromium.md) 심층 분석은 Chromium 브라우저의 일부로 Rust"
|
"[Chromium의 Rust](chromium.md) 심층 분석은 Chromium 브라우저의 일부로 Rust"
|
||||||
"를 사용하는 방법에 관한 반나절 과정입니다. 여기에는 Chromium의 'gn' 빌드 시스"
|
"를 사용하는 방법에 관한 반나절 과정입니다. 여기에는 Chromium의 'gn' 빌드 시스"
|
||||||
"템에서 Rust를 사용하여 서드 파티 라이브러리(\"crates\")와 C++ 상호 운용성을 "
|
"템에서 Rust를 사용하여 서드 파티 라이브러리(\"crates\")와 C++ 상호 운용성을 "
|
||||||
"가져오는 방법이 포함되어 있습니다."
|
"가져오는 방법이 포함되어 있습니다."
|
||||||
@@ -2253,7 +2253,8 @@ msgid ""
|
|||||||
"Dependencies can also be resolved from alternative [registries](https://doc."
|
"Dependencies can also be resolved from alternative [registries](https://doc."
|
||||||
"rust-lang.org/cargo/reference/registries.html), git, folders, and more."
|
"rust-lang.org/cargo/reference/registries.html), git, folders, and more."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"의존성은 다양한 [저장소](registries), git 프로젝트, 디렉터리 등에서 제공될 "
|
"의존성은 다양한 [저장소](https://doc."
|
||||||
|
"rust-lang.org/cargo/reference/registries.html), git 프로젝트, 디렉터리 등에서 제공될 "
|
||||||
"수 있습니다."
|
"수 있습니다."
|
||||||
|
|
||||||
#: src/cargo/rust-ecosystem.md
|
#: src/cargo/rust-ecosystem.md
|
||||||
|
21
po/vi.po
21
po/vi.po
@@ -4785,34 +4785,38 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/welcome-day-2.md
|
#: src/welcome-day-2.md
|
||||||
msgid "Welcome to Day 2"
|
msgid "Welcome to Day 2"
|
||||||
msgstr ""
|
msgstr "Chào mừng tới Ngày 2"
|
||||||
|
|
||||||
#: src/welcome-day-2.md
|
#: src/welcome-day-2.md
|
||||||
msgid ""
|
msgid ""
|
||||||
"Now that we have seen a fair amount of Rust, today will focus on Rust's type "
|
"Now that we have seen a fair amount of Rust, today will focus on Rust's type "
|
||||||
"system:"
|
"system:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Chúng ta đã có kiến thức tổng quan về Rust, hôm nay sẽ tập trung vào hệ "
|
||||||
|
"thống kiểu trong Rust:"
|
||||||
|
|
||||||
#: src/welcome-day-2.md
|
#: src/welcome-day-2.md
|
||||||
msgid "Pattern matching: extracting data from structures."
|
msgid "Pattern matching: extracting data from structures."
|
||||||
msgstr ""
|
msgstr "So khớp mẫu (Pattern matching): trích xuất dữ liệu từ các cấu trúc."
|
||||||
|
|
||||||
#: src/welcome-day-2.md
|
#: src/welcome-day-2.md
|
||||||
msgid "Methods: associating functions with types."
|
msgid "Methods: associating functions with types."
|
||||||
msgstr ""
|
msgstr "Phương thức (Methods): liên kết hàm với các kiểu dữ liệu."
|
||||||
|
|
||||||
#: src/welcome-day-2.md
|
#: src/welcome-day-2.md
|
||||||
msgid "Traits: behaviors shared by multiple types."
|
msgid "Traits: behaviors shared by multiple types."
|
||||||
msgstr ""
|
msgstr "Traits: hành vi được chia sẻ bởi nhiều kiểu dữ liệu."
|
||||||
|
|
||||||
#: src/welcome-day-2.md
|
#: src/welcome-day-2.md
|
||||||
msgid "Generics: parameterizing types on other types."
|
msgid "Generics: parameterizing types on other types."
|
||||||
msgstr ""
|
msgstr "Generics: tham số hóa các kiểu dữ liệu trên các kiểu khác nhau."
|
||||||
|
|
||||||
#: src/welcome-day-2.md
|
#: src/welcome-day-2.md
|
||||||
msgid ""
|
msgid ""
|
||||||
"Standard library types and traits: a tour of Rust's rich standard library."
|
"Standard library types and traits: a tour of Rust's rich standard library."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Các kiểu thư viện chuẩn và traits: sơ bộ về thư viện chuẩn phong phú của "
|
||||||
|
"Rust."
|
||||||
|
|
||||||
#: src/welcome-day-2.md src/welcome-day-4-afternoon.md
|
#: src/welcome-day-2.md src/welcome-day-4-afternoon.md
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -7113,21 +7117,24 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/welcome-day-3.md
|
#: src/welcome-day-3.md
|
||||||
msgid "Welcome to Day 3"
|
msgid "Welcome to Day 3"
|
||||||
msgstr ""
|
msgstr "Chào mừng tới Ngày 3"
|
||||||
|
|
||||||
#: src/welcome-day-3.md
|
#: src/welcome-day-3.md
|
||||||
msgid "Today, we will cover:"
|
msgid "Today, we will cover:"
|
||||||
msgstr ""
|
msgstr "Chủ đề chúng ta sẽ học hôm nay là:"
|
||||||
|
|
||||||
#: src/welcome-day-3.md
|
#: src/welcome-day-3.md
|
||||||
msgid ""
|
msgid ""
|
||||||
"Memory management, lifetimes, and the borrow checker: how Rust ensures "
|
"Memory management, lifetimes, and the borrow checker: how Rust ensures "
|
||||||
"memory safety."
|
"memory safety."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Quản lý bộ nhớ, vòng đời (lifetimes), và quá trình kiểm mượn (the borrow "
|
||||||
|
"checker): cách mà Rust đảm bảo được tính an toàn bộ nhớ."
|
||||||
|
|
||||||
#: src/welcome-day-3.md
|
#: src/welcome-day-3.md
|
||||||
msgid "Smart pointers: standard library pointer types."
|
msgid "Smart pointers: standard library pointer types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Con trỏ thông minh (smart pointers): các kiểu con trỏ trong thư viện chuẩn."
|
||||||
|
|
||||||
#: src/welcome-day-3.md
|
#: src/welcome-day-3.md
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
# Please use a nightly rustfmt for these settings.
|
# Please use a nightly rustfmt for these settings.
|
||||||
|
unstable_features = true
|
||||||
imports_granularity = "module"
|
imports_granularity = "module"
|
||||||
wrap_comments = true
|
wrap_comments = true
|
||||||
|
|
||||||
|
@@ -108,6 +108,12 @@
|
|||||||
# Day 2: Afternoon
|
# Day 2: Afternoon
|
||||||
|
|
||||||
- [Welcome](welcome-day-2-afternoon.md)
|
- [Welcome](welcome-day-2-afternoon.md)
|
||||||
|
- [Closures](closures.md)
|
||||||
|
- [Closure Syntax](closures/syntax.md)
|
||||||
|
- [Capturing](closures/capturing.md)
|
||||||
|
- [Closure Traits](closures/traits.md)
|
||||||
|
- [Exercise: Log Filter](closures/exercise.md)
|
||||||
|
- [Solution](closures/solution.md)
|
||||||
- [Standard Library Types](std-types.md)
|
- [Standard Library Types](std-types.md)
|
||||||
- [Standard Library](std-types/std.md)
|
- [Standard Library](std-types/std.md)
|
||||||
- [Documentation](std-types/docs.md)
|
- [Documentation](std-types/docs.md)
|
||||||
@@ -118,12 +124,6 @@
|
|||||||
- [`HashMap`](std-types/hashmap.md)
|
- [`HashMap`](std-types/hashmap.md)
|
||||||
- [Exercise: Counter](std-types/exercise.md)
|
- [Exercise: Counter](std-types/exercise.md)
|
||||||
- [Solution](std-types/solution.md)
|
- [Solution](std-types/solution.md)
|
||||||
- [Closures](closures.md)
|
|
||||||
- [Closure Syntax](closures/syntax.md)
|
|
||||||
- [Capturing](closures/capturing.md)
|
|
||||||
- [Closure Traits](closures/traits.md)
|
|
||||||
- [Exercise: Log Filter](closures/exercise.md)
|
|
||||||
- [Solution](closures/solution.md)
|
|
||||||
- [Standard Library Traits](std-traits.md)
|
- [Standard Library Traits](std-traits.md)
|
||||||
- [Comparisons](std-traits/comparisons.md)
|
- [Comparisons](std-traits/comparisons.md)
|
||||||
- [Operators](std-traits/operators.md)
|
- [Operators](std-traits/operators.md)
|
||||||
@@ -442,6 +442,31 @@
|
|||||||
- [Drop Guards](idiomatic/leveraging-the-type-system/raii/drop_guards.md)
|
- [Drop Guards](idiomatic/leveraging-the-type-system/raii/drop_guards.md)
|
||||||
- [Drop Bomb](idiomatic/leveraging-the-type-system/raii/drop_bomb.md)
|
- [Drop Bomb](idiomatic/leveraging-the-type-system/raii/drop_bomb.md)
|
||||||
- [Scope Guard](idiomatic/leveraging-the-type-system/raii/scope_guard.md)
|
- [Scope Guard](idiomatic/leveraging-the-type-system/raii/scope_guard.md)
|
||||||
|
- [Typestate Pattern](idiomatic/leveraging-the-type-system/typestate-pattern.md)
|
||||||
|
- [Typestate Pattern Example](idiomatic/leveraging-the-type-system/typestate-pattern/typestate-example.md)
|
||||||
|
- [Beyond Simple Typestate](idiomatic/leveraging-the-type-system/typestate-pattern/typestate-advanced.md)
|
||||||
|
- [Typestate Pattern with Generics](idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics.md)
|
||||||
|
- [Serializer: implement Root](idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/root.md)
|
||||||
|
- [Serializer: implement Struct](idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/struct.md)
|
||||||
|
- [Serializer: implement Property](idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/property.md)
|
||||||
|
- [Serializer: Complete implementation](idiomatic/leveraging-the-type-system/typestate-pattern/typestate-generics/complete.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Unsafe
|
||||||
|
|
||||||
|
- [Welcome](unsafe-deep-dive/welcome.md)
|
||||||
|
- [Setup](unsafe-deep-dive/setup.md)
|
||||||
|
- [Motivations](unsafe-deep-dive/motivations.md)
|
||||||
|
- [Interoperability](unsafe-deep-dive/motivations/interop.md)
|
||||||
|
- [Data Structures](unsafe-deep-dive/motivations/data-structures.md)
|
||||||
|
- [Performance](unsafe-deep-dive/motivations/performance.md)
|
||||||
|
- [Foundations](unsafe-deep-dive/foundations.md)
|
||||||
|
- [What is unsafe?](unsafe-deep-dive/foundations/what-is-unsafe.md)
|
||||||
|
- [When is unsafe used?](unsafe-deep-dive/foundations/when-is-unsafe-used.md)
|
||||||
|
- [Data structures are safe](unsafe-deep-dive/foundations/data-structures-are-safe.md)
|
||||||
|
- [Actions might not be](unsafe-deep-dive/foundations/actions-might-not-be.md)
|
||||||
|
- [Less powerful than it seems](unsafe-deep-dive/foundations/less-powerful.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@@ -1,18 +1,16 @@
|
|||||||
# AIDL
|
# AIDL
|
||||||
|
|
||||||
The
|
Rust supports the
|
||||||
[Android Interface Definition Language
|
[Android Interface Definition Language (AIDL)](https://developer.android.com/guide/components/aidl):
|
||||||
(AIDL)](https://developer.android.com/guide/components/aidl) is supported in
|
|
||||||
Rust:
|
|
||||||
|
|
||||||
- Rust code can call existing AIDL servers,
|
- Rust code can call existing AIDL servers.
|
||||||
- You can create new AIDL servers in Rust.
|
- You can create new AIDL servers in Rust.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
- AIDL is what enables Android apps to interact with each other.
|
- AIDL enables Android apps to interact with each other.
|
||||||
|
|
||||||
- Since Rust is supported as a first-class citizen in this ecosystem, Rust
|
- Since Rust is a first-class citizen in this ecosystem, other processes on the
|
||||||
services can be called by any other process on the phone.
|
device can call Rust services.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
# Birthday Service Tutorial
|
# Birthday Service Tutorial
|
||||||
|
|
||||||
To illustrate how to use Rust with Binder, we're going to walk through the
|
To illustrate using Rust with Binder, we will create a Binder interface. Then,
|
||||||
process of creating a Binder interface. We're then going to both implement the
|
we'll implement the service and write a client that talks to it.
|
||||||
described service and write client code that talks to that service.
|
|
||||||
|
@@ -1,11 +1,10 @@
|
|||||||
// ANCHOR: libbirthdayservice
|
// ANCHOR: libbirthdayservice
|
||||||
rust_library {
|
rust_library {
|
||||||
name: "libbirthdayservice",
|
name: "libbirthdayservice",
|
||||||
srcs: ["src/lib.rs"],
|
|
||||||
crate_name: "birthdayservice",
|
crate_name: "birthdayservice",
|
||||||
|
srcs: ["src/lib.rs"],
|
||||||
rustlibs: [
|
rustlibs: [
|
||||||
"com.example.birthdayservice-rust",
|
"com.example.birthdayservice-rust",
|
||||||
"libbinder_rs",
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
// ANCHOR_END: libbirthdayservice
|
// ANCHOR_END: libbirthdayservice
|
||||||
@@ -17,7 +16,6 @@ rust_binary {
|
|||||||
srcs: ["src/server.rs"],
|
srcs: ["src/server.rs"],
|
||||||
rustlibs: [
|
rustlibs: [
|
||||||
"com.example.birthdayservice-rust",
|
"com.example.birthdayservice-rust",
|
||||||
"libbinder_rs",
|
|
||||||
"libbirthdayservice",
|
"libbirthdayservice",
|
||||||
],
|
],
|
||||||
prefer_rlib: true, // To avoid dynamic link error.
|
prefer_rlib: true, // To avoid dynamic link error.
|
||||||
@@ -31,7 +29,6 @@ rust_binary {
|
|||||||
srcs: ["src/client.rs"],
|
srcs: ["src/client.rs"],
|
||||||
rustlibs: [
|
rustlibs: [
|
||||||
"com.example.birthdayservice-rust",
|
"com.example.birthdayservice-rust",
|
||||||
"libbinder_rs",
|
|
||||||
],
|
],
|
||||||
prefer_rlib: true, // To avoid dynamic link error.
|
prefer_rlib: true, // To avoid dynamic link error.
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# Changing API
|
# Changing API
|
||||||
|
|
||||||
Let us extend the API with more functionality: we want to let clients specify a
|
Let's extend the API: we'll let clients specify a list of lines for the birthday
|
||||||
list of lines for the birthday card:
|
card:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
package com.example.birthdayservice;
|
package com.example.birthdayservice;
|
||||||
|
@@ -16,21 +16,21 @@ _birthday_service/Android.bp_:
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
The process for taking a user-defined service implementation (in this case the
|
The process for taking a user-defined service implementation (in this case, the
|
||||||
`BirthdayService` type, which implements the `IBirthdayService`) and starting it
|
`BirthdayService` type, which implements the `IBirthdayService`) and starting it
|
||||||
as a Binder service has multiple steps, and may appear more complicated than
|
as a Binder service has multiple steps. This may appear more complicated than
|
||||||
students are used to if they've used Binder from C++ or another language.
|
students are used to if they've used Binder from C++ or another language.
|
||||||
Explain to students why each step is necessary.
|
Explain to students why each step is necessary.
|
||||||
|
|
||||||
1. Create an instance of your service type (`BirthdayService`).
|
1. Create an instance of your service type (`BirthdayService`).
|
||||||
1. Wrap the service object in corresponding `Bn*` type (`BnBirthdayService` in
|
2. Wrap the service object in the corresponding `Bn*` type (`BnBirthdayService`
|
||||||
this case). This type is generated by Binder and provides the common Binder
|
in this case). This type is generated by Binder and provides common Binder
|
||||||
functionality that would be provided by the `BnBinder` base class in C++. We
|
functionality, similar to the `BnBinder` base class in C++. Since Rust
|
||||||
don't have inheritance in Rust, so instead we use composition, putting our
|
doesn't have inheritance, we use composition, putting our `BirthdayService`
|
||||||
`BirthdayService` within the generated `BnBinderService`.
|
within the generated `BnBinderService`.
|
||||||
1. Call `add_service`, giving it a service identifier and your service object
|
3. Call `add_service`, giving it a service identifier and your service object
|
||||||
(the `BnBirthdayService` object in the example).
|
(the `BnBirthdayService` object in the example).
|
||||||
1. Call `join_thread_pool` to add the current thread to Binder's thread pool and
|
4. Call `join_thread_pool` to add the current thread to Binder's thread pool and
|
||||||
start listening for connections.
|
start listening for connections.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -25,7 +25,7 @@ trait to talk to the service.
|
|||||||
<details>
|
<details>
|
||||||
|
|
||||||
- Point out how the generated function signature, specifically the argument and
|
- Point out how the generated function signature, specifically the argument and
|
||||||
return types, correspond the interface definition.
|
return types, correspond to the interface definition.
|
||||||
- `String` for an argument results in a different Rust type than `String` as a
|
- `String` for an argument results in a different Rust type than `String` as a
|
||||||
return type.
|
return type.
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ _birthday_service/Android.bp_:
|
|||||||
each of the segments is necessary.
|
each of the segments is necessary.
|
||||||
- Note that `wishHappyBirthday` and other AIDL IPC methods take `&self` (instead
|
- Note that `wishHappyBirthday` and other AIDL IPC methods take `&self` (instead
|
||||||
of `&mut self`).
|
of `&mut self`).
|
||||||
- This is necessary because binder responds to incoming requests on a thread
|
- This is necessary because Binder responds to incoming requests on a thread
|
||||||
pool, allowing for multiple requests to be processed in parallel. This
|
pool, allowing for multiple requests to be processed in parallel. This
|
||||||
requires that the service methods only get a shared reference to `self`.
|
requires that the service methods only get a shared reference to `self`.
|
||||||
- Any state that needs to be modified by the service will have to be put in
|
- Any state that needs to be modified by the service will have to be put in
|
||||||
@@ -33,6 +33,6 @@ _birthday_service/Android.bp_:
|
|||||||
- The correct approach for managing service state depends heavily on the
|
- The correct approach for managing service state depends heavily on the
|
||||||
details of your service.
|
details of your service.
|
||||||
- TODO: What does the `binder::Interface` trait do? Are there methods to
|
- TODO: What does the `binder::Interface` trait do? Are there methods to
|
||||||
override? Where source?
|
override? Where is the source?
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Array Types
|
# Array Types
|
||||||
|
|
||||||
The array types (`T[]`, `byte[]`, and `List<T>`) get translated to the
|
The array types (`T[]`, `byte[]`, and `List<T>`) are translated to the
|
||||||
appropriate Rust array type depending on how they are used in the function
|
appropriate Rust array type depending on how they are used in the function
|
||||||
signature:
|
signature:
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Build Rules
|
# Build Rules
|
||||||
|
|
||||||
The Android build system (Soong) supports Rust via a number of modules:
|
The Android build system (Soong) supports Rust through several modules:
|
||||||
|
|
||||||
| Module Type | Description |
|
| Module Type | Description |
|
||||||
| ----------------- | -------------------------------------------------------------------------------------------------- |
|
| ----------------- | -------------------------------------------------------------------------------------------------- |
|
||||||
@@ -17,13 +17,13 @@ We will look at `rust_binary` and `rust_library` next.
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
Additional items speaker may mention:
|
Additional items the speaker may mention:
|
||||||
|
|
||||||
- Cargo is not optimized for multi-language repos, and also downloads packages
|
- Cargo is not optimized for multi-language repositories, and also downloads
|
||||||
from the internet.
|
packages from the internet.
|
||||||
|
|
||||||
- For compliance and performance, Android must have crates in-tree. It must also
|
- For compliance and performance, Android must have crates in-tree. It must also
|
||||||
interop with C/C++/Java code. Soong fills that gap.
|
interoperate with C/C++/Java code. Soong fills that gap.
|
||||||
|
|
||||||
- Soong has many similarities to [Bazel](https://bazel.build/), which is the
|
- Soong has many similarities to [Bazel](https://bazel.build/), which is the
|
||||||
open-source variant of Blaze (used in google3).
|
open-source variant of Blaze (used in google3).
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Rust Binaries
|
# Rust Binaries
|
||||||
|
|
||||||
Let us start with a simple application. At the root of an AOSP checkout, create
|
Let's start with a simple application. At the root of an AOSP checkout, create
|
||||||
the following files:
|
the following files:
|
||||||
|
|
||||||
_hello_rust/Android.bp_:
|
_hello_rust/Android.bp_:
|
||||||
@@ -33,7 +33,7 @@ Hello from Rust!
|
|||||||
that all modules have documentation. Try removing it and see what error you
|
that all modules have documentation. Try removing it and see what error you
|
||||||
get.
|
get.
|
||||||
|
|
||||||
- Stress that the Rust build rules look like the other Soong rules. This is on
|
- Stress that the Rust build rules look like the other Soong rules. This is by
|
||||||
purpose to make it as easy to use Rust as C++ or Java.
|
design, to make using Rust as easy as C++ or Java.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -6,8 +6,8 @@ that you can:
|
|||||||
- Call Rust functions from other languages.
|
- Call Rust functions from other languages.
|
||||||
- Call functions written in other languages from Rust.
|
- Call functions written in other languages from Rust.
|
||||||
|
|
||||||
When you call functions in a foreign language we say that you're using a
|
When you call functions in a foreign language, you're using a _foreign function
|
||||||
_foreign function interface_, also known as FFI.
|
interface_, also known as FFI.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
# With C++
|
# With C++
|
||||||
|
|
||||||
The [CXX crate][1] makes it possible to do safe interoperability between Rust
|
The [CXX crate][1] enables safe interoperability between Rust and C++.
|
||||||
and C++.
|
|
||||||
|
|
||||||
The overall approach looks like this:
|
The overall approach looks like this:
|
||||||
|
|
||||||
|
@@ -30,9 +30,9 @@ We will look at better options next.
|
|||||||
- The [`"C"` part][extern-abi] of the `extern` block tells Rust that `abs` can
|
- The [`"C"` part][extern-abi] of the `extern` block tells Rust that `abs` can
|
||||||
be called using the C [ABI] (application binary interface).
|
be called using the C [ABI] (application binary interface).
|
||||||
|
|
||||||
- The `safe fn abs` part tells that Rust that `abs` is a safe function. By
|
- The `safe fn abs` part tells Rust that `abs` is a safe function. By default,
|
||||||
default, extern functions are considered unsafe, but since `abs(x)` is valid
|
extern functions are unsafe, but since `abs(x)` can't trigger undefined
|
||||||
for any `x`, we can declare it safe.
|
behavior with any `x`, we can declare it safe.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@@ -25,6 +25,6 @@ fn main() {
|
|||||||
// remains valid. `print_card` doesn't store either pointer to use later
|
// remains valid. `print_card` doesn't store either pointer to use later
|
||||||
// after it returns.
|
// after it returns.
|
||||||
unsafe {
|
unsafe {
|
||||||
print_card(&card as *const card);
|
print_card(&card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
# A better UART driver
|
# A better UART driver
|
||||||
|
|
||||||
The PL011 actually has [a bunch more registers][1], and adding offsets to
|
The PL011 actually has [more registers][1], and adding offsets to construct
|
||||||
construct pointers to access them is error-prone and hard to read. Plus, some of
|
pointers to access them is error-prone and hard to read. Additionally, some of
|
||||||
them are bit fields which would be nice to access in a structured way.
|
them are bit fields, which would be nice to access in a structured way.
|
||||||
|
|
||||||
| Offset | Register name | Width |
|
| Offset | Register name | Width |
|
||||||
| ------ | ------------- | ----- |
|
| ------ | ------------- | ----- |
|
||||||
@@ -23,7 +23,7 @@ them are bit fields which would be nice to access in a structured way.
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
- There are also some ID registers which have been omitted for brevity.
|
- There are also some ID registers that have been omitted for brevity.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# Getting Ready to Rust
|
# Getting Ready to Rust
|
||||||
|
|
||||||
Before we can start running Rust code, we need to do some initialisation.
|
Before we can start running Rust code, we need to do some initialization.
|
||||||
|
|
||||||
```armasm
|
```armasm
|
||||||
{{#include examples/src/entry.S:entry}}
|
{{#include examples/src/entry.S:entry}}
|
||||||
@@ -12,21 +12,21 @@ This code is in `src/bare-metal/aps/examples/src/entry.S`. It's not necessary to
|
|||||||
understand this in detail -- the takeaway is that typically some low-level setup
|
understand this in detail -- the takeaway is that typically some low-level setup
|
||||||
is needed to meet Rust's expectations of the system.
|
is needed to meet Rust's expectations of the system.
|
||||||
|
|
||||||
- This is the same as it would be for C: initialising the processor state,
|
- This is the same as it would be for C: initializing the processor state,
|
||||||
zeroing the BSS, and setting up the stack pointer.
|
zeroing the BSS, and setting up the stack pointer.
|
||||||
- The BSS (block starting symbol, for historical reasons) is the part of the
|
- The BSS (block starting symbol, for historical reasons) is the part of the
|
||||||
object file which containing statically allocated variables which are
|
object file that contains statically allocated variables that are
|
||||||
initialised to zero. They are omitted from the image, to avoid wasting space
|
initialized to zero. They are omitted from the image, to avoid wasting space
|
||||||
on zeroes. The compiler assumes that the loader will take care of zeroing
|
on zeroes. The compiler assumes that the loader will take care of zeroing
|
||||||
them.
|
them.
|
||||||
- The BSS may already be zeroed, depending on how memory is initialised and the
|
- The BSS may already be zeroed, depending on how memory is initialized and the
|
||||||
image is loaded, but we zero it to be sure.
|
image is loaded, but we zero it to be sure.
|
||||||
- We need to enable the MMU and cache before reading or writing any memory. If
|
- We need to enable the MMU and cache before reading or writing any memory. If
|
||||||
we don't:
|
we don't:
|
||||||
- Unaligned accesses will fault. We build the Rust code for the
|
- Unaligned accesses will fault. We build the Rust code for the
|
||||||
`aarch64-unknown-none` target which sets `+strict-align` to prevent the
|
`aarch64-unknown-none` target that sets `+strict-align` to prevent the
|
||||||
compiler generating unaligned accesses, so it should be fine in this case,
|
compiler from generating unaligned accesses, so it should be fine in this
|
||||||
but this is not necessarily the case in general.
|
case, but this is not necessarily the case in general.
|
||||||
- If it were running in a VM, this can lead to cache coherency issues. The
|
- If it were running in a VM, this can lead to cache coherency issues. The
|
||||||
problem is that the VM is accessing memory directly with the cache disabled,
|
problem is that the VM is accessing memory directly with the cache disabled,
|
||||||
while the host has cacheable aliases to the same memory. Even if the host
|
while the host has cacheable aliases to the same memory. Even if the host
|
||||||
@@ -34,14 +34,14 @@ is needed to meet Rust's expectations of the system.
|
|||||||
fills, and then changes from one or the other will get lost when the cache
|
fills, and then changes from one or the other will get lost when the cache
|
||||||
is cleaned or the VM enables the cache. (Cache is keyed by physical address,
|
is cleaned or the VM enables the cache. (Cache is keyed by physical address,
|
||||||
not VA or IPA.)
|
not VA or IPA.)
|
||||||
- For simplicity, we just use a hardcoded pagetable (see `idmap.S`) which
|
- For simplicity, we just use a hardcoded pagetable (see `idmap.S`) that
|
||||||
identity maps the first 1 GiB of address space for devices, the next 1 GiB for
|
identity maps the first 1 GiB of address space for devices, the next 1 GiB for
|
||||||
DRAM, and another 1 GiB higher up for more devices. This matches the memory
|
DRAM, and another 1 GiB higher up for more devices. This matches the memory
|
||||||
layout that QEMU uses.
|
layout that QEMU uses.
|
||||||
- We also set up the exception vector (`vbar_el1`), which we'll see more about
|
- We also set up the exception vector (`vbar_el1`), which we'll see more about
|
||||||
later.
|
later.
|
||||||
- All examples this afternoon assume we will be running at exception level 1
|
- All examples this afternoon assume we will be running at exception level 1
|
||||||
(EL1). If you need to run at a different exception level you'll need to modify
|
(EL1). If you need to run at a different exception level, you'll need to
|
||||||
`entry.S` accordingly.
|
modify `entry.S` accordingly.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
12
src/bare-metal/aps/examples/Cargo.lock
generated
12
src/bare-metal/aps/examples/Cargo.lock
generated
@@ -4,9 +4,9 @@ version = 4
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aarch64-paging"
|
name = "aarch64-paging"
|
||||||
version = "0.9.1"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3b8f725e9256b2fac2d25e013e22a6a391b8c07e23c4c5eac6e037a78a28801"
|
checksum = "1f02b5bfa3a481fdade5948a994ce93aa6c76f67fc19f3a9b270565cf7dfc657"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -38,9 +38,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arm-pl011-uart"
|
name = "arm-pl011-uart"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff5b0f1e39ec186e409c6fd80bbb83aa00622ca71c9c0561b5571df3b5f5391f"
|
checksum = "8797e113733a36b5fa906c81aefc126d255b88dd1c10a737749aa22ec7736b6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"embedded-hal-nb",
|
"embedded-hal-nb",
|
||||||
@@ -58,9 +58,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.1"
|
version = "2.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-hal"
|
name = "embedded-hal"
|
||||||
|
@@ -7,10 +7,10 @@ edition = "2024"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aarch64-paging = { version = "0.9.1", default-features = false }
|
aarch64-paging = { version = "0.10.0", default-features = false }
|
||||||
aarch64-rt = "0.2.2"
|
aarch64-rt = "0.2.2"
|
||||||
arm-pl011-uart = "0.3.1"
|
arm-pl011-uart = "0.3.2"
|
||||||
bitflags = "2.9.1"
|
bitflags = "2.9.3"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
safe-mmio = "0.2.5"
|
safe-mmio = "0.2.5"
|
||||||
smccc = "0.2.0"
|
smccc = "0.2.0"
|
||||||
|
@@ -16,7 +16,7 @@ for all these functions.)
|
|||||||
- PSCI is the Arm Power State Coordination Interface, a standard set of
|
- PSCI is the Arm Power State Coordination Interface, a standard set of
|
||||||
functions to manage system and CPU power states, among other things. It is
|
functions to manage system and CPU power states, among other things. It is
|
||||||
implemented by EL3 firmware and hypervisors on many systems.
|
implemented by EL3 firmware and hypervisors on many systems.
|
||||||
- The `0 => _` syntax means initialise the register to 0 before running the
|
- The `0 => _` syntax means initialize the register to 0 before running the
|
||||||
inline assembly code, and ignore its contents afterwards. We need to use
|
inline assembly code, and ignore its contents afterwards. We need to use
|
||||||
`inout` rather than `in` because the call could potentially clobber the
|
`inout` rather than `in` because the call could potentially clobber the
|
||||||
contents of the registers.
|
contents of the registers.
|
||||||
@@ -24,7 +24,7 @@ for all these functions.)
|
|||||||
because it is called from our entry point in `entry.S`.
|
because it is called from our entry point in `entry.S`.
|
||||||
- Just `#[no_mangle]` would be sufficient but
|
- Just `#[no_mangle]` would be sufficient but
|
||||||
[RFC3325](https://rust-lang.github.io/rfcs/3325-unsafe-attributes.html) uses
|
[RFC3325](https://rust-lang.github.io/rfcs/3325-unsafe-attributes.html) uses
|
||||||
this notation to draw reviewer attention to attributes which might cause
|
this notation to draw reviewer attention to attributes that might cause
|
||||||
undefined behavior if used incorrectly.
|
undefined behavior if used incorrectly.
|
||||||
- `_x0`–`_x3` are the values of registers `x0`–`x3`, which are conventionally
|
- `_x0`–`_x3` are the values of registers `x0`–`x3`, which are conventionally
|
||||||
used by the bootloader to pass things like a pointer to the device tree.
|
used by the bootloader to pass things like a pointer to the device tree.
|
||||||
|
@@ -9,7 +9,7 @@ We can do this by implementing the `Log` trait.
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
- The first unwrap in `log` will succeed because we initialise `LOGGER` before
|
- The first unwrap in `log` will succeed because we initialize `LOGGER` before
|
||||||
calling `set_logger`. The second will succeed because `Uart::write_str` always
|
calling `set_logger`. The second will succeed because `Uart::write_str` always
|
||||||
returns `Ok`.
|
returns `Ok`.
|
||||||
|
|
||||||
|
@@ -28,7 +28,7 @@ unsafe {
|
|||||||
compiler may assume that the value read is the same as the value just
|
compiler may assume that the value read is the same as the value just
|
||||||
written, and not bother actually reading memory.
|
written, and not bother actually reading memory.
|
||||||
- Some existing crates for volatile access to hardware do hold references, but
|
- Some existing crates for volatile access to hardware do hold references, but
|
||||||
this is unsound. Whenever a reference exist, the compiler may choose to
|
this is unsound. Whenever a reference exists, the compiler may choose to
|
||||||
dereference it.
|
dereference it.
|
||||||
- Use `&raw` to get struct field pointers from a pointer to the struct.
|
- Use `&raw` to get struct field pointers from a pointer to the struct.
|
||||||
- For compatibility with old versions of Rust you can use the [`addr_of!`] macro
|
- For compatibility with old versions of Rust you can use the [`addr_of!`] macro
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
- Supports x86, aarch64 and RISC-V.
|
- Supports x86, aarch64 and RISC-V.
|
||||||
- Relies on LinuxBoot rather than having many drivers itself.
|
- Relies on LinuxBoot rather than having many drivers itself.
|
||||||
- [Rust RaspberryPi OS tutorial](https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials)
|
- [Rust RaspberryPi OS tutorial](https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials)
|
||||||
- Initialisation, UART driver, simple bootloader, JTAG, exception levels,
|
- Initialization, UART driver, simple bootloader, JTAG, exception levels,
|
||||||
exception handling, page tables.
|
exception handling, page tables.
|
||||||
- Some dodginess around cache maintenance and initialisation in Rust, not
|
- Some caveats around cache maintenance and initialization in Rust, not
|
||||||
necessarily a good example to copy for production code.
|
necessarily a good example to copy for production code.
|
||||||
- [`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)
|
- [`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)
|
||||||
- Static analysis to determine maximum stack usage.
|
- Static analysis to determine maximum stack usage.
|
||||||
|
@@ -17,14 +17,14 @@ Now let's use the new `Registers` struct in our driver.
|
|||||||
- These MMIO accesses are generally a wrapper around `read_volatile` and
|
- These MMIO accesses are generally a wrapper around `read_volatile` and
|
||||||
`write_volatile`, though on aarch64 they are instead implemented in assembly
|
`write_volatile`, though on aarch64 they are instead implemented in assembly
|
||||||
to work around a bug where the compiler can emit instructions that prevent
|
to work around a bug where the compiler can emit instructions that prevent
|
||||||
MMIO virtualisation.
|
MMIO virtualization.
|
||||||
- The `field!` and `field_shared!` macros internally use `&raw mut` and
|
- The `field!` and `field_shared!` macros internally use `&raw mut` and
|
||||||
`&raw const` to get pointers to individual fields without creating an
|
`&raw const` to get pointers to individual fields without creating an
|
||||||
intermediate reference, which would be unsound.
|
intermediate reference, which would be unsound.
|
||||||
- `field!` needs a mutable reference to a `UniqueMmioPointer`, and returns a
|
- `field!` needs a mutable reference to a `UniqueMmioPointer`, and returns a
|
||||||
`UniqueMmioPointer` which allows reads with side effects and writes.
|
`UniqueMmioPointer` that allows reads with side effects and writes.
|
||||||
- `field_shared!` works with a shared reference to either a `UniqueMmioPointer`
|
- `field_shared!` works with a shared reference to either a `UniqueMmioPointer`
|
||||||
or a `SharedMmioPointer`. It returns a `SharedMmioPointer` which only allows
|
or a `SharedMmioPointer`. It returns a `SharedMmioPointer` that only allows
|
||||||
pure reads.
|
pure reads.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# safe-mmio
|
# safe-mmio
|
||||||
|
|
||||||
The [`safe-mmio`] crate provides types to wrap registers which can be read or
|
The [`safe-mmio`] crate provides types to wrap registers that can be read or
|
||||||
written safely.
|
written safely.
|
||||||
|
|
||||||
| | Can't read | Read has no side-effects | Read has side-effects |
|
| | Can't read | Read has no side-effects | Read has side-effects |
|
||||||
@@ -23,7 +23,7 @@ written safely.
|
|||||||
operations; we recommend the `safe-mmio` crate.
|
operations; we recommend the `safe-mmio` crate.
|
||||||
- The difference between `ReadPure` or `ReadOnly` (and likewise between
|
- The difference between `ReadPure` or `ReadOnly` (and likewise between
|
||||||
`ReadPureWrite` and `ReadWrite`) is whether reading a register can have
|
`ReadPureWrite` and `ReadWrite`) is whether reading a register can have
|
||||||
side-effects which change the state of the device. E.g. reading the data
|
side-effects that change the state of the device, e.g., reading the data
|
||||||
register pops a byte from the receive FIFO. `ReadPure` means that reads have
|
register pops a byte from the receive FIFO. `ReadPure` means that reads have
|
||||||
no side-effects, they are purely reading data.
|
no side-effects, they are purely reading data.
|
||||||
|
|
||||||
|
@@ -12,7 +12,7 @@ for convenience.
|
|||||||
<details>
|
<details>
|
||||||
|
|
||||||
- In this case the board support crate is just providing more useful names, and
|
- In this case the board support crate is just providing more useful names, and
|
||||||
a bit of initialisation.
|
a bit of initialization.
|
||||||
- The crate may also include drivers for some on-board devices outside of the
|
- The crate may also include drivers for some on-board devices outside of the
|
||||||
microcontroller itself.
|
microcontroller itself.
|
||||||
- `microbit-v2` includes a simple driver for the LED matrix.
|
- `microbit-v2` includes a simple driver for the LED matrix.
|
||||||
|
@@ -8,7 +8,7 @@ microcontroller peripherals:
|
|||||||
- Delay timers
|
- Delay timers
|
||||||
- I2C and SPI buses and devices
|
- I2C and SPI buses and devices
|
||||||
|
|
||||||
Similar traits for byte streams (e.g. UARTs), CAN buses and RNGs and broken out
|
Similar traits for byte streams (e.g. UARTs), CAN buses and RNGs are broken out
|
||||||
into [`embedded-io`], [`embedded-can`] and [`rand_core`] respectively.
|
into [`embedded-io`], [`embedded-can`] and [`rand_core`] respectively.
|
||||||
|
|
||||||
Other crates then implement [drivers] in terms of these traits, e.g. an
|
Other crates then implement [drivers] in terms of these traits, e.g. an
|
||||||
@@ -16,8 +16,8 @@ accelerometer driver might need an I2C or SPI device instance.
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
- The traits cover using the peripherals but not initialising or configuring
|
- The traits cover using the peripherals but not initializing or configuring
|
||||||
them, as initialisation and configuration is usually highly platform-specific.
|
them, as initialization and configuration is usually highly platform-specific.
|
||||||
- There are implementations for many microcontrollers, as well as other
|
- There are implementations for many microcontrollers, as well as other
|
||||||
platforms such as Linux on Raspberry Pi.
|
platforms such as Linux on Raspberry Pi.
|
||||||
- [`embedded-hal-async`] provides async versions of the traits.
|
- [`embedded-hal-async`] provides async versions of the traits.
|
||||||
|
@@ -11,12 +11,11 @@ wrappers for memory-mapped peripherals from
|
|||||||
<details>
|
<details>
|
||||||
|
|
||||||
- SVD (System View Description) files are XML files typically provided by
|
- SVD (System View Description) files are XML files typically provided by
|
||||||
silicon vendors which describe the memory map of the device.
|
silicon vendors that describe the memory map of the device.
|
||||||
- They are organised by peripheral, register, field and value, with names,
|
- They are organized by peripheral, register, field and value, with names,
|
||||||
descriptions, addresses and so on.
|
descriptions, addresses and so on.
|
||||||
- SVD files are often buggy and incomplete, so there are various projects
|
- SVD files are often buggy and incomplete, so there are various projects that
|
||||||
which patch the mistakes, add missing details, and publish the generated
|
patch the mistakes, add missing details, and publish the generated crates.
|
||||||
crates.
|
|
||||||
- `cortex-m-rt` provides the vector table, among other things.
|
- `cortex-m-rt` provides the vector table, among other things.
|
||||||
- If you `cargo install cargo-binutils` then you can run
|
- If you `cargo install cargo-binutils` then you can run
|
||||||
`cargo objdump --bin pac -- -d --no-show-raw-insn` to see the resulting
|
`cargo objdump --bin pac -- -d --no-show-raw-insn` to see the resulting
|
||||||
|
@@ -21,7 +21,7 @@ in your project directory.
|
|||||||
a range from SEGGER.
|
a range from SEGGER.
|
||||||
- The Debug Access Port is usually either a 5-pin JTAG interface or 2-pin Serial
|
- The Debug Access Port is usually either a 5-pin JTAG interface or 2-pin Serial
|
||||||
Wire Debug.
|
Wire Debug.
|
||||||
- probe-rs is a library which you can integrate into your own tools if you want
|
- probe-rs is a library that you can integrate into your own tools if you want
|
||||||
to.
|
to.
|
||||||
- The
|
- The
|
||||||
[Microsoft Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/)
|
[Microsoft Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/)
|
||||||
@@ -29,6 +29,6 @@ in your project directory.
|
|||||||
microcontroller.
|
microcontroller.
|
||||||
- cargo-embed is a binary built using the probe-rs library.
|
- cargo-embed is a binary built using the probe-rs library.
|
||||||
- RTT (Real Time Transfers) is a mechanism to transfer data between the debug
|
- RTT (Real Time Transfers) is a mechanism to transfer data between the debug
|
||||||
host and the target through a number of ringbuffers.
|
host and the target through a number of ring buffers.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -7,12 +7,12 @@
|
|||||||
<details>
|
<details>
|
||||||
|
|
||||||
- Pins don't implement `Copy` or `Clone`, so only one instance of each can
|
- Pins don't implement `Copy` or `Clone`, so only one instance of each can
|
||||||
exist. Once a pin is moved out of the port struct nobody else can take it.
|
exist. Once a pin is moved out of the port struct, nobody else can take it.
|
||||||
- Changing the configuration of a pin consumes the old pin instance, so you
|
- Changing the configuration of a pin consumes the old pin instance, so you
|
||||||
can’t keep use the old instance afterwards.
|
can't use the old instance afterwards.
|
||||||
- The type of a value indicates the state that it is in: e.g. in this case, the
|
- The type of a value indicates the state it is in: e.g., in this case, the
|
||||||
configuration state of a GPIO pin. This encodes the state machine into the
|
configuration state of a GPIO pin. This encodes the state machine into the
|
||||||
type system, and ensures that you don't try to use a pin in a certain way
|
type system and ensures that you don't try to use a pin in a certain way
|
||||||
without properly configuring it first. Illegal state transitions are caught at
|
without properly configuring it first. Illegal state transitions are caught at
|
||||||
compile time.
|
compile time.
|
||||||
- You can call `is_high` on an input pin and `set_high` on an output pin, but
|
- You can call `is_high` on an input pin and `set_high` on an output pin, but
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Useful crates
|
# Useful crates
|
||||||
|
|
||||||
We'll look at a few crates which solve some common problems in bare-metal
|
We'll look at a few crates that solve some common problems in bare-metal
|
||||||
programming.
|
programming.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
# `buddy_system_allocator`
|
# `buddy_system_allocator`
|
||||||
|
|
||||||
[`buddy_system_allocator`][1] is a crate implementing a basic buddy system
|
[`buddy_system_allocator`][1] is a crate that implements a basic buddy system
|
||||||
allocator. It can be used both to implement [`GlobalAlloc`][3] (using
|
allocator. It can be used both to implement [`GlobalAlloc`][3] (using
|
||||||
[`LockedHeap`][2]) so you can use the standard `alloc` crate (as we saw
|
[`LockedHeap`][2]) so you can use the standard `alloc` crate (as we saw
|
||||||
[before][4]), or for allocating other address space (using
|
[before][4]), or for allocating other address space (using
|
||||||
|
@@ -25,8 +25,8 @@ fn main() {
|
|||||||
|
|
||||||
- Be careful to avoid deadlock if you take locks in interrupt handlers.
|
- Be careful to avoid deadlock if you take locks in interrupt handlers.
|
||||||
- `spin` also has a ticket lock mutex implementation; equivalents of `RwLock`,
|
- `spin` also has a ticket lock mutex implementation; equivalents of `RwLock`,
|
||||||
`Barrier` and `Once` from `std::sync`; and `Lazy` for lazy initialisation.
|
`Barrier` and `Once` from `std::sync`; and `Lazy` for lazy initialization.
|
||||||
- The [`once_cell`][2] crate also has some useful types for late initialisation
|
- The [`once_cell`][2] crate also has some useful types for late initialization
|
||||||
with a slightly different approach to `spin::once::Once`.
|
with a slightly different approach to `spin::once::Once`.
|
||||||
- The Rust Playground includes `spin`, so this example will run fine inline.
|
- The Rust Playground includes `spin`, so this example will run fine inline.
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
# `tinyvec`
|
# `tinyvec`
|
||||||
|
|
||||||
Sometimes you want something which can be resized like a `Vec`, but without heap
|
Sometimes you want something that can be resized like a `Vec`, but without heap
|
||||||
allocation. [`tinyvec`][1] provides this: a vector backed by an array or slice,
|
allocation. [`tinyvec`][1] provides this: a vector backed by an array or slice,
|
||||||
which could be statically allocated or on the stack, which keeps track of how
|
which could be statically allocated or on the stack, that keeps track of how
|
||||||
many elements are used and panics if you try to use more than are allocated.
|
many elements are used and panics if you try to use more than are allocated.
|
||||||
|
|
||||||
<!-- mdbook-xgettext: skip -->
|
<!-- mdbook-xgettext: skip -->
|
||||||
@@ -23,7 +23,7 @@ fn main() {
|
|||||||
<details>
|
<details>
|
||||||
|
|
||||||
- `tinyvec` requires that the element type implement `Default` for
|
- `tinyvec` requires that the element type implement `Default` for
|
||||||
initialisation.
|
initialization.
|
||||||
- The Rust Playground includes `tinyvec`, so this example will run fine inline.
|
- The Rust Playground includes `tinyvec`, so this example will run fine inline.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -65,9 +65,9 @@ fn main() {
|
|||||||
|
|
||||||
## More to Explore
|
## More to Explore
|
||||||
|
|
||||||
- Technically multiple mutable references to a piece of data can exist at the
|
- Technically, multiple mutable references to a piece of data can exist at the
|
||||||
same time via re-borrowing. This is what allows you to pass a mutable
|
same time via re-borrowing. This is what allows you to pass a mutable
|
||||||
reference into a function without invaliding the original reference.
|
reference into a function without invalidating the original reference.
|
||||||
[This playground example][1] demonstrates that behavior.
|
[This playground example][1] demonstrates that behavior.
|
||||||
- Rust uses the exclusive reference constraint to ensure that data races do not
|
- Rust uses the exclusive reference constraint to ensure that data races do not
|
||||||
occur in multi-threaded code, since only one thread can have mutable access to
|
occur in multi-threaded code, since only one thread can have mutable access to
|
||||||
|
@@ -12,7 +12,7 @@ fits into this training.
|
|||||||
|
|
||||||
This will give you the Cargo build tool (`cargo`) and the Rust compiler
|
This will give you the Cargo build tool (`cargo`) and the Rust compiler
|
||||||
(`rustc`). You will also get `rustup`, a command line utility that you can use
|
(`rustc`). You will also get `rustup`, a command line utility that you can use
|
||||||
to install to different compiler versions.
|
to install different compiler versions.
|
||||||
|
|
||||||
After installing Rust, you should configure your editor or IDE to work with
|
After installing Rust, you should configure your editor or IDE to work with
|
||||||
Rust. Most editors do this by talking to [rust-analyzer], which provides
|
Rust. Most editors do this by talking to [rust-analyzer], which provides
|
||||||
|
@@ -5,7 +5,7 @@ which can be executed through your browser. This makes the setup much easier and
|
|||||||
ensures a consistent experience for everyone.
|
ensures a consistent experience for everyone.
|
||||||
|
|
||||||
Installing Cargo is still encouraged: it will make it easier for you to do the
|
Installing Cargo is still encouraged: it will make it easier for you to do the
|
||||||
exercises. On the last day, we will do a larger exercise which shows you how to
|
exercises. On the last day, we will do a larger exercise that shows you how to
|
||||||
work with dependencies and for that you need Cargo.
|
work with dependencies and for that you need Cargo.
|
||||||
|
|
||||||
The code blocks in this course are fully interactive:
|
The code blocks in this course are fully interactive:
|
||||||
@@ -16,8 +16,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can use <kbd>Ctrl + Enter</kbd> to execute the code when focus is in the
|
You can use <kbd>Ctrl</kbd> + <kbd>Enter</kbd> to execute the code when focus is
|
||||||
text box.
|
in the text box.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
|
@@ -38,7 +38,7 @@ examples in this training:
|
|||||||
Hello, world!
|
Hello, world!
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Replace the boiler-plate code in `src/main.rs` with your own code. For
|
4. Replace the boilerplate code in `src/main.rs` with your own code. For
|
||||||
example, using the example on the previous page, make `src/main.rs` look like
|
example, using the example on the previous page, make `src/main.rs` look like
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The Rust ecosystem consists of a number of tools, of which the main ones are:
|
The Rust ecosystem consists of a number of tools, of which the main ones are:
|
||||||
|
|
||||||
- `rustc`: the Rust compiler which turns `.rs` files into binaries and other
|
- `rustc`: the Rust compiler that turns `.rs` files into binaries and other
|
||||||
intermediate formats.
|
intermediate formats.
|
||||||
|
|
||||||
- `cargo`: the Rust dependency manager and build tool. Cargo knows how to
|
- `cargo`: the Rust dependency manager and build tool. Cargo knows how to
|
||||||
|
@@ -9,6 +9,6 @@ Rust is supported for third-party libraries in Chromium, with first-party glue
|
|||||||
code to connect between Rust and existing Chromium C++ code.
|
code to connect between Rust and existing Chromium C++ code.
|
||||||
|
|
||||||
> Today, we'll call into Rust to do something silly with strings. If you've got
|
> Today, we'll call into Rust to do something silly with strings. If you've got
|
||||||
> a corner of the code where you're displaying a UTF8 string to the user, feel
|
> a corner of the code where you're displaying a UTF-8 string to the user, feel
|
||||||
> free to follow this recipe in your part of the codebase instead of the exact
|
> free to follow this recipe in your part of the codebase instead of the exact
|
||||||
> part we talk about.
|
> part we talk about.
|
||||||
|
@@ -11,7 +11,7 @@ Please also add an `OWNERS` file in the latter location.
|
|||||||
You should land all this, along with your `Cargo.toml` and `gnrt_config.toml`
|
You should land all this, along with your `Cargo.toml` and `gnrt_config.toml`
|
||||||
changes, into the Chromium repo.
|
changes, into the Chromium repo.
|
||||||
|
|
||||||
**Important**: you need to use `git add -f` because otherwise `.gitignore` files
|
**Important:** you need to use `git add -f` because otherwise `.gitignore` files
|
||||||
may result in some files being skipped.
|
may result in some files being skipped.
|
||||||
|
|
||||||
As you do so, you might find presubmit checks fail because of non-inclusive
|
As you do so, you might find presubmit checks fail because of non-inclusive
|
||||||
|
@@ -60,8 +60,8 @@ may offer an advantage"):
|
|||||||
|
|
||||||
- Perhaps surprisingly, Rust is becoming increasingly popular in the industry
|
- Perhaps surprisingly, Rust is becoming increasingly popular in the industry
|
||||||
for writing command line tools. The breadth and ergonomics of libraries is
|
for writing command line tools. The breadth and ergonomics of libraries is
|
||||||
comparable to Python, while being more robust (thanks to the rich
|
comparable to Python, while being more robust (thanks to the rich type
|
||||||
typesystem) and running faster (as a compiled, rather than interpreted
|
system) and running faster (as a compiled, rather than interpreted
|
||||||
language).
|
language).
|
||||||
- Participating in the Rust ecosystem requires using standard Rust tools like
|
- Participating in the Rust ecosystem requires using standard Rust tools like
|
||||||
Cargo. Libraries that want to get external contributions, and want to be
|
Cargo. Libraries that want to get external contributions, and want to be
|
||||||
|
@@ -40,7 +40,7 @@ following benefits:
|
|||||||
memory-safety risks.
|
memory-safety risks.
|
||||||
- `rust::String` and `CxxString` types understand and maintain differences in
|
- `rust::String` and `CxxString` types understand and maintain differences in
|
||||||
string representation across the languages (e.g. `rust::String::lossy` can
|
string representation across the languages (e.g. `rust::String::lossy` can
|
||||||
build a Rust string from non-UTF8 input and `rust::String::c_str` can
|
build a Rust string from non-UTF-8 input and `rust::String::c_str` can
|
||||||
NUL-terminate a string).
|
NUL-terminate a string).
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -20,7 +20,7 @@ Point out:
|
|||||||
- Calls from C++ to Rust, and Rust types (in the top part)
|
- Calls from C++ to Rust, and Rust types (in the top part)
|
||||||
- Calls from Rust to C++, and C++ types (in the bottom part)
|
- Calls from Rust to C++, and C++ types (in the bottom part)
|
||||||
|
|
||||||
**Common misconception**: It _looks_ like a C++ header is being parsed by Rust,
|
**Common misconception:** It _looks_ like a C++ header is being parsed by Rust,
|
||||||
but this is misleading. This header is never interpreted by Rust, but simply
|
but this is misleading. This header is never interpreted by Rust, but simply
|
||||||
`#include`d in the generated C++ code for the benefit of C++ compilers.
|
`#include`d in the generated C++ code for the benefit of C++ compilers.
|
||||||
|
|
||||||
|
@@ -22,7 +22,7 @@ It's also recommended that you have Visual Studio code installed.
|
|||||||
|
|
||||||
# About the exercises
|
# About the exercises
|
||||||
|
|
||||||
This part of the course has a series of exercises which build on each other.
|
This part of the course has a series of exercises that build on each other.
|
||||||
We'll be doing them spread throughout the course instead of just at the end. If
|
We'll be doing them spread throughout the course instead of just at the end. If
|
||||||
you don't have time to complete a certain part, don't worry: you can catch up in
|
you don't have time to complete a certain part, don't worry: you can catch up in
|
||||||
the next slot.
|
the next slot.
|
||||||
|
@@ -44,9 +44,9 @@ used:
|
|||||||
the C++ and the Rust implementation (parameterizing the tests so they enable
|
the C++ and the Rust implementation (parameterizing the tests so they enable
|
||||||
or disable Rust using a `ScopedFeatureList`).
|
or disable Rust using a `ScopedFeatureList`).
|
||||||
|
|
||||||
- Hypothetical/WIP PNG integration may need to implement memory-safe
|
- Hypothetical/WIP PNG integration may need memory-safe implementations of pixel
|
||||||
implementation of pixel transformations that are provided by `libpng` but
|
transformations that are provided by `libpng` but missing in the `png` crate -
|
||||||
missing in the `png` crate - e.g. RGBA => BGRA, or gamma correction. Such
|
e.g. RGBA => BGRA, or gamma correction. Such functionality may benefit from
|
||||||
functionality may benefit from separate tests authored in Rust.
|
separate tests authored in Rust.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -4,8 +4,8 @@ minutes: 10
|
|||||||
|
|
||||||
# Exercise: Log Filter
|
# Exercise: Log Filter
|
||||||
|
|
||||||
Building on the generic logger from this morning, implement a `Filter` which
|
Building on the generic logger from this morning, implement a `Filter` that uses
|
||||||
uses a closure to filter log messages, sending those which pass the filtering
|
a closure to filter log messages, sending those that pass the filtering
|
||||||
predicate to an inner logger.
|
predicate to an inner logger.
|
||||||
|
|
||||||
```rust,compile_fail,editable
|
```rust,compile_fail,editable
|
||||||
|
@@ -4,7 +4,7 @@ minutes: 10
|
|||||||
|
|
||||||
# Closure traits
|
# Closure traits
|
||||||
|
|
||||||
Closures or lambda expressions have types which cannot be named. However, they
|
Closures or lambda expressions have types that cannot be named. However, they
|
||||||
implement special [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn.html),
|
implement special [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn.html),
|
||||||
[`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html), and
|
[`FnMut`](https://doc.rust-lang.org/std/ops/trait.FnMut.html), and
|
||||||
[`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) traits:
|
[`FnOnce`](https://doc.rust-lang.org/std/ops/trait.FnOnce.html) traits:
|
||||||
@@ -67,7 +67,7 @@ can (i.e. you call it once), or `FnMut` else, and last `Fn`. This allows the
|
|||||||
most flexibility for the caller.
|
most flexibility for the caller.
|
||||||
|
|
||||||
In contrast, when you have a closure, the most flexible you can have is `Fn`
|
In contrast, when you have a closure, the most flexible you can have is `Fn`
|
||||||
(which can be passed to a consumer of any of the 3 closure traits), then
|
(which can be passed to a consumer of any of the three closure traits), then
|
||||||
`FnMut`, and lastly `FnOnce`.
|
`FnMut`, and lastly `FnOnce`.
|
||||||
|
|
||||||
The compiler also infers `Copy` (e.g. for `add_suffix`) and `Clone` (e.g.
|
The compiler also infers `Copy` (e.g. for `add_suffix`) and `Clone` (e.g.
|
||||||
|
@@ -6,5 +6,5 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
futures-util = { version = "0.3.31", features = ["sink"] }
|
futures-util = { version = "0.3.31", features = ["sink"] }
|
||||||
http = "1.3.1"
|
http = "1.3.1"
|
||||||
tokio = { version = "1.45.1", features = ["full"] }
|
tokio = { version = "1.47.1", features = ["full"] }
|
||||||
tokio-websockets = { version = "0.11.4", features = ["client", "fastrand", "server", "sha1_smol"] }
|
tokio-websockets = { version = "0.12.1", features = ["client", "fastrand", "server", "sha1_smol"] }
|
||||||
|
@@ -41,7 +41,7 @@ async fn main() -> Result<(), tokio_websockets::Error> {
|
|||||||
println!("From server: {}", text);
|
println!("From server: {}", text);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(Err(err)) => return Err(err.into()),
|
Some(Err(err)) => return Err(err),
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,8 +11,6 @@ not have a "built-in" runtime, but several options are available:
|
|||||||
- [Tokio](https://tokio.rs/): performant, with a well-developed ecosystem of
|
- [Tokio](https://tokio.rs/): performant, with a well-developed ecosystem of
|
||||||
functionality like [Hyper](https://hyper.rs/) for HTTP or
|
functionality like [Hyper](https://hyper.rs/) for HTTP or
|
||||||
[Tonic](https://github.com/hyperium/tonic) for gRPC.
|
[Tonic](https://github.com/hyperium/tonic) for gRPC.
|
||||||
- [async-std](https://async.rs/): aims to be a "std for async", and includes a
|
|
||||||
basic runtime in `async::task`.
|
|
||||||
- [smol](https://docs.rs/smol/latest/smol/): simple and lightweight
|
- [smol](https://docs.rs/smol/latest/smol/): simple and lightweight
|
||||||
|
|
||||||
Several larger applications have their own runtimes. For example,
|
Several larger applications have their own runtimes. For example,
|
||||||
|
@@ -33,9 +33,9 @@ fn two_d10(modifier: u32) -> TwoD10 {
|
|||||||
enum TwoD10 {
|
enum TwoD10 {
|
||||||
// Function has not begun yet.
|
// Function has not begun yet.
|
||||||
Init { modifier: u32 },
|
Init { modifier: u32 },
|
||||||
// Waitig for first `.await` to complete.
|
// Waiting for first `.await` to complete.
|
||||||
FirstRoll { modifier: u32, fut: RollD10Future },
|
FirstRoll { modifier: u32, fut: RollD10Future },
|
||||||
// Waitig for second `.await` to complete.
|
// Waiting for second `.await` to complete.
|
||||||
SecondRoll { modifier: u32, first_roll: u32, fut: RollD10Future },
|
SecondRoll { modifier: u32, first_roll: u32, fut: RollD10Future },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,9 +13,9 @@ name = "link-checker"
|
|||||||
path = "link-checker.rs"
|
path = "link-checker.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = { version = "0.12.21", features = ["blocking"] }
|
reqwest = { version = "0.12.23", features = ["blocking"] }
|
||||||
scraper = "0.23.1"
|
scraper = "0.24.0"
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.16"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tempfile = "3.20.0"
|
tempfile = "3.21.0"
|
||||||
|
@@ -4,9 +4,9 @@ minutes: 5
|
|||||||
|
|
||||||
# Blocks and Scopes
|
# Blocks and Scopes
|
||||||
|
|
||||||
A block in Rust contains a sequence of expressions, enclosed by braces `{}`.
|
- A block in Rust contains a sequence of expressions, enclosed by braces `{}`.
|
||||||
Each block has a value and a type, which are those of the last expression of the
|
- The final expression of a block determines the value and type of the whole
|
||||||
block:
|
block.
|
||||||
|
|
||||||
```rust,editable
|
```rust,editable
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@@ -30,7 +30,7 @@ fn main() {
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
Note that `loop` is the only looping construct which can return a non-trivial
|
Note that `loop` is the only looping construct that can return a non-trivial
|
||||||
value. This is because it's guaranteed to only return at a `break` statement
|
value. This is because it's guaranteed to only return at a `break` statement
|
||||||
(unlike `while` and `for` loops, which can also return when the condition
|
(unlike `while` and `for` loops, which can also return when the condition
|
||||||
fails).
|
fails).
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# Labels
|
# Labels
|
||||||
|
|
||||||
Both `continue` and `break` can optionally take a label argument which is used
|
Both `continue` and `break` can optionally take a label argument that is used to
|
||||||
to break out of nested loops:
|
break out of nested loops:
|
||||||
|
|
||||||
```rust,editable
|
```rust,editable
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@@ -22,7 +22,7 @@ For example, beginning with _n<sub>1</sub>_ = 3:
|
|||||||
- 2 is even, so _n<sub>8</sub>_ = 1; and
|
- 2 is even, so _n<sub>8</sub>_ = 1; and
|
||||||
- the sequence terminates.
|
- the sequence terminates.
|
||||||
|
|
||||||
Write a function to calculate the length of the collatz sequence for a given
|
Write a function to calculate the length of the Collatz sequence for a given
|
||||||
initial `n`.
|
initial `n`.
|
||||||
|
|
||||||
```rust,editable,should_panic
|
```rust,editable,should_panic
|
||||||
|
@@ -19,6 +19,6 @@ fn main() {
|
|||||||
<details>
|
<details>
|
||||||
|
|
||||||
- The `loop` statement works like a `while true` loop. Use it for things like
|
- The `loop` statement works like a `while true` loop. Use it for things like
|
||||||
servers which will serve connections forever.
|
servers that will serve connections forever.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@@ -59,7 +59,7 @@ fn main() {
|
|||||||
## More to Explore
|
## More to Explore
|
||||||
|
|
||||||
- To further motivate the usage of `match`, you can compare the examples to
|
- To further motivate the usage of `match`, you can compare the examples to
|
||||||
their equivalents written with `if`. In the second case matching on a `bool`
|
their equivalents written with `if`. In the second case, matching on a `bool`,
|
||||||
an `if {} else {}` block is pretty similar. But in the first example that
|
an `if {} else {}` block is pretty similar. But in the first example that
|
||||||
checks multiple cases, a `match` expression can be more concise than
|
checks multiple cases, a `match` expression can be more concise than
|
||||||
`if {} else if {} else if {} else`.
|
`if {} else if {} else if {} else`.
|
||||||
|
@@ -3,3 +3,12 @@
|
|||||||
```rust,editable
|
```rust,editable
|
||||||
{{#include exercise.rs:solution}}
|
{{#include exercise.rs:solution}}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
- Note that the argument `n` is marked as `mut`, allowing you to change the
|
||||||
|
value of `n` in the function. Like variables, function arguments are immutable
|
||||||
|
by default and you must add `mut` if you want to modify their value. This does
|
||||||
|
not affect how the function is called or how the argument is passed in.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
@@ -4,9 +4,7 @@ minutes: 3
|
|||||||
|
|
||||||
# Panics
|
# Panics
|
||||||
|
|
||||||
Rust handles fatal errors with a "panic".
|
In case of a fatal runtime error, Rust triggers a "panic":
|
||||||
|
|
||||||
Rust will trigger a panic if a fatal error happens at runtime:
|
|
||||||
|
|
||||||
```rust,editable,should_panic
|
```rust,editable,should_panic
|
||||||
fn main() {
|
fn main() {
|
||||||
@@ -17,8 +15,8 @@ fn main() {
|
|||||||
|
|
||||||
- Panics are for unrecoverable and unexpected errors.
|
- Panics are for unrecoverable and unexpected errors.
|
||||||
- Panics are symptoms of bugs in the program.
|
- Panics are symptoms of bugs in the program.
|
||||||
- Runtime failures like failed bounds checks can panic
|
- Runtime failures like failed bounds checks can panic.
|
||||||
- Assertions (such as `assert!`) panic on failure
|
- Assertions (such as `assert!`) panic on failure.
|
||||||
- Purpose-specific panics can use the `panic!` macro.
|
- Purpose-specific panics can use the `panic!` macro.
|
||||||
- A panic will "unwind" the stack, dropping values just as if the functions had
|
- A panic will "unwind" the stack, dropping values just as if the functions had
|
||||||
returned.
|
returned.
|
||||||
|
28
src/exercises/bare-metal/rtc/Cargo.lock
generated
28
src/exercises/bare-metal/rtc/Cargo.lock
generated
@@ -4,9 +4,9 @@ version = 4
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aarch64-paging"
|
name = "aarch64-paging"
|
||||||
version = "0.9.1"
|
version = "0.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a3b8f725e9256b2fac2d25e013e22a6a391b8c07e23c4c5eac6e037a78a28801"
|
checksum = "1f02b5bfa3a481fdade5948a994ce93aa6c76f67fc19f3a9b270565cf7dfc657"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -14,18 +14,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aarch64-rt"
|
name = "aarch64-rt"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8069db67616de3ec8d024aa717f447a6995f159a3b46b4379d600a6224640c03"
|
checksum = "683c4295f0608c531130ed6daf301785844c1f71eb126eb56343838968e728c5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smccc",
|
"smccc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arm-gic"
|
name = "arm-gic"
|
||||||
version = "0.4.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd58684ee8041735b64d9e731b18c5515397ee4487f56f7cb9a409c8cbd17839"
|
checksum = "6bfdb03424c95b58315a4cb0ff4ca919568a5a28ae5ba960a1ad92c9ccaf49b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"safe-mmio",
|
"safe-mmio",
|
||||||
@@ -35,9 +35,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arm-pl011-uart"
|
name = "arm-pl011-uart"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff5b0f1e39ec186e409c6fd80bbb83aa00622ca71c9c0561b5571df3b5f5391f"
|
checksum = "8797e113733a36b5fa906c81aefc126d255b88dd1c10a737749aa22ec7736b6a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"embedded-hal-nb",
|
"embedded-hal-nb",
|
||||||
@@ -55,9 +55,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.9.1"
|
version = "2.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
@@ -202,18 +202,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.12"
|
version = "2.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "2.0.12"
|
version = "2.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@@ -7,11 +7,11 @@ edition = "2024"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aarch64-paging = { version = "0.9.1", default-features = false }
|
aarch64-paging = { version = "0.10.0", default-features = false }
|
||||||
aarch64-rt = "0.2.1"
|
aarch64-rt = "0.2.2"
|
||||||
arm-gic = "0.4.0"
|
arm-gic = "0.6.1"
|
||||||
arm-pl011-uart = "0.3.1"
|
arm-pl011-uart = "0.3.2"
|
||||||
bitflags = "2.9.1"
|
bitflags = "2.9.3"
|
||||||
chrono = { version = "0.4.41", default-features = false }
|
chrono = { version = "0.4.41", default-features = false }
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
safe-mmio = "0.2.5"
|
safe-mmio = "0.2.5"
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use arm_gic::gicv3::GicV3;
|
use arm_gic::gicv3::{GicV3, InterruptGroup};
|
||||||
use log::{error, info, trace};
|
use log::{error, info, trace};
|
||||||
use smccc::Hvc;
|
use smccc::Hvc;
|
||||||
use smccc::psci::system_off;
|
use smccc::psci::system_off;
|
||||||
@@ -28,8 +28,8 @@ extern "C" fn sync_exception_current(_elr: u64, _spsr: u64) {
|
|||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
extern "C" fn irq_current(_elr: u64, _spsr: u64) {
|
extern "C" fn irq_current(_elr: u64, _spsr: u64) {
|
||||||
trace!("irq_current");
|
trace!("irq_current");
|
||||||
let intid =
|
let intid = GicV3::get_and_acknowledge_interrupt(InterruptGroup::Group1)
|
||||||
GicV3::get_and_acknowledge_interrupt().expect("No pending interrupt");
|
.expect("No pending interrupt");
|
||||||
info!("IRQ {intid:?}");
|
info!("IRQ {intid:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,8 +33,8 @@ should have created Chrome for pixies!
|
|||||||
<details>
|
<details>
|
||||||
Students will likely need some hints here. Hints include:
|
Students will likely need some hints here. Hints include:
|
||||||
|
|
||||||
- UTF16 vs UTF8. Students should be aware that Rust strings are always UTF8, and
|
- UTF-16 vs UTF-8. Students should be aware that Rust strings are always UTF-8,
|
||||||
will probably decide that it's better to do the conversion on the C++ side
|
and will probably decide that it's better to do the conversion on the C++ side
|
||||||
using `base::UTF16ToUTF8` and back again.
|
using `base::UTF16ToUTF8` and back again.
|
||||||
- If students decide to do the conversion on the Rust side, they'll need to
|
- If students decide to do the conversion on the Rust side, they'll need to
|
||||||
consider [`String::from_utf16`][1], consider error handling, and consider
|
consider [`String::from_utf16`][1], consider error handling, and consider
|
||||||
|
@@ -11,7 +11,7 @@ pub extern "C" fn hello_from_rust() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Important**: note that `no_mangle` here is considered a type of unsafety by
|
**Important:** note that `no_mangle` here is considered a type of unsafety by
|
||||||
the Rust compiler, so you'll need to allow unsafe code in your `gn` target.
|
the Rust compiler, so you'll need to allow unsafe code in your `gn` target.
|
||||||
|
|
||||||
Add this new Rust target as a dependency of `//ui/base:base`. Declare this
|
Add this new Rust target as a dependency of `//ui/base:base`. Declare this
|
||||||
|
@@ -60,7 +60,7 @@ fn main() {
|
|||||||
instance of the function for each different type that the generic is
|
instance of the function for each different type that the generic is
|
||||||
instantiated with. This means that calling a trait method from within a
|
instantiated with. This means that calling a trait method from within a
|
||||||
generic function still uses static dispatch, as the compiler has full type
|
generic function still uses static dispatch, as the compiler has full type
|
||||||
information and can resolve which type's trait implementation to use.
|
information and can resolve that type's trait implementation to use.
|
||||||
|
|
||||||
- When using `dyn Trait`, it instead uses dynamic dispatch through a
|
- When using `dyn Trait`, it instead uses dynamic dispatch through a
|
||||||
[virtual method table][vtable] (vtable). This means that there's a single
|
[virtual method table][vtable] (vtable). This means that there's a single
|
||||||
|
@@ -44,7 +44,7 @@ fn main() {
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
- _Q:_ Why `L` is specified twice in `impl<L: Logger> .. VerbosityFilter<L>`?
|
- _Q:_ Why is `L` specified twice in `impl<L: Logger> .. VerbosityFilter<L>`?
|
||||||
Isn't that redundant?
|
Isn't that redundant?
|
||||||
- This is because it is a generic implementation section for generic type.
|
- This is because it is a generic implementation section for generic type.
|
||||||
They are independently generic.
|
They are independently generic.
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
Minutes: 5
|
minutes: 5
|
||||||
---
|
---
|
||||||
|
|
||||||
# Generic Traits
|
# Generic Traits
|
||||||
|
@@ -30,7 +30,7 @@ fn main() {
|
|||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
`impl Trait` allows you to work with types which you cannot name. The meaning of
|
`impl Trait` allows you to work with types that you cannot name. The meaning of
|
||||||
`impl Trait` is a bit different in the different positions.
|
`impl Trait` is a bit different in the different positions.
|
||||||
|
|
||||||
- For a parameter, `impl Trait` is like an anonymous generic parameter with a
|
- For a parameter, `impl Trait` is like an anonymous generic parameter with a
|
||||||
|
150
src/glossary.md
150
src/glossary.md
@@ -31,7 +31,8 @@ h1#glossary ~ ul > li:first-line {
|
|||||||
- allocate:\
|
- allocate:\
|
||||||
Dynamic memory allocation on [the heap](memory-management/review.md).
|
Dynamic memory allocation on [the heap](memory-management/review.md).
|
||||||
- argument:\
|
- argument:\
|
||||||
Information that is passed into a function or method.
|
Information that is passed into a [function](control-flow-basics/functions.md)
|
||||||
|
or method.
|
||||||
- associated type:\
|
- associated type:\
|
||||||
A type associated with a specific trait. Useful for defining the relationship
|
A type associated with a specific trait. Useful for defining the relationship
|
||||||
between types.
|
between types.
|
||||||
@@ -43,165 +44,192 @@ h1#glossary ~ ul > li:first-line {
|
|||||||
- borrow:\
|
- borrow:\
|
||||||
See [Borrowing](borrowing/shared.md).
|
See [Borrowing](borrowing/shared.md).
|
||||||
- borrow checker:\
|
- borrow checker:\
|
||||||
The part of the Rust compiler which checks that all borrows are valid.
|
The part of the Rust compiler which checks that all
|
||||||
|
[borrows](borrowing/borrowck.md) are valid.
|
||||||
- brace:\
|
- brace:\
|
||||||
`{` and `}`. Also called _curly brace_, they delimit _blocks_.
|
`{` and `}`. Also called _curly brace_, they delimit
|
||||||
|
[_blocks_](control-flow-basics/blocks-and-scopes.md).
|
||||||
- build:\
|
- build:\
|
||||||
The process of converting source code into executable code or a usable
|
The process of converting source code into executable code or a usable
|
||||||
program.
|
program. See [Running Code Locally with Cargo](cargo/running-locally.md).
|
||||||
- call:\
|
- call:\
|
||||||
To invoke or execute a function or method.
|
To invoke or execute a [function or method](control-flow-basics/functions.md).
|
||||||
- channel:\
|
- channel:\
|
||||||
Used to safely pass messages [between threads](concurrency/channels.md).
|
Used to safely pass messages [between threads](concurrency/channels.md).
|
||||||
- Comprehensive Rust 🦀:\
|
- Comprehensive Rust 🦀:\
|
||||||
The courses here are jointly called Comprehensive Rust 🦀.
|
The courses here are jointly called Comprehensive Rust 🦀.
|
||||||
- concurrency:\
|
- concurrency:\
|
||||||
The execution of multiple tasks or processes at the same time.
|
The execution of multiple tasks or processes at the same time. See
|
||||||
|
[Welcome to Concurrency in Rust](concurrency/welcome.md).
|
||||||
- Concurrency in Rust:\
|
- Concurrency in Rust:\
|
||||||
See [Concurrency in Rust](concurrency/welcome.md).
|
See [Concurrency in Rust](concurrency/welcome.md).
|
||||||
- constant:\
|
- constant:\
|
||||||
A value that does not change during the execution of a program.
|
A value that does not change during the execution of a program. See
|
||||||
|
[const](user-defined-types/const.md).
|
||||||
- control flow:\
|
- control flow:\
|
||||||
The order in which the individual statements or instructions are executed in a
|
The order in which the individual statements or instructions are executed in a
|
||||||
program.
|
program. See [Control Flow Basics](control-flow-basics.md).
|
||||||
- crash:\
|
- crash:\
|
||||||
An unexpected and unhandled failure or termination of a program.
|
An unexpected and unhandled failure or termination of a program. See
|
||||||
|
[panic](error-handling/panics.md).
|
||||||
- enumeration:\
|
- enumeration:\
|
||||||
A data type that holds one of several named constants, possibly with an
|
A data type that holds one of several named constants, possibly with an
|
||||||
associated tuple or struct.
|
associated tuple or struct. See [enum](user-defined-types/enums.md).
|
||||||
- error:\
|
- error:\
|
||||||
An unexpected condition or result that deviates from the expected behavior.
|
An unexpected condition or result that deviates from the expected behavior.
|
||||||
|
See [Error Handling](error-handling.md).
|
||||||
- error handling:\
|
- error handling:\
|
||||||
The process of managing and responding to errors that occur during program
|
The process of managing and responding to [errors](error-handling.md) that
|
||||||
execution.
|
occur during program execution.
|
||||||
- exercise:\
|
- exercise:\
|
||||||
A task or problem designed to practice and test programming skills.
|
A task or problem designed to practice and test programming skills.
|
||||||
- function:\
|
- function:\
|
||||||
A reusable block of code that performs a specific task.
|
A reusable block of code that performs a specific task. See
|
||||||
|
[Functions](control-flow-basics/functions.md).
|
||||||
- garbage collector:\
|
- garbage collector:\
|
||||||
A mechanism that automatically frees up memory occupied by objects that are no
|
A mechanism that automatically frees up memory occupied by objects that are no
|
||||||
longer in use.
|
longer in use. See
|
||||||
|
[Approaches to Memory Management](memory-management/approaches.md).
|
||||||
- generics:\
|
- generics:\
|
||||||
A feature that allows writing code with placeholders for types, enabling code
|
A feature that allows writing code with placeholders for types, enabling code
|
||||||
reuse with different data types.
|
reuse with different data types. See [Generics](generics.md).
|
||||||
- immutable:\
|
- immutable:\
|
||||||
Unable to be changed after creation.
|
Unable to be changed after creation. See
|
||||||
|
[Variables](types-and-values/variables.md).
|
||||||
- integration test:\
|
- integration test:\
|
||||||
A type of test that verifies the interactions between different parts or
|
A type of test that verifies the interactions between different parts or
|
||||||
components of a system.
|
components of a system. See [Other Types of Tests](testing/other.md).
|
||||||
- keyword:\
|
- keyword:\
|
||||||
A reserved word in a programming language that has a specific meaning and
|
A reserved word in a programming language that has a specific meaning and
|
||||||
cannot be used as an identifier.
|
cannot be used as an identifier.
|
||||||
- library:\
|
- library:\
|
||||||
A collection of precompiled routines or code that can be used by programs.
|
A collection of precompiled routines or code that can be used by programs. See
|
||||||
|
[Modules](modules.md).
|
||||||
- macro:\
|
- macro:\
|
||||||
Rust macros can be recognized by a `!` in the name. Macros are used when
|
Rust [macros](control-flow-basics/macros.md) can be recognized by a `!` in the
|
||||||
normal functions are not enough. A typical example is `format!`, which takes a
|
name. Macros are used when normal functions are not enough. A typical example
|
||||||
variable number of arguments, which isn't supported by Rust functions.
|
is `format!`, which takes a variable number of arguments, which isn't
|
||||||
|
supported by Rust functions.
|
||||||
- `main` function:\
|
- `main` function:\
|
||||||
Rust programs start executing with the `main` function.
|
Rust programs start executing with the
|
||||||
|
[`main` function](types-and-values/hello-world.md).
|
||||||
- match:\
|
- match:\
|
||||||
A control flow construct in Rust that allows for pattern matching on the value
|
A control flow construct in Rust that allows for
|
||||||
of an expression.
|
[pattern matching](pattern-matching.md) on the value of an expression.
|
||||||
- memory leak:\
|
- memory leak:\
|
||||||
A situation where a program fails to release memory that is no longer needed,
|
A situation where a program fails to release memory that is no longer needed,
|
||||||
leading to a gradual increase in memory usage.
|
leading to a gradual increase in memory usage. See
|
||||||
|
[Approaches to Memory Management](memory-management/approaches.md).
|
||||||
- method:\
|
- method:\
|
||||||
A function associated with an object or a type in Rust.
|
A function associated with an object or a type in Rust. See
|
||||||
|
[Methods](methods-and-traits/methods.md).
|
||||||
- module:\
|
- module:\
|
||||||
A namespace that contains definitions, such as functions, types, or traits, to
|
A namespace that contains definitions, such as functions, types, or traits, to
|
||||||
organize code in Rust.
|
organize code in Rust. See [Modules](modules.md).
|
||||||
- move:\
|
- move:\
|
||||||
The transfer of ownership of a value from one variable to another in Rust.
|
The transfer of ownership of a value from one variable to another in Rust. See
|
||||||
|
[Move Semantics](memory-management/move.md).
|
||||||
- mutable:\
|
- mutable:\
|
||||||
A property in Rust that allows variables to be modified after they have been
|
A property in Rust that allows [variables](types-and-values/variables.md) to
|
||||||
declared.
|
be modified after they have been declared.
|
||||||
- ownership:\
|
- ownership:\
|
||||||
The concept in Rust that defines which part of the code is responsible for
|
The concept in Rust that defines which part of the code is responsible for
|
||||||
managing the memory associated with a value.
|
managing the memory associated with a value. See
|
||||||
|
[Ownership](memory-management/ownership.md).
|
||||||
- panic:\
|
- panic:\
|
||||||
An unrecoverable error condition in Rust that results in the termination of
|
An unrecoverable error condition in Rust that results in the termination of
|
||||||
the program.
|
the program. See [Panics](error-handling/panics.md).
|
||||||
- parameter:\
|
- parameter:\
|
||||||
A value that is passed into a function or method when it is called.
|
A value that is passed into a
|
||||||
|
[function or method](control-flow-basics/functions.md) when it is called.
|
||||||
- pattern:\
|
- pattern:\
|
||||||
A combination of values, literals, or structures that can be matched against
|
A combination of values, literals, or structures that can be matched against
|
||||||
an expression in Rust.
|
an expression in Rust. See [Pattern Matching](pattern-matching.md).
|
||||||
- payload:\
|
- payload:\
|
||||||
The data or information carried by a message, event, or data structure.
|
The data or information carried by a message, event, or data structure.
|
||||||
- program:\
|
- program:\
|
||||||
A set of instructions that a computer can execute to perform a specific task
|
A set of instructions that a computer can execute to perform a specific task
|
||||||
or solve a particular problem.
|
or solve a particular problem. See
|
||||||
|
[Hello, World](types-and-values/hello-world.md).
|
||||||
- programming language:\
|
- programming language:\
|
||||||
A formal system used to communicate instructions to a computer, such as Rust.
|
A formal system used to communicate instructions to a computer, such as
|
||||||
|
[Rust](hello-world/what-is-rust.md).
|
||||||
- receiver:\
|
- receiver:\
|
||||||
The first parameter in a Rust method that represents the instance on which the
|
The first parameter in a Rust [method](methods-and-traits/methods.md) that
|
||||||
method is called.
|
represents the instance on which the method is called.
|
||||||
- reference counting:\
|
- reference counting:\
|
||||||
A memory management technique in which the number of references to an object
|
A memory management technique in which the number of references to an object
|
||||||
is tracked, and the object is deallocated when the count reaches zero.
|
is tracked, and the object is deallocated when the count reaches zero. See
|
||||||
|
[Rc](smart-pointers/rc.md).
|
||||||
- return:\
|
- return:\
|
||||||
A keyword in Rust used to indicate the value to be returned from a function.
|
A keyword in Rust used to indicate the value to be returned from a
|
||||||
|
[function](control-flow-basics/functions.md).
|
||||||
- Rust:\
|
- Rust:\
|
||||||
A systems programming language that focuses on safety, performance, and
|
A systems programming language that focuses on safety, performance, and
|
||||||
concurrency.
|
concurrency. See [What is Rust?](hello-world/what-is-rust.md).
|
||||||
- Rust Fundamentals:\
|
- Rust Fundamentals:\
|
||||||
Days 1 to 4 of this course.
|
Days 1 to 4 of this course. See [Welcome to Day 1](welcome-day-1.md).
|
||||||
- Rust in Android:\
|
- Rust in Android:\
|
||||||
See [Rust in Android](android.md).
|
See [Rust in Android](android.md).
|
||||||
- Rust in Chromium:\
|
- Rust in Chromium:\
|
||||||
See [Rust in Chromium](chromium.md).
|
See [Rust in Chromium](chromium.md).
|
||||||
- safe:\
|
- safe:\
|
||||||
Refers to code that adheres to Rust's ownership and borrowing rules,
|
Refers to code that adheres to Rust's ownership and borrowing rules,
|
||||||
preventing memory-related errors.
|
preventing memory-related errors. See [Unsafe Rust](unsafe-rust.md).
|
||||||
- scope:\
|
- scope:\
|
||||||
The region of a program where a variable is valid and can be used.
|
The region of a program where a variable is valid and can be used. See
|
||||||
|
[Blocks and Scopes](control-flow-basics/blocks-and-scopes.md).
|
||||||
- standard library:\
|
- standard library:\
|
||||||
A collection of modules providing essential functionality in Rust.
|
A collection of modules providing essential functionality in Rust. See
|
||||||
|
[Standard Library](std-types/std.md).
|
||||||
- static:\
|
- static:\
|
||||||
A keyword in Rust used to define static variables or items with a `'static`
|
A keyword in Rust used to define static variables or items with a `'static`
|
||||||
lifetime.
|
lifetime. See [static](user-defined-types/static.md).
|
||||||
- string:\
|
- string:\
|
||||||
A data type storing textual data. See [Strings](references/strings.html) for
|
A data type storing textual data. See [Strings](references/strings.md).
|
||||||
more.
|
|
||||||
- struct:\
|
- struct:\
|
||||||
A composite data type in Rust that groups together variables of different
|
A composite data type in Rust that groups together variables of different
|
||||||
types under a single name.
|
types under a single name. See [Structs](user-defined-types/named-structs.md).
|
||||||
- test:\
|
- test:\
|
||||||
A Rust module containing functions that test the correctness of other
|
A function that tests the correctness of other code. Rust has a built-in test
|
||||||
functions.
|
runner. See [Testing](testing.md).
|
||||||
- thread:\
|
- thread:\
|
||||||
A separate sequence of execution in a program, allowing concurrent execution.
|
A separate sequence of execution in a program, allowing concurrent execution.
|
||||||
|
See [Threads](concurrency/threads.md).
|
||||||
- thread safety:\
|
- thread safety:\
|
||||||
The property of a program that ensures correct behavior in a multithreaded
|
The property of a program that ensures correct behavior in a multithreaded
|
||||||
environment.
|
environment. See [Send and Sync](concurrency/send-sync.md).
|
||||||
- trait:\
|
- trait:\
|
||||||
A collection of methods defined for an unknown type, providing a way to
|
A collection of methods defined for an unknown type, providing a way to
|
||||||
achieve polymorphism in Rust.
|
achieve polymorphism in Rust. See [Traits](methods-and-traits/traits.md).
|
||||||
- trait bound:\
|
- trait bound:\
|
||||||
An abstraction where you can require types to implement some traits of your
|
An abstraction where you can require types to implement some traits of your
|
||||||
interest.
|
interest. See [Trait Bounds](generics/trait-bounds.md).
|
||||||
- tuple:\
|
- tuple:\
|
||||||
A composite data type that contains variables of different types. Tuple fields
|
A composite data type that contains variables of different types. Tuple fields
|
||||||
have no names, and are accessed by their ordinal numbers.
|
have no names, and are accessed by their ordinal numbers. See
|
||||||
|
[Tuples](tuples-and-arrays/tuples.md).
|
||||||
- type:\
|
- type:\
|
||||||
A classification that specifies which operations can be performed on values of
|
A classification that specifies which operations can be performed on values of
|
||||||
a particular kind in Rust.
|
a particular kind in Rust. See [Types and Values](types-and-values.md).
|
||||||
- type inference:\
|
- type inference:\
|
||||||
The ability of the Rust compiler to deduce the type of a variable or
|
The ability of the Rust compiler to deduce the type of a variable or
|
||||||
expression.
|
expression. See [Type Inference](types-and-values/inference.md).
|
||||||
- undefined behavior:\
|
- undefined behavior:\
|
||||||
Actions or conditions in Rust that have no specified result, often leading to
|
Actions or conditions in Rust that have no specified result, often leading to
|
||||||
unpredictable program behavior.
|
unpredictable program behavior. See [Unsafe Rust](unsafe-rust.md).
|
||||||
- union:\
|
- union:\
|
||||||
A data type that can hold values of different types but only one at a time.
|
A data type that can hold values of different types but only one at a time.
|
||||||
|
See [Unions](unsafe-rust/unions.md).
|
||||||
- unit test:\
|
- unit test:\
|
||||||
Rust comes with built-in support for running small unit tests and larger
|
Rust comes with built-in support for running small unit tests and larger
|
||||||
integration tests. See [Unit Tests](testing/unit-tests.html).
|
integration tests. See [Unit Tests](testing/unit-tests.md).
|
||||||
- unit type:\
|
- unit type:\
|
||||||
Type that holds no data, written as a tuple with no members.
|
Type that holds no data, written as a tuple with no members. See speaker notes
|
||||||
|
on [Functions](control-flow-basics/functions.html).
|
||||||
- unsafe:\
|
- unsafe:\
|
||||||
The subset of Rust which allows you to trigger _undefined behavior_. See
|
The subset of Rust which allows you to trigger _undefined behavior_. See
|
||||||
[Unsafe Rust](unsafe-rust/unsafe.md).
|
[Unsafe Rust](unsafe-rust/unsafe.md).
|
||||||
- variable:\
|
- variable:\
|
||||||
A memory location storing data. Variables are valid in a _scope_.
|
A memory location storing data. Variables are valid in a _scope_. See
|
||||||
|
[Variables](types-and-values/variables.md).
|
||||||
|
@@ -4,7 +4,7 @@ minutes: 10
|
|||||||
|
|
||||||
# What is Rust?
|
# What is Rust?
|
||||||
|
|
||||||
Rust is a new programming language which had its [1.0 release in 2015][1]:
|
Rust is a new programming language that had its [1.0 release in 2015][1]:
|
||||||
|
|
||||||
- Rust is a statically compiled language in a similar role as C++
|
- Rust is a statically compiled language in a similar role as C++
|
||||||
- `rustc` uses LLVM as its backend.
|
- `rustc` uses LLVM as its backend.
|
||||||
|
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
minutes: 30
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typestate Pattern: Problem
|
||||||
|
|
||||||
|
How can we ensure that only valid operations are allowed on a value based on its
|
||||||
|
current state?
|
||||||
|
|
||||||
|
```rust,editable
|
||||||
|
use std::fmt::Write as _;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct Serializer {
|
||||||
|
output: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serializer {
|
||||||
|
fn serialize_struct_start(&mut self, name: &str) {
|
||||||
|
let _ = writeln!(&mut self.output, "{name} {{");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_struct_field(&mut self, key: &str, value: &str) {
|
||||||
|
let _ = writeln!(&mut self.output, " {key}={value};");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_struct_end(&mut self) {
|
||||||
|
self.output.push_str("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish(self) -> String {
|
||||||
|
self.output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut serializer = Serializer::default();
|
||||||
|
serializer.serialize_struct_start("User");
|
||||||
|
serializer.serialize_struct_field("id", "42");
|
||||||
|
serializer.serialize_struct_field("name", "Alice");
|
||||||
|
|
||||||
|
// serializer.serialize_struct_end(); // ← Oops! Forgotten
|
||||||
|
|
||||||
|
println!("{}", serializer.finish());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<details>
|
||||||
|
|
||||||
|
- This `Serializer` is meant to write a structured value.
|
||||||
|
|
||||||
|
- However, in this example we forgot to call `serialize_struct_end()` before
|
||||||
|
`finish()`. As a result, the serialized output is incomplete or syntactically
|
||||||
|
incorrect.
|
||||||
|
|
||||||
|
- One approach to fix this would be to track internal state manually, and return
|
||||||
|
a `Result` from methods like `serialize_struct_field()` or `finish()` if the
|
||||||
|
current state is invalid.
|
||||||
|
|
||||||
|
- But this has downsides:
|
||||||
|
|
||||||
|
- It is easy to get wrong as an implementer. Rust’s type system cannot help
|
||||||
|
enforce the correctness of our state transitions.
|
||||||
|
|
||||||
|
- It also adds unnecessary burden on the user, who must handle `Result` values
|
||||||
|
for operations that are misused in source code rather than at runtime.
|
||||||
|
|
||||||
|
- A better solution is to model the valid state transitions directly in the type
|
||||||
|
system.
|
||||||
|
|
||||||
|
In the next slide, we will apply the **typestate pattern** to enforce correct
|
||||||
|
usage at compile time and make it impossible to call incompatible methods or
|
||||||
|
forget to do a required action.
|
||||||
|
|
||||||
|
</details>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user