diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..ac07f01
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,61 @@
+version: 2
+updates:
+ - package-ecosystem: "cargo"
+ directories:
+ - "/exercises/1-course-introduction/1-introduction/1-setup-your-installation"
+ - "/exercises/1-course-introduction/1-introduction/2-embedded"
+ - "/exercises/2-foundations-of-rust/1-basic-syntax/1-basic-syntax"
+ - "/exercises/2-foundations-of-rust/2-ownership-and-references/1-move-semantics"
+ - "/exercises/2-foundations-of-rust/2-ownership-and-references/2-borrowing"
+ - "/exercises/2-foundations-of-rust/3-advanced-syntax/1-error-propagation"
+ - "/exercises/2-foundations-of-rust/3-advanced-syntax/2-error-handling"
+ - "/exercises/2-foundations-of-rust/3-advanced-syntax/3-slices"
+ - "/exercises/2-foundations-of-rust/3-advanced-syntax/4-ring-buffer"
+ - "/exercises/2-foundations-of-rust/3-advanced-syntax/5-boxed-data"
+ - "/exercises/2-foundations-of-rust/4-traits-and-generics/1-local-storage-vec"
+ - "/exercises/2-foundations-of-rust/5-closures-and-dynamic-dispatch/1-config-reader"
+ - "/exercises/3-crate-engineering/1-crate-engineering/1-my-serde-app"
+ - "/exercises/3-crate-engineering/1-crate-engineering/3-bsn"
+ - "/exercises/3-crate-engineering/1-crate-engineering/4-3d-printer"
+ - "/exercises/3-crate-engineering/1-crate-engineering/5-fizzbuzz"
+ - "/exercises/4-multitasking/2-parallel-multitasking/1-tf-idf"
+ - "/exercises/4-multitasking/2-parallel-multitasking/2-mutex"
+ - "/exercises/4-multitasking/3-asynchronous-multitasking/0-sync-to-async"
+ - "/exercises/4-multitasking/3-asynchronous-multitasking/1-async-channels"
+ - "/exercises/4-multitasking/3-asynchronous-multitasking/2-async-chat"
+ - "/exercises/4-multitasking/3-asynchronous-multitasking/3-measurement-data-sink"
+ - "/exercises/4-multitasking/3-asynchronous-multitasking/3-measurement-data-sink/node-simulator"
+ - "/exercises/6-rust-for-systems-programming/1-foreign-function-interface/1-crc-in-c"
+ - "/exercises/6-rust-for-systems-programming/1-foreign-function-interface/2-crc-in-rust"
+ - "/exercises/6-rust-for-systems-programming/1-foreign-function-interface/3-tweetnacl-bindgen"
+ - "/exercises/7-rust-for-data-science/1-rust-from-python/1-hello-world"
+ - "/exercises/7-rust-for-data-science/1-rust-from-python/2-strompy"
+ - "/exercises/8-embedded/1-embedded-ecosystem/1-lsm303agr-id"
+ - "/exercises/8-embedded/2-portable-drivers/1-lsm303agr-driver"
+ - "/exercises/8-embedded/3-async-on-embedded/1-compass"
+ - "/exercises/8-embedded/4-embassy-framework/1-embassy-project"
+ schedule:
+ interval: "weekly"
+ day: "thursday"
+ groups:
+ exercises-dependencies:
+ patterns:
+ - "*"
+ - package-ecosystem: "npm"
+ directory: "/slides/"
+ schedule:
+ interval: "weekly"
+ day: "thursday"
+ groups:
+ npm-dependencies:
+ patterns:
+ - "*"
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ day: "thursday"
+ groups:
+ ci-dependencies:
+ patterns:
+ - "*"
\ No newline at end of file
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
new file mode 100644
index 0000000..4b1a0c2
--- /dev/null
+++ b/.github/workflows/check.yml
@@ -0,0 +1,36 @@
+name: checks
+
+permissions:
+ contents: read
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches-ignore:
+ - 'release/**'
+ merge_group:
+ branches:
+ - main
+ workflow_call: {}
+
+jobs:
+ check:
+ name: "Check everything still builds"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 'lts/*'
+ - name: Install mdbook
+ run: |
+ wget --no-verbose "https://github.com/rust-lang/mdBook/releases/download/v0.4.40/mdbook-v0.4.40-x86_64-unknown-linux-gnu.tar.gz"
+ tar -xzf mdbook-v0.4.40-x86_64-unknown-linux-gnu.tar.gz
+ sudo mv mdbook /usr/bin/
+
+ - name: Run checks
+ run: ./check.sh
+ - name: Build book and slides
+ run: ./build-all.sh ${{github.event.repository.name}}
\ No newline at end of file
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..1a63b1d
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,48 @@
+on:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 'lts/*'
+ - name: Install mdbook
+ run: |
+ wget --no-verbose "https://github.com/rust-lang/mdBook/releases/download/v0.4.40/mdbook-v0.4.40-x86_64-unknown-linux-gnu.tar.gz"
+ tar -xzf mdbook-v0.4.40-x86_64-unknown-linux-gnu.tar.gz
+ sudo mv mdbook /usr/bin/
+
+ - name: Build
+ run: ./build-all.sh ${{github.event.repository.name}}
+
+ - name: Setup Pages
+ uses: actions/configure-pages@v4
+ - name: Upload artifacts
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: public/
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ needs: build
+ runs-on: ubuntu-latest
+ name: Deploy
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 4bb727c..a3d7bbc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
*/**/target
target
.idea
+public/
diff --git a/book/book.toml b/book/book.toml
index 15df35f..c9675a9 100644
--- a/book/book.toml
+++ b/book/book.toml
@@ -4,3 +4,7 @@ multilingual = false
[build]
build-dir = "./target"
+
+[output.html]
+git-repository-url = "https://github.com/tweedegolf/rust-training/"
+site-url = "/rust-training/"
diff --git a/book/src/advanced-syntax.md b/book/src/advanced-syntax.md
index 69b0825..7536345 100644
--- a/book/src/advanced-syntax.md
+++ b/book/src/advanced-syntax.md
@@ -1,6 +1,6 @@
# Unit 2.3 - Advanced Syntax
-Slides
+Slides
## Exercise 2.3.1: Error propagation
diff --git a/book/src/async-on-embedded.md b/book/src/async-on-embedded.md
index 359d5d0..3b67557 100644
--- a/book/src/async-on-embedded.md
+++ b/book/src/async-on-embedded.md
@@ -1,6 +1,6 @@
# Unit 8.3 - Async on Embedded
-Slides
+Slides
## Exercise 8.3.1: Compass
In this exercise, we'll use the [`lsm303agr`](https://docs.rs/lsm303agr) driver. Although the documentation doesn't show it, it supports async if you enable its `async` [feature](https://doc.rust-lang.org/cargo/reference/features.html)
diff --git a/book/src/asynchronous-multitasking.md b/book/src/asynchronous-multitasking.md
index 8cf673f..df1bd00 100644
--- a/book/src/asynchronous-multitasking.md
+++ b/book/src/asynchronous-multitasking.md
@@ -1,6 +1,6 @@
# Unit 4.3 - Asynchronous Multitasking
-Slides
+Slides
## Exercise 4.3.1: Async Channels
diff --git a/book/src/basic-syntax.md b/book/src/basic-syntax.md
index ba5afbd..c0f3bb5 100644
--- a/book/src/basic-syntax.md
+++ b/book/src/basic-syntax.md
@@ -1,6 +1,6 @@
# Unit 2.1 - Basic Syntax
-Slides
+Slides
## Exercise 2.1.1: Basic Syntax
diff --git a/book/src/closures-and-dynamic-dispatch.md b/book/src/closures-and-dynamic-dispatch.md
index c63575a..d05488a 100644
--- a/book/src/closures-and-dynamic-dispatch.md
+++ b/book/src/closures-and-dynamic-dispatch.md
@@ -1,6 +1,6 @@
# Unit 2.5 - Closures and Dynamic dispatch
-Slides
+Slides
## Exercise 2.5.1: Config Reader
diff --git a/book/src/crate-engineering.md b/book/src/crate-engineering.md
index 6a32c2a..81c93a6 100644
--- a/book/src/crate-engineering.md
+++ b/book/src/crate-engineering.md
@@ -1,6 +1,6 @@
# Unit 3.1 - Crate Engineering
-Slides
+Slides
## Exercise 3.1.1: My Serde App
diff --git a/book/src/embassy-framework.md b/book/src/embassy-framework.md
index 7c529b3..9aaf464 100644
--- a/book/src/embassy-framework.md
+++ b/book/src/embassy-framework.md
@@ -1,6 +1,6 @@
# Unit 8.4 - The Embassy Framework
-Slides
+Slides
## Exercise 8.4.1: Embassy project
diff --git a/book/src/embedded-ecosystem.md b/book/src/embedded-ecosystem.md
index 5e32139..12f2f70 100644
--- a/book/src/embedded-ecosystem.md
+++ b/book/src/embedded-ecosystem.md
@@ -1,6 +1,6 @@
# Unit 8.1 - The Rust embedded ecosystem
-Slides
+Slides
## Exercise 8.1.1: LSM303AGR ID
Use our newly gained knowledge to get our first application running and read out the ID of the LSM303AGR accelerometer.
diff --git a/book/src/foreign-function-interface.md b/book/src/foreign-function-interface.md
index e49aba2..7e52937 100644
--- a/book/src/foreign-function-interface.md
+++ b/book/src/foreign-function-interface.md
@@ -1,6 +1,6 @@
# Unit 6.1 - Foreign Function Interface
-Slides
+Slides
## Exercise 6.1.1: CRC in C
diff --git a/book/src/introduction-to-multitasking.md b/book/src/introduction-to-multitasking.md
index f3e7d5b..802b831 100644
--- a/book/src/introduction-to-multitasking.md
+++ b/book/src/introduction-to-multitasking.md
@@ -1,5 +1,5 @@
# Unit 4.1 - Introduction to Multitasking
-Slides
+Slides
*There are no exercises for this unit*
\ No newline at end of file
diff --git a/book/src/introduction.md b/book/src/introduction.md
index 46d5b87..8cfafc4 100644
--- a/book/src/introduction.md
+++ b/book/src/introduction.md
@@ -1,6 +1,6 @@
# Unit 1.1 - Introduction
-Slides
+Slides
## Exercise 1.1.1: Setup Your Installation
diff --git a/book/src/ownership-and-references.md b/book/src/ownership-and-references.md
index c2a57c0..c5040ca 100644
--- a/book/src/ownership-and-references.md
+++ b/book/src/ownership-and-references.md
@@ -1,6 +1,6 @@
# Unit 2.2 - Ownership and References
-Slides
+Slides
## Exercise 2.2.1: Move Semantics
diff --git a/book/src/parallel-multitasking.md b/book/src/parallel-multitasking.md
index 10c7587..ee6f535 100644
--- a/book/src/parallel-multitasking.md
+++ b/book/src/parallel-multitasking.md
@@ -1,6 +1,6 @@
# Unit 4.2 - Parallel Multitasking
-Slides
+Slides
## Exercise 4.2.1: TF-IDF
diff --git a/book/src/portable-drivers.md b/book/src/portable-drivers.md
index 01791ed..5597263 100644
--- a/book/src/portable-drivers.md
+++ b/book/src/portable-drivers.md
@@ -1,6 +1,6 @@
# Unit 8.2 - Portable Rust drivers
-Slides
+Slides
## Exercise 8.2.1: LSM303AGR Driver
diff --git a/book/src/rust-for-web.md b/book/src/rust-for-web.md
index b96be4b..fd08908 100644
--- a/book/src/rust-for-web.md
+++ b/book/src/rust-for-web.md
@@ -1,6 +1,6 @@
# Unit 5.1 - Rust for Web
-Slides
+Slides
## Exercise 5.1.1: Pastebin
diff --git a/book/src/rust-from-python.md b/book/src/rust-from-python.md
index 3428477..f2631dc 100644
--- a/book/src/rust-from-python.md
+++ b/book/src/rust-from-python.md
@@ -1,6 +1,6 @@
# Unit 7.1 - Rust from Python
-Slides
+Slides
## Exercise 7.1.1: Test your environment
diff --git a/book/src/traits-and-generics.md b/book/src/traits-and-generics.md
index e3ee752..6fb8a70 100644
--- a/book/src/traits-and-generics.md
+++ b/book/src/traits-and-generics.md
@@ -1,6 +1,6 @@
# Unit 2.4 - Traits and Generics
-Slides
+Slides
## Exercise 2.4.1: Local Storage Vec
diff --git a/book/src/wrap-up.md b/book/src/wrap-up.md
index ad4e08f..89d0212 100644
--- a/book/src/wrap-up.md
+++ b/book/src/wrap-up.md
@@ -1,6 +1,6 @@
# Wrap-up
-Slides
+Slides
## Evaluation form
diff --git a/build-all.sh b/build-all.sh
new file mode 100755
index 0000000..a1477a2
--- /dev/null
+++ b/build-all.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+set -eo pipefail
+
+echo "TODO: use $1 as base"
+
+rm -rf public/
+mkdir -p public/
+
+# build mdbook
+pushd book
+ mdbook build
+popd
+mv book/target/* ./public/
+
+# build slides
+pushd slides
+ npm install
+ for f in *.md; do
+ npm run build -- --out "dist/${f%.md}" --base "/rust-training/slides/$f{%.md}/" "$f"
+ done
+popd
+mv slides/dist ./public/slides
diff --git a/check.sh b/check.sh
new file mode 100755
index 0000000..ffc0b08
--- /dev/null
+++ b/check.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -eo pipefail
+
+TARGETS=$(find exercises/ -name Cargo.toml | sort)
+
+echo "Check all examples are covered by dependabot"
+for target in $TARGETS; do
+ DIRNAME=$(dirname "$target")
+ grep -Fxq " - \"/$DIRNAME\"" .github/dependabot.yml || echo "Missing entry in dependabot.yml: $DIRNAME" 1>&2
+done
diff --git a/slides/1_1-introduction.md b/slides/1_1-introduction.md
index cb8b8f1..32d6a0a 100644
--- a/slides/1_1-introduction.md
+++ b/slides/1_1-introduction.md
@@ -7,6 +7,7 @@ fonts:
drawings:
persist: false
layout: cover
+routerMode: hash
---
diff --git a/slides/2_1-basic-syntax.md b/slides/2_1-basic-syntax.md
index 8c86c58..b2294c7 100644
--- a/slides/2_1-basic-syntax.md
+++ b/slides/2_1-basic-syntax.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 2.1: Basic Syntax"
+routerMode: hash
---
# Rust programming
diff --git a/slides/2_2-ownership-and-references.md b/slides/2_2-ownership-and-references.md
index 0313787..9be1ecf 100644
--- a/slides/2_2-ownership-and-references.md
+++ b/slides/2_2-ownership-and-references.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 2.2: Ownership and References"
+routerMode: hash
---
# Rust programming
diff --git a/slides/2_3-advanced-syntax.md b/slides/2_3-advanced-syntax.md
index db90af0..f683788 100644
--- a/slides/2_3-advanced-syntax.md
+++ b/slides/2_3-advanced-syntax.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 2.3: Advanced Syntax"
+routerMode: hash
---
# Rust programming
diff --git a/slides/2_4-traits-and-generics.md b/slides/2_4-traits-and-generics.md
index 355e80c..b430168 100644
--- a/slides/2_4-traits-and-generics.md
+++ b/slides/2_4-traits-and-generics.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 2.4: Traits and Generics"
+routerMode: hash
---
# Rust programming
diff --git a/slides/2_5-closures-and-dynamic-dispatch.md b/slides/2_5-closures-and-dynamic-dispatch.md
index 0fb1d8f..10be715 100644
--- a/slides/2_5-closures-and-dynamic-dispatch.md
+++ b/slides/2_5-closures-and-dynamic-dispatch.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 2.5: Closures and Dynamic dispatch"
+routerMode: hash
---
# Rust programming
diff --git a/slides/3_1-crate-engineering.md b/slides/3_1-crate-engineering.md
index 461ad1e..ed0e1f9 100644
--- a/slides/3_1-crate-engineering.md
+++ b/slides/3_1-crate-engineering.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 3.1: Crate Engineering"
+routerMode: hash
---
# Rust programming
diff --git a/slides/4_1-introduction-to-multitasking.md b/slides/4_1-introduction-to-multitasking.md
index 9b33541..b740db8 100644
--- a/slides/4_1-introduction-to-multitasking.md
+++ b/slides/4_1-introduction-to-multitasking.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 4.1: Introduction to Multitasking"
+routerMode: hash
---
# Rust programming
diff --git a/slides/4_2-parallel-multitasking.md b/slides/4_2-parallel-multitasking.md
index 9351b5b..1afe767 100644
--- a/slides/4_2-parallel-multitasking.md
+++ b/slides/4_2-parallel-multitasking.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 4.2: Parallel Multitasking"
+routerMode: hash
---
# Rust programming
diff --git a/slides/4_3-asynchronous-multitasking.md b/slides/4_3-asynchronous-multitasking.md
index ae454b4..285eddb 100644
--- a/slides/4_3-asynchronous-multitasking.md
+++ b/slides/4_3-asynchronous-multitasking.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 4.3: Asynchronous Multitasking"
+routerMode: hash
---
# Rust programming
diff --git a/slides/5_1-rust-for-web.md b/slides/5_1-rust-for-web.md
index 5e4b783..086d69d 100644
--- a/slides/5_1-rust-for-web.md
+++ b/slides/5_1-rust-for-web.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 5.1: Rust for Web"
+routerMode: hash
---
# Rust programming
diff --git a/slides/6_1-foreign-function-interface.md b/slides/6_1-foreign-function-interface.md
index 0f1a701..4f39aeb 100644
--- a/slides/6_1-foreign-function-interface.md
+++ b/slides/6_1-foreign-function-interface.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 6.1: Foreign Function Interface"
+routerMode: hash
---
# Rust programming
diff --git a/slides/7_1-rust-from-python.md b/slides/7_1-rust-from-python.md
index be71eb2..34d23f2 100644
--- a/slides/7_1-rust-from-python.md
+++ b/slides/7_1-rust-from-python.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 7.1: Calling Rust from Python"
+routerMode: hash
---
# Rust programming
diff --git a/slides/8_1-embedded-ecosystem.md b/slides/8_1-embedded-ecosystem.md
index df743e9..6fe263d 100644
--- a/slides/8_1-embedded-ecosystem.md
+++ b/slides/8_1-embedded-ecosystem.md
@@ -10,6 +10,7 @@ fonts:
mono: Fira Mono
layout: cover
title: "Rust - 8.1: The Rust Embedded Ecosystem"
+routerMode: hash
---