Fix Mermaid diagrams: replace \n with <br/> for v10+ compatibility

Mermaid v10+ renders \n as literal text in node labels. Replace all
152 occurrences across 28 files with <br/> which produces proper
line breaks in the rendered diagrams.
This commit is contained in:
Atul Khare
2026-04-06 09:24:10 -07:00
parent 33768719fc
commit 9258adb9ff
27 changed files with 123 additions and 123 deletions
@@ -292,12 +292,12 @@ Structs in Rust are similar to classes in C#, but with some key differences arou
```mermaid
graph TD
subgraph "C# Class (Heap)"
CObj["Object Header\n+ vtable ptr"] --> CFields["Name: string ref\nAge: int\nHobbies: List ref"]
CObj["Object Header<br/>+ vtable ptr"] --> CFields["Name: string ref<br/>Age: int<br/>Hobbies: List ref"]
CFields --> CHeap1["#quot;Alice#quot; on heap"]
CFields --> CHeap2["List&lt;string&gt; on heap"]
end
subgraph "Rust Struct (Stack)"
RFields["name: String\n ptr | len | cap\nage: i32\nhobbies: Vec\n ptr | len | cap"]
RFields["name: String<br/> ptr | len | cap<br/>age: i32<br/>hobbies: Vec<br/> ptr | len | cap"]
RFields --> RHeap1["#quot;Alice#quot; heap buffer"]
RFields --> RHeap2["Vec heap buffer"]
end
+3 -3
View File
@@ -104,12 +104,12 @@ Rust can expose C-compatible functions that C# can call via P/Invoke.
```mermaid
graph LR
subgraph "C# Process"
CS["C# Code"] -->|"P/Invoke"| MI["Marshal Layer\nUTF-16 → UTF-8\nstruct layout"]
CS["C# Code"] -->|"P/Invoke"| MI["Marshal Layer<br/>UTF-16 → UTF-8<br/>struct layout"]
end
MI -->|"C ABI call"| FFI["FFI Boundary"]
subgraph "Rust cdylib (.so / .dll)"
FFI --> RF["extern \"C\" fn\n#[no_mangle]"]
RF --> Safe["Safe Rust\ninternals"]
FFI --> RF["extern \"C\" fn<br/>#[no_mangle]"]
RF --> Safe["Safe Rust<br/>internals"]
end
style FFI fill:#fff9c4,color:#000
+4 -4
View File
@@ -12,11 +12,11 @@ This capstone pulls together concepts from every part of the book. You'll build
```mermaid
graph TD
CLI["main.rs\nclap CLI parser"] --> Client["client.rs\nreqwest + tokio"]
CLI["main.rs<br/>clap CLI parser"] --> Client["client.rs<br/>reqwest + tokio"]
Client -->|"HTTP GET"| API["Weather API"]
Client -->|"JSON → struct"| Model["weather.rs\nserde Deserialize"]
Model --> Display["display.rs\nfmt::Display"]
CLI --> Err["error.rs\nthiserror"]
Client -->|"JSON → struct"| Model["weather.rs<br/>serde Deserialize"]
Model --> Display["display.rs<br/>fmt::Display"]
CLI --> Err["error.rs<br/>thiserror"]
Client --> Err
style CLI fill:#bbdefb,color:#000
@@ -544,13 +544,13 @@ flowchart TD
START["Need compile-time work?"] -->|No| SKIP["No build.rs needed"]
START -->|Yes| WHAT{"What kind?"}
WHAT -->|"Embed metadata"| P1["Pattern 1\nCompile-Time Constants"]
WHAT -->|"Compile C/C++"| P2["Pattern 2\ncc crate"]
WHAT -->|"Code generation"| P3["Pattern 3\nprost-build / tonic-build"]
WHAT -->|"Link system lib"| P4["Pattern 4\npkg-config"]
WHAT -->|"Detect features"| P5["Pattern 5\ncfg flags"]
WHAT -->|"Embed metadata"| P1["Pattern 1<br/>Compile-Time Constants"]
WHAT -->|"Compile C/C++"| P2["Pattern 2<br/>cc crate"]
WHAT -->|"Code generation"| P3["Pattern 3<br/>prost-build / tonic-build"]
WHAT -->|"Link system lib"| P4["Pattern 4<br/>pkg-config"]
WHAT -->|"Detect features"| P5["Pattern 5<br/>cfg flags"]
P1 --> RERUN["Always emit\ncargo::rerun-if-changed"]
P1 --> RERUN["Always emit<br/>cargo::rerun-if-changed"]
P2 --> RERUN
P3 --> RERUN
P4 --> RERUN
@@ -417,17 +417,17 @@ linker = "musl-gcc"
flowchart TD
START["Need to cross-compile?"] --> STATIC{"Static binary?"}
STATIC -->|Yes| MUSL["musl target\n--target x86_64-unknown-linux-musl"]
STATIC -->|Yes| MUSL["musl target<br/>--target x86_64-unknown-linux-musl"]
STATIC -->|No| GLIBC{"Need old glibc?"}
GLIBC -->|Yes| ZIG["cargo-zigbuild\n--target x86_64-unknown-linux-gnu.2.17"]
GLIBC -->|Yes| ZIG["cargo-zigbuild<br/>--target x86_64-unknown-linux-gnu.2.17"]
GLIBC -->|No| ARCH{"Target arch?"}
ARCH -->|"Same arch"| NATIVE["Native toolchain\nrustup target add + linker"]
ARCH -->|"Same arch"| NATIVE["Native toolchain<br/>rustup target add + linker"]
ARCH -->|"ARM/other"| DOCKER{"Docker available?"}
DOCKER -->|Yes| CROSS["cross build\nDocker-based, zero setup"]
DOCKER -->|No| MANUAL["Manual sysroot\napt install gcc-aarch64-linux-gnu"]
DOCKER -->|Yes| CROSS["cross build<br/>Docker-based, zero setup"]
DOCKER -->|No| MANUAL["Manual sysroot<br/>apt install gcc-aarch64-linux-gnu"]
style MUSL fill:#91e5a3,color:#000
style ZIG fill:#91e5a3,color:#000
@@ -440,13 +440,13 @@ criterion_main!(benches);
flowchart TD
START["Want to measure performance?"] --> WHAT{"What level?"}
WHAT -->|"Single function"| CRITERION["Criterion.rs\nStatistical, regression detection"]
WHAT -->|"Quick function check"| DIVAN["Divan\nLighter, attribute macros"]
WHAT -->|"Whole binary"| HYPERFINE["hyperfine\nEnd-to-end, wall-clock"]
WHAT -->|"Find hot spots"| PERF["perf + flamegraph\nCPU sampling profiler"]
WHAT -->|"Single function"| CRITERION["Criterion.rs<br/>Statistical, regression detection"]
WHAT -->|"Quick function check"| DIVAN["Divan<br/>Lighter, attribute macros"]
WHAT -->|"Whole binary"| HYPERFINE["hyperfine<br/>End-to-end, wall-clock"]
WHAT -->|"Find hot spots"| PERF["perf + flamegraph<br/>CPU sampling profiler"]
CRITERION --> CI_BENCH["Continuous benchmarking\nin GitHub Actions"]
PERF --> OPTIMIZE["Profile-Guided\nOptimization (PGO)"]
CRITERION --> CI_BENCH["Continuous benchmarking<br/>in GitHub Actions"]
PERF --> OPTIMIZE["Profile-Guided<br/>Optimization (PGO)"]
style CRITERION fill:#91e5a3,color:#000
style DIVAN fill:#91e5a3,color:#000
@@ -381,11 +381,11 @@ done
flowchart TD
START["Need code coverage?"] --> ACCURACY{"Priority?"}
ACCURACY -->|"Most accurate"| LLVM["cargo-llvm-cov\nSource-based, compiler-native"]
ACCURACY -->|"Quick check"| TARP["cargo-tarpaulin\nLinux only, fast"]
ACCURACY -->|"Multi-run aggregate"| GRCOV["grcov\nMozilla, combines profiles"]
ACCURACY -->|"Most accurate"| LLVM["cargo-llvm-cov<br/>Source-based, compiler-native"]
ACCURACY -->|"Quick check"| TARP["cargo-tarpaulin<br/>Linux only, fast"]
ACCURACY -->|"Multi-run aggregate"| GRCOV["grcov<br/>Mozilla, combines profiles"]
LLVM --> CI_GATE["CI coverage gate\n--fail-under-lines 80"]
LLVM --> CI_GATE["CI coverage gate<br/>--fail-under-lines 80"]
TARP --> CI_GATE
CI_GATE --> UPLOAD{"Upload to?"}
@@ -575,15 +575,15 @@ Least overhead Most thorough
```mermaid
flowchart TD
START["Have unsafe code?"] -->|No| SAFE["Safe Rust — no\nverification needed"]
START["Have unsafe code?"] -->|No| SAFE["Safe Rust — no<br/>verification needed"]
START -->|Yes| KIND{"What kind?"}
KIND -->|"Pure Rust unsafe"| MIRI["Miri\nMIR interpreter\ncatches aliasing, UB, leaks"]
KIND -->|"FFI / C interop"| VALGRIND["Valgrind memcheck\nor ASan"]
KIND -->|"Pure Rust unsafe"| MIRI["Miri<br/>MIR interpreter<br/>catches aliasing, UB, leaks"]
KIND -->|"FFI / C interop"| VALGRIND["Valgrind memcheck<br/>or ASan"]
KIND -->|"Concurrent unsafe"| CONC{"Lock-free?"}
CONC -->|"Atomics/lock-free"| LOOM["loom\nModel checker for atomics"]
CONC -->|"Mutex/shared state"| TSAN["TSan or\nMiri -Zmiri-check-number-validity"]
CONC -->|"Atomics/lock-free"| LOOM["loom<br/>Model checker for atomics"]
CONC -->|"Mutex/shared state"| TSAN["TSan or<br/>Miri -Zmiri-check-number-validity"]
MIRI --> CI_MIRI["CI: cargo +nightly miri test"]
VALGRIND --> CI_VALGRIND["CI: valgrind --leak-check=full"]
@@ -317,10 +317,10 @@ unknown-git = "deny"
```mermaid
flowchart LR
PR["Pull Request"] --> AUDIT["cargo audit\nKnown CVEs"]
AUDIT --> DENY["cargo deny check\nLicenses + Bans + Sources"]
DENY --> OUTDATED["cargo outdated\nWeekly schedule"]
OUTDATED --> SEMVER["cargo semver-checks\nLibrary crates only"]
PR["Pull Request"] --> AUDIT["cargo audit<br/>Known CVEs"]
AUDIT --> DENY["cargo deny check<br/>Licenses + Bans + Sources"]
DENY --> OUTDATED["cargo outdated<br/>Weekly schedule"]
OUTDATED --> SEMVER["cargo semver-checks<br/>Library crates only"]
AUDIT -->|"Fail"| BLOCK["❌ Block merge"]
DENY -->|"Fail"| BLOCK
@@ -252,13 +252,13 @@ cargo shear --fix
```mermaid
flowchart TD
START["Binary too large?"] --> STRIP{"strip = true?"}
STRIP -->|"No"| DO_STRIP["Add strip = true\n-50 to -70% size"]
STRIP -->|"No"| DO_STRIP["Add strip = true<br/>-50 to -70% size"]
STRIP -->|"Yes"| LTO{"LTO enabled?"}
LTO -->|"No"| DO_LTO["Add lto = true\ncodegen-units = 1"]
LTO -->|"Yes"| BLOAT["Run cargo-bloat\n--crates"]
LTO -->|"No"| DO_LTO["Add lto = true<br/>codegen-units = 1"]
LTO -->|"Yes"| BLOAT["Run cargo-bloat<br/>--crates"]
BLOAT --> BIG_DEP{"Large dependency?"}
BIG_DEP -->|"Yes"| REPLACE["Replace with lighter\nalternative or disable\ndefault features"]
BIG_DEP -->|"No"| UDEPS["cargo-udeps\nRemove unused deps"]
BIG_DEP -->|"Yes"| REPLACE["Replace with lighter<br/>alternative or disable<br/>default features"]
BIG_DEP -->|"No"| UDEPS["cargo-udeps<br/>Remove unused deps"]
UDEPS --> OPT_LEVEL{"Need smaller?"}
OPT_LEVEL -->|"Yes"| SIZE_OPT["opt-level = 's' or 'z'"]
@@ -418,14 +418,14 @@ pub fn get_battery_status() -> Option<u8> {
flowchart TD
START["Compile too slow?"] --> WHERE{"Where's the time?"}
WHERE -->|"Recompiling\nunchanged crates"| SCCACHE["sccache\nShared compilation cache"]
WHERE -->|"Linking phase"| MOLD["mold linker\n3-10× faster linking"]
WHERE -->|"Running tests"| NEXTEST["cargo-nextest\nParallel test runner"]
WHERE -->|"Everything"| COMBO["All of the above +\ncargo-udeps to trim deps"]
WHERE -->|"Recompiling<br/>unchanged crates"| SCCACHE["sccache<br/>Shared compilation cache"]
WHERE -->|"Linking phase"| MOLD["mold linker<br/>3-10× faster linking"]
WHERE -->|"Running tests"| NEXTEST["cargo-nextest<br/>Parallel test runner"]
WHERE -->|"Everything"| COMBO["All of the above +<br/>cargo-udeps to trim deps"]
SCCACHE --> CI_CACHE{"CI or local?"}
CI_CACHE -->|"CI"| S3["S3/GCS shared cache"]
CI_CACHE -->|"Local"| LOCAL["Local disk cache\nauto-configured"]
CI_CACHE -->|"Local"| LOCAL["Local disk cache<br/>auto-configured"]
style SCCACHE fill:#91e5a3,color:#000
style MOLD fill:#e3f2fd,color:#000
@@ -352,18 +352,18 @@ cargo check --target riscv32imac-unknown-none-elf # RISC-V
```mermaid
flowchart TD
START["Does your code need\nthe standard library?"] --> NEED_FS{"File system,\nnetwork, threads?"}
NEED_FS -->|"Yes"| USE_STD["Use std\nNormal application"]
NEED_FS -->|"No"| NEED_HEAP{"Need heap allocation?\nVec, String, Box"}
NEED_HEAP -->|"Yes"| USE_ALLOC["#![no_std]\nextern crate alloc"]
NEED_HEAP -->|"No"| USE_CORE["#![no_std]\ncore only"]
START["Does your code need<br/>the standard library?"] --> NEED_FS{"File system,<br/>network, threads?"}
NEED_FS -->|"Yes"| USE_STD["Use std<br/>Normal application"]
NEED_FS -->|"No"| NEED_HEAP{"Need heap allocation?<br/>Vec, String, Box"}
NEED_HEAP -->|"Yes"| USE_ALLOC["#![no_std]<br/>extern crate alloc"]
NEED_HEAP -->|"No"| USE_CORE["#![no_std]<br/>core only"]
USE_ALLOC --> VERIFY["cargo-hack\n--each-feature"]
USE_ALLOC --> VERIFY["cargo-hack<br/>--each-feature"]
USE_CORE --> VERIFY
USE_STD --> VERIFY
VERIFY --> TARGET{"Target has OS?"}
TARGET -->|"Yes"| HOST_TEST["cargo test --lib\nStandard testing"]
TARGET -->|"No"| CROSS_TEST["QEMU / defmt-test\nOn-device testing"]
TARGET -->|"Yes"| HOST_TEST["cargo test --lib<br/>Standard testing"]
TARGET -->|"No"| CROSS_TEST["QEMU / defmt-test<br/>On-device testing"]
style USE_STD fill:#91e5a3,color:#000
style USE_ALLOC fill:#ffd43b,color:#000
@@ -374,17 +374,17 @@ implementation is complete — catching `cfg` mistakes early.
flowchart TD
START["Platform-specific code?"] --> HOW_MANY{"How many platforms?"}
HOW_MANY -->|"2 (Linux + Windows)"| CFG_BLOCKS["#[cfg] blocks\nin leaf functions"]
HOW_MANY -->|"3+"| TRAIT_APPROACH["Platform trait\n+ per-platform impl"]
HOW_MANY -->|"2 (Linux + Windows)"| CFG_BLOCKS["#[cfg] blocks<br/>in leaf functions"]
HOW_MANY -->|"3+"| TRAIT_APPROACH["Platform trait<br/>+ per-platform impl"]
CFG_BLOCKS --> WINAPI{"Need Windows APIs?"}
WINAPI -->|"Minimal"| WIN_SYS["windows-sys\nRaw FFI bindings"]
WINAPI -->|"Rich (COM, etc)"| WIN_RS["windows crate\nSafe idiomatic wrappers"]
WINAPI -->|"None\n(just #[cfg])"| NATIVE["cfg(windows)\ncfg(unix)"]
WINAPI -->|"Minimal"| WIN_SYS["windows-sys<br/>Raw FFI bindings"]
WINAPI -->|"Rich (COM, etc)"| WIN_RS["windows crate<br/>Safe idiomatic wrappers"]
WINAPI -->|"None<br/>(just #[cfg])"| NATIVE["cfg(windows)<br/>cfg(unix)"]
TRAIT_APPROACH --> CI_CHECK["cargo-hack\n--each-feature"]
TRAIT_APPROACH --> CI_CHECK["cargo-hack<br/>--each-feature"]
CFG_BLOCKS --> CI_CHECK
CI_CHECK --> XCOMPILE["Cross-compile in CI\ncargo-xwin or\nnative runners"]
CI_CHECK --> XCOMPILE["Cross-compile in CI<br/>cargo-xwin or<br/>native runners"]
style CFG_BLOCKS fill:#91e5a3,color:#000
style TRAIT_APPROACH fill:#ffd43b,color:#000
@@ -545,27 +545,27 @@ shows your release targets. You now have a production-grade Rust pipeline.
```mermaid
flowchart LR
subgraph "Stage 1 — Fast Feedback < 2 min"
CHECK["cargo check\ncargo clippy\ncargo fmt"]
CHECK["cargo check<br/>cargo clippy<br/>cargo fmt"]
end
subgraph "Stage 2 — Tests < 5 min"
TEST["cargo nextest\ncargo test --doc"]
TEST["cargo nextest<br/>cargo test --doc"]
end
subgraph "Stage 3 — Coverage"
COV["cargo llvm-cov\nfail-under 80%"]
COV["cargo llvm-cov<br/>fail-under 80%"]
end
subgraph "Stage 4 — Security"
SEC["cargo audit\ncargo deny check"]
SEC["cargo audit<br/>cargo deny check"]
end
subgraph "Stage 5 — Cross-Build"
CROSS["musl static\naarch64 + x86_64"]
CROSS["musl static<br/>aarch64 + x86_64"]
end
subgraph "Stage 6 — Release (tag only)"
REL["cargo dist\nGitHub Release"]
REL["cargo dist<br/>GitHub Release"]
end
CHECK --> TEST --> COV --> SEC --> CROSS --> REL
@@ -102,13 +102,13 @@ fn main() {
```mermaid
flowchart LR
subgraph Python ["Python Types"]
PI["int\n(arbitrary precision)"]
PF["float\n(64-bit only)"]
PI["int<br/>(arbitrary precision)"]
PF["float<br/>(64-bit only)"]
PB["bool"]
PS["str\n(Unicode)"]
PS["str<br/>(Unicode)"]
end
subgraph Rust ["Rust Types"]
RI["i8 / i16 / i32 / i64 / i128\nu8 / u16 / u32 / u64 / u128"]
RI["i8 / i16 / i32 / i64 / i128<br/>u8 / u16 / u32 / u64 / u128"]
RF["f32 / f64"]
RB["bool"]
RS["String / &str"]
@@ -191,12 +191,12 @@ fn main() {
```mermaid
flowchart LR
subgraph Python ["Python Object (Heap)"]
PH["PyObject Header\n(refcount + type ptr)"] --> PW["width: float obj"]
PH["PyObject Header<br/>(refcount + type ptr)"] --> PW["width: float obj"]
PH --> PHT["height: float obj"]
PH --> PD["__dict__"]
end
subgraph Rust ["Rust Struct (Stack)"]
RW["width: f64\n(8 bytes)"] --- RH["height: f64\n(8 bytes)"]
RW["width: f64<br/>(8 bytes)"] --- RH["height: f64<br/>(8 bytes)"]
end
style Python fill:#ffeeba
style Rust fill:#d4edda
@@ -113,10 +113,10 @@ enum Message {
```mermaid
flowchart TD
E["enum Message"] --> T["Text(String)\n🏷️ tag=0 + String data"]
E --> I["Image { url, width, height }\n🏷️ tag=1 + 3 fields"]
E --> Q["Quit\n🏷️ tag=2 + no data"]
E --> M["Move { x, y }\n🏷️ tag=3 + 2 fields"]
E["enum Message"] --> T["Text(String)<br/>🏷️ tag=0 + String data"]
E --> I["Image { url, width, height }<br/>🏷️ tag=1 + 3 fields"]
E --> Q["Quit<br/>🏷️ tag=2 + no data"]
E --> M["Move { x, y }<br/>🏷️ tag=3 + 2 fields"]
style E fill:#d4edda,stroke:#28a745
style T fill:#fff3cd
style I fill:#fff3cd
@@ -99,13 +99,13 @@ stateDiagram-v2
a_owns --> shared: b = a
shared --> b_only: del a (refcount 2→1)
b_only --> freed: del b (refcount 1→0)
note right of shared: Both a and b point\nto the SAME object
note right of shared: Both a and b point<br/>to the SAME object
}
state "Rust (Ownership Move)" as RS {
[*] --> a_owns2: let a = vec![1,2,3]
a_owns2 --> b_owns: let b = a (MOVE)
b_owns --> freed2: b goes out of scope
note right of b_owns: a is INVALID after move\nCompile error if used
note right of b_owns: a is INVALID after move<br/>Compile error if used
}
```
@@ -203,9 +203,9 @@ Rust: One person owns the book. Others can:
```mermaid
flowchart TD
R["Borrowing Rules"] --> IMM["✅ Many &T\n(shared/immutable)"]
R --> MUT["✅ One &mut T\n(exclusive/mutable)"]
R --> CONFLICT["❌ &T + &mut T\n(NEVER at same time)"]
R["Borrowing Rules"] --> IMM["✅ Many &T<br/>(shared/immutable)"]
R --> MUT["✅ One &mut T<br/>(exclusive/mutable)"]
R --> CONFLICT["❌ &T + &mut T<br/>(NEVER at same time)"]
IMM --> SAFE["Multiple readers, safe"]
MUT --> SAFE2["Single writer, safe"]
CONFLICT --> ERR["Compile error!"]
+4 -4
View File
@@ -194,10 +194,10 @@ flowchart TD
```mermaid
graph TD
AE["AppError (enum)"] --> NF["NotFound\n{ entity, id }"]
AE --> VE["Validation\n{ field, message }"]
AE --> IO["Io(std::io::Error)\n#[from]"]
AE --> JSON["Json(serde_json::Error)\n#[from]"]
AE["AppError (enum)"] --> NF["NotFound<br/>{ entity, id }"]
AE --> VE["Validation<br/>{ field, message }"]
AE --> IO["Io(std::io::Error)<br/>#[from]"]
AE --> JSON["Json(serde_json::Error)<br/>#[from]"]
IO2["std::io::Error"] -->|"auto-convert via From"| IO
JSON2["serde_json::Error"] -->|"auto-convert via From"| JSON
style AE fill:#d4edda,stroke:#28a745
@@ -173,10 +173,10 @@ flat = [item for sublist in nested for item in sublist]
```mermaid
flowchart LR
A["Source\n[1,2,3,4,5]"] -->|.iter\(\)| B["Iterator"]
A["Source<br/>[1,2,3,4,5]"] -->|.iter\(\)| B["Iterator"]
B -->|.filter\(\|x\| x%2==0\)| C["[2, 4]"]
C -->|.map\(\|x\| x*x\)| D["[4, 16]"]
D -->|.collect\(\)| E["Vec&lt;i32&gt;\n[4, 16]"]
D -->|.collect\(\)| E["Vec&lt;i32&gt;<br/>[4, 16]"]
style A fill:#ffeeba
style E fill:#d4edda
```
+4 -4
View File
@@ -252,10 +252,10 @@ let db_host = get_config()["database"]["host"].as_str().unwrap();
```mermaid
flowchart LR
A["1️⃣ Profile Python\n(find hotspots)"] --> B["2️⃣ Write Rust Extension\n(PyO3 + maturin)"]
B --> C["3️⃣ Replace Python Call\n(same API)"]
C --> D["4️⃣ Expand Gradually\n(more functions)"]
D --> E{"Full rewrite\nworth it?"}
A["1️⃣ Profile Python<br/>(find hotspots)"] --> B["2️⃣ Write Rust Extension<br/>(PyO3 + maturin)"]
B --> C["3️⃣ Replace Python Call<br/>(same API)"]
C --> D["4️⃣ Expand Gradually<br/>(more functions)"]
D --> E{"Full rewrite<br/>worth it?"}
E -->|Yes| F["Pure Rust🦀"]
E -->|No| G["Hybrid🐍+🦀"]
style A fill:#ffeeba
+4 -4
View File
@@ -7,10 +7,10 @@
```mermaid
flowchart LR
A["🟢 Week 1-2\nFoundations\n'Why won't this compile?'"] --> B["🟡 Week 3-4\nCore Concepts\n'Oh, it's protecting me'"]
B --> C["🟡 Month 2\nIntermediate\n'I see why this matters'"]
C --> D["🔴 Month 3+\nAdvanced\n'Caught a bug at compile time!'"]
D --> E["🏆 Month 6\nFluent\n'Better programmer everywhere'"]
A["🟢 Week 1-2<br/>Foundations<br/>'Why won't this compile?'"] --> B["🟡 Week 3-4<br/>Core Concepts<br/>'Oh, it's protecting me'"]
B --> C["🟡 Month 2<br/>Intermediate<br/>'I see why this matters'"]
C --> D["🔴 Month 3+<br/>Advanced<br/>'Caught a bug at compile time!'"]
D --> E["🏆 Month 6<br/>Fluent<br/>'Better programmer everywhere'"]
style A fill:#d4edda
style B fill:#fff3cd
style C fill:#fff3cd
@@ -793,8 +793,8 @@ combination — is two-dimensional:
block-beta
columns 4
space header1["Locked"] header2["Unlocked"] header3["ExtendedUnlocked"]
basic["Basic Vendor"]:1 b1["unlock()"] b2["read_reg()\nwrite_reg()"] b3["— unreachable —"]
memory["Memory Vendor"]:1 m1["unlock()"] m2["read_reg()\nwrite_reg()\nextended_unlock()"] m3["read_reg()\nwrite_reg()\nread_memory()\nwrite_memory()"]
basic["Basic Vendor"]:1 b1["unlock()"] b2["read_reg()<br/>write_reg()"] b3["— unreachable —"]
memory["Memory Vendor"]:1 m1["unlock()"] m2["read_reg()<br/>write_reg()<br/>extended_unlock()"] m3["read_reg()<br/>write_reg()<br/>read_memory()<br/>write_memory()"]
style b1 fill:#ffd,stroke:#aa0
style b2 fill:#efe,stroke:#3a3
@@ -300,14 +300,14 @@ No functional equivalent is cleaner. The loop with `match state` is the natural
flowchart TB
START{What are you doing?}
START -->|"Transforming a collection\ninto another collection"| PIPE[Use iterator chain]
START -->|"Computing a single value\nfrom a collection"| AGG{How complex?}
START -->|"Multiple outputs from\none pass"| LOOP[Use a for loop]
START -->|"State machine with\nI/O or side effects"| LOOP
START -->|"One Option/Result\ntransform + default"| COMB[Use combinators]
START -->|"Transforming a collection<br/>into another collection"| PIPE[Use iterator chain]
START -->|"Computing a single value<br/>from a collection"| AGG{How complex?}
START -->|"Multiple outputs from<br/>one pass"| LOOP[Use a for loop]
START -->|"State machine with<br/>I/O or side effects"| LOOP
START -->|"One Option/Result<br/>transform + default"| COMB[Use combinators]
AGG -->|"Sum, count, min, max"| BUILTIN["Use .sum(), .count(),\n.min(), .max()"]
AGG -->|"Custom accumulation"| FOLD{Accumulator has mutation\nor side effects?}
AGG -->|"Sum, count, min, max"| BUILTIN["Use .sum(), .count(),<br/>.min(), .max()"]
AGG -->|"Custom accumulation"| FOLD{Accumulator has mutation<br/>or side effects?}
FOLD -->|"No"| FOLDF["Use .fold()"]
FOLD -->|"Yes"| LOOP
@@ -315,7 +315,7 @@ fn sensor_workflow() -> io::Result<()> {
flowchart LR
N["Nonce::new()"] -->|move| E["encrypt(nonce, msg)"]
E -->|consumed| X["❌ nonce gone"]
N -.->|"reuse attempt"| ERR["COMPILE ERROR:\nuse of moved value"]
N -.->|"reuse attempt"| ERR["COMPILE ERROR:<br/>use of moved value"]
style N fill:#e1f5fe,color:#000
style E fill:#c8e6c9,color:#000
style X fill:#ffcdd2,color:#000
@@ -1266,12 +1266,12 @@ bytes to Redfish-ready health values:
```mermaid
flowchart LR
RAW["Raw [u8; 16]\nSEL entries"]
PARSE["TryFrom:\nValidSelRecord\n(enum tree)"]
CLASSIFY["classify_event_health\n(exhaustive match)"]
LINEARIZE["SDR linearize\nraw → Celsius/Rpm/Watts"]
SUMMARY["TypedSelSummary\n(per-subsystem health\n+ dimensional readings)"]
REDFISH["ch18: health rollup\n→ Status.Health JSON"]
RAW["Raw [u8; 16]<br/>SEL entries"]
PARSE["TryFrom:<br/>ValidSelRecord<br/>(enum tree)"]
CLASSIFY["classify_event_health<br/>(exhaustive match)"]
LINEARIZE["SDR linearize<br/>raw → Celsius/Rpm/Watts"]
SUMMARY["TypedSelSummary<br/>(per-subsystem health<br/>+ dimensional readings)"]
REDFISH["ch18: health rollup<br/>→ Status.Health JSON"]
RAW -->|"ch07 §Parse"| PARSE
PARSE -->|"typed events"| CLASSIFY
@@ -18,17 +18,17 @@ A single `GET /redfish/v1/Systems/1` response must fuse data from many sources:
```mermaid
flowchart LR
subgraph Sources
SMBIOS["SMBIOS\nType 1, Type 17"]
SDR["IPMI Sensors\n(SDR + readings)"]
SEL["IPMI SEL\n(critical events)"]
PCIe["PCIe Config\nSpace"]
FW["Firmware\nVersion Table"]
PWR["Power State\nRegister"]
SMBIOS["SMBIOS<br/>Type 1, Type 17"]
SDR["IPMI Sensors<br/>(SDR + readings)"]
SEL["IPMI SEL<br/>(critical events)"]
PCIe["PCIe Config<br/>Space"]
FW["Firmware<br/>Version Table"]
PWR["Power State<br/>Register"]
end
subgraph Server["Redfish Server"]
Handler["GET handler"]
Builder["ComputerSystem\nBuilder"]
Builder["ComputerSystem<br/>Builder"]
end
SMBIOS -->|"Name, UUID, Serial"| Handler
@@ -38,7 +38,7 @@ flowchart LR
FW -->|"BIOS version"| Handler
PWR -->|"PowerState"| Handler
Handler --> Builder
Builder -->|".build()"| JSON["Schema-compliant\nJSON response"]
Builder -->|".build()"| JSON["Schema-compliant<br/>JSON response"]
style JSON fill:#c8e6c9,color:#000
style Builder fill:#e1f5fe,color:#000