Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions csharp-book/src/ch05-data-structures-and-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions csharp-book/src/ch14-unsafe-rust-and-ffi.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions csharp-book/src/ch17-capstone-project.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions engineering-book/src/ch01-build-scripts-buildrs-in-depth.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
P1 --> RERUN["Always emit\ncargo::rerun-if-changed"]
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<br>cargo::rerun-if-changed"]
P2 --> RERUN
P3 --> RERUN
P4 --> RERUN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions engineering-book/src/ch03-benchmarking-measuring-what-matters.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
LLVM --> CI_GATE["CI coverage gate\n--fail-under-lines 80"]
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<br>--fail-under-lines 80"]
TARP --> CI_GATE

CI_GATE --> UPLOAD{"Upload to?"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions engineering-book/src/ch07-release-profiles-and-binary-size.md
Original file line number Diff line number Diff line change
Expand Up @@ -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'"]

Expand Down
10 changes: 5 additions & 5 deletions engineering-book/src/ch08-compile-time-and-developer-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 9 additions & 9 deletions engineering-book/src/ch09-no-std-and-feature-verification.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
USE_ALLOC --> VERIFY["cargo-hack\n--each-feature"]
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<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
Expand Down
18 changes: 9 additions & 9 deletions engineering-book/src/ch10-windows-and-conditional-compilation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)"]
TRAIT_APPROACH --> CI_CHECK["cargo-hack\n--each-feature"]
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<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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions python-book/src/ch03-built-in-types-and-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
4 changes: 2 additions & 2 deletions python-book/src/ch05-data-structures-and-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions python-book/src/ch06-enums-and-pattern-matching.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions python-book/src/ch07-ownership-and-borrowing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
```

Expand Down Expand Up @@ -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!"]
Expand Down
8 changes: 4 additions & 4 deletions python-book/src/ch09-error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading