Learn Rust & egui by Building a Schematic & PCB Design Reviewer

A hands-on, mutation-tested engineering course from immediate-mode fundamentals to an engine-first CAD architecture

Learning a new GUI framework from toy counter apps is easy. Building a real tool with a 2D CAD canvas, spatial hit-testing, and undo history is where things get interesting.

So, in this course, we are going to learn Rust and Emil Ernerfeldt's egui by building a Schematic & PCB Design Reviewer from scratch.Every lesson in this repository pairs an interactive HTML tutorial (with live in-browser simulators, code-completion labs, and retrieval quizzes) with a real, runnable Cargo project under ./apps/<NNNN-slug>/. Each lesson introduces one focused egui capability alongside one just-in-time Rust concept—and because we like keeping our sanity as the codebase grows, we verify our assertions continuously with cargo test and Martin Pool's cargo-mutants.

flowchart LR
  L0["0001–0002\nFoundation & IMGUI Loop"] --> A1["Act I (0003–0006)\n2D CAD Canvas & Hit-Testing"]
  A1 --> A2["Act II (0007–0010)\nSchematics & egui_kittest"]
  A2 --> A3["Act III (0011–0014)\nDRC Overlays & Review Pins"]
  A3 --> A4["Act IV (0015–0018)\nMulti-Crate CoW Engine"]
  A4 --> A5["Act V (0019–0022)\nCommand Engine, Culling & Snapshots"]
  A5 --> A6["Act VI (0023–0026)\nKiCad nom Parser & Turso SQL"]
  A6 --> A7["Act VII (0027–0030)\nMCP Server (rmcp) & Agent Workbench"]
  

Multi-Act Curriculum Progression: Every lesson builds toward an engine-first, AI-controllable Schematic & PCB Design Review System verified with unit tests and mutation coverage.

Published Interactive Lessons (0001–0030)

Start with Lesson 0001 to set up your Cargo project and mutation-testing harness, or jump directly to any section using the curriculum table of contents below:

Foundation: Project Setup & Immediate-Mode Core (0001–0002)

Every hardware review tool starts with a reliable application shell and a clear understanding of how immediate-mode GUIs manage state. In this foundational module, we configure a high-performance Cargo project with dev-profile optimizations, boot a native desktop window with eframe::run_native, and explore Emil Ernerfeldt’s single-frame immediate-mode loop (eframe::App::ui) by building an interactive PCB layer visibility inspector backed by mutation testing.

Lesson 0001 1 / 1 Mutants Caught

Bootstrapping Your Rust & eframe Project

Create the Cargo package, configure dev-profile optimisation for 60 FPS rendering, boot a native window with eframe::run_native, and catch your first mutant.

egui Skill: eframe::run_native & ViewportBuilder Rust Concept: impl Default, Box::new, #[cfg(test)] Runnable App: apps/0001-project-setup-and-eframe-boot
Lesson 0002 3 / 3 Mutants Caught

The Immediate-Mode Loop & Mutable State (&mut)

Drive a PCB Layer Inspector sidebar with Panel::left, CentralPanel, ui.checkbox, and pure state-transition methods verified by unit and mutation tests.

egui Skill: App::ui, Panel::left, ui.checkbox Rust Concept: Mutable borrows (&mut self) & closures (|ui|) Runnable App: apps/0002-the-immediate-mode-loop

Act I: The 2D CAD Canvas & Viewport (0003–0006)

With a native window running, Act I transforms an empty CentralPanel into a responsive 2D CAD canvas. We reserve custom drawing space with ui.allocate_painter, master world-to-screen camera math for drag-panning and cursor-centered zoom, build deterministic multi-layer PCB models (substrate, copper traces, SMD pads, and vias), and implement spatial hit-testing for cross-probing interconnected nets under the mouse cursor.

Lesson 0003 23 / 23 Mutants Caught

Custom 2D Canvas & Drawing Primitives with Painter

Reserve an interactive 2D CAD viewport with ui.allocate_painter and render PCB substrate outlines, SMD pads, copper traces, and drill vias.

egui Skill: ui.allocate_painter, Rect, Pos2, Stroke Rust Concept: Value semantics (Copy) & pure geometry helpers Runnable App: apps/0003-custom-2d-canvas-and-painter
Lesson 0004 14 / 14 Mutants Caught

World-to-Screen Transforms, Drag Panning & Cursor-Centred Zoom

Map physical board millimetres to screen points using TSTransform, pan with Sense::drag(), and zoom smoothly around the cursor position.

egui Skill: TSTransform, Sense::drag(), ctx.input Rust Concept: Encapsulating maths on BoardViewport & f32::clamp Runnable App: apps/0004-world-to-screen-transforms-pan-and-zoom
Lesson 0005 20 / 20 Mutants Caught

Modelling PCB Layers, Traces & Deterministic Z-Ordering

Model multi-layer board primitives with a strongly-typed PcbLayer enum and sort visible traces in deterministic back-to-front Z-order.

egui Skill: Multi-layer painter batching & Z-order rendering Rust Concept: enum, exhaustive match, Vec<T> & slices Runnable App: apps/0005-modeling-layers-traces-and-footprints
Lesson 0006 25 / 25 Mutants Caught

Spatial Hit-Testing, Selection State & Net Cross-Probing

Convert pointer coordinates back into physical millimetres, hit-test SMD pads in reverse Z-order, highlight connected nets, and populate the Net Inspector.

egui Skill: Sense::click_and_drag(), hover vs. locked selection Rust Concept: Option<NetId>, if let Some(...), .or(...) Runnable App: apps/0006-hit-testing-and-net-cross-probing

Act II: Schematic Views, Layout & egui_kittest (0007–0010)

Act II bridges PCB layouts with schematic diagrams and inspector tooling. We render vector schematic symbols and reference designators, coordinate side-by-side viewports with shared egui::Scene navigation, build a virtualized Bill of Materials (BOM) table that scales to thousands of components, implement keyboard shortcuts and an interactive point-to-point CAD ruler, and verify headless UI widgets using egui_kittest.

Lesson 0007 35 / 35 Mutants Caught

Schematic Symbols, Text Rendering & Headless UI Verification (egui_kittest)

Render silkscreen IC reference designators (U1, R12, J1) and net names using Painter::text, FontId, and Align2, and boot your app headlessly with egui_kittest::Harness.

egui Skill: Painter::text, FontId, Align2, egui_kittest Rust Concept: Owned String vs. borrowed &str & format!(...) Runnable App: apps/0007-schematic-symbols-and-text-rendering
Lesson 0008 40 / 40 Mutants Caught

Split Viewports, egui::Scene & Schematic-to-PCB Cross-Probing

Add a top schematic symbol bar with Panel::top, wrap the 2D board in egui::Scene, and cross-probe schematic components to centre the PCB camera rectangle.

egui Skill: Panel::top, egui::Scene, camera focusing Rust Concept: Disjoint struct borrows (&BoardModel vs. &mut ViewState) Runnable App: apps/0008-split-viewports-and-egui-scene
Lesson 0009 47 / 47 Mutants Caught

Searchable Netlist, Virtualised BOM & Iterator Adapters

Filter components and nets live with TextEdit::singleline, lay out virtualised rows using ScrollArea::show_rows and egui::Grid, and catch boolean filter mutants.

egui Skill: TextEdit::singleline, ScrollArea::show_rows, Grid Rust Concept: Iterator adapters (.filter()), slices & case-insensitive search Runnable App: apps/0009-searchable-netlist-and-bom-inspector
Lesson 0010 59 / 59 Mutants Caught

Keyboard Shortcuts (F, M, Esc) & Point-to-Point CAD Ruler

Consume single-key CAD shortcuts with ctx.input_mut and consume_key, model tool states with data-carrying enums, and render a live Δx / Δy distance ruler.

egui Skill: InputState::consume_key, Key, CAD ruler overlay Rust Concept: Data-carrying enums (enum ActiveTool) & pattern matching Runnable App: apps/0010-keyboard-shortcuts-and-point-to-point-ruler

Act III: Design Review Workflows (0011–0014)

Hardware design reviews require contextual annotations and clearance rule checks. Act III builds production review workflows: pinning interactive callout comments directly onto board coordinates, orchestrating a triage state machine with right-click context menus and severity filters, rendering Design Rule Check (DRC) violation halos with an interactive minimap, and packaging custom reusable egui::Widget layer swatches.

Lesson 0011 72 / 72 Mutants Caught

Review Pins, HashMap Entry API & Callouts

Drop engineering review pins anchored to (x, y) board coordinates (mm), guard against duplicate IDs with HashMap::entry, and inspect notes in floating egui::Window callouts.

egui Skill: egui::Window, egui::Id::unique & Key::P tool Rust Concept: HashMap<PinId, ReviewNote>, Hash + Eq & Entry API Runnable App: apps/0011-review-pins-and-sticky-note-callouts
Lesson 0012 88 / 88 Mutants Caught

Review Status Triage & Severity Filtering

Triage engineering review pins through an Open → Resolved → Verified state machine, filter by severity using static enum slices, and verify all transition and boolean filter branches.

egui Skill: ui.selectable_value & interactive callout triage Rust Concept: &'static [Self] enum constants & transition guards Runnable App: apps/0012-review-status-workflow-and-popups
Lesson 0013 125 / 125 Mutants Caught

DRC Violation Halos & Minimap Clamping

Compute Euclidean edge-to-edge copper pad clearance, highlight Design Rule Check (DRC) violations on the canvas, and clamp bird's-eye minimap camera bounds.

egui Skill: painter.circle_stroke DRC halos & camera jump Rust Concept: Iterator::reduce(Rect::union) & f32::clamp Runnable App: apps/0013-drc-violation-overlay-and-minimap
Lesson 0014 134 / 134 Mutants Caught

Custom egui::Widget Layer Swatches & Lifetimes

Build a reusable LayerSwatch<'a> implementing egui::Widget (colour swatch + visibility toggle + opacity slider) and test it standalone with Harness::new_ui_state.

egui Skill: impl<'a> egui::Widget for LayerSwatch<'a> & ui.add(...) Rust Concept: Struct lifetimes ('a) & implementing foreign traits Runnable App: apps/0014-custom-layer-swatch-widget-and-design-tokens

Act IV: Engine-First Architecture & Persistence (0015–0018)

As applications grow, UI code must separate from pure domain logic. Act IV refactors our single-file app into a strict multi-crate workspace (pcb-doc L1 vs. pcb-reviewer L6), introduces robust JSON serialization and file format upgrades with serde and thiserror, adopts copy-on-write Arc document snapshots for $O(1)$ zero-cost branching, and implements a multi-level undo/redo history stack with slider drag coalescing.

Lesson 0015 144 / 144 Caught

Multi-Crate Workspace (pcb-doc L1 vs. pcb-reviewer L6)

Refactor the single-file app into a Cargo [workspace] separating pure L1 domain state (crates/pcb-doc, depending only on emath) from the L6/L7 eframe UI crate, enforced by a Tier 1 manifest dependency gate.

egui Skill: Engine-First Layering (L1 Domain vs. L6 UI) Rust Concept: Cargo [workspace], pub/pub(crate) Visibility & Lint Gates Runnable App: apps/0015-multi-crate-workspace-doc-vs-ui-egui
Lesson 0016 155 / 155 Caught

Loading & Saving Board & Review Session Files (serde & thiserror)

Serialize and deserialize PCB geometry and review pins with serde_json (emath serde feature), enforce CURRENT_SCHEMA_VERSION = 1 with thiserror (SessionIoError), and display dismissible I/O error banners in Panel::right.

egui Skill: Panel::right Session Persistence & Error Banner UI Rust Concept: serde (Serialize/Deserialize), thiserror::Error & Exhaustive Destructuring Runnable App: apps/0016-loading-board-and-review-files-serde
Lesson 0017 169 / 169 Caught

Copy-on-Write Document Snapshots (Arc & Arc::make_mut)

Upgrade BoardModel collections to Arc<Vec<...>> and Arc<HashMap<...>>, mutate touched buffers with Arc::make_mut, and verify O(1) snapshot structural sharing (Arc::ptr_eq) with proptest.

egui Skill: Snapshot Telemetry & Instant O(1) Rollback UI Rust Concept: std::sync::Arc, Arc::make_mut, Arc::ptr_eq & proptest Runnable App: apps/0017-copy-on-write-arc-document-snapshots
Lesson 0018 217 / 217 Caught

Undo/Redo History (VecDeque) & Slider Drag Coalescing

Implement a bounded BoardHistory (VecDeque<HistoryEntry>, redo_stack, revision), coalesce continuous egui::Slider drags using coalesce_key and Response::drag_stopped(), wire Z/Y hotkeys, and verify with proptest.

egui Skill: Response::changed() + Response::drag_stopped() Coalescing & Z/Y Undo/Redo Rust Concept: VecDeque Ring Buffer, std::mem::replace & Stateful proptest Runnable App: apps/0018-undo-redo-history-and-slider-coalescing

Act V: Command Engine, Performance & Polish (0019–0022)

Act V brings commercial CAD performance and reliability to the review system. We route all state mutations through a static CommandSpec registry with a searchable Key::K command palette and adversarial fuzz testing (panic_hunt), implement viewport bounding-box culling with cached tessellation for 60 FPS budgets, offload heavy file parsing to worker threads with non-blocking progress UI, and establish headless snapshot testing (gpu_lock) with WebAssembly (wasm32) deployment targets.

Lesson 0019 238 / 238 Caught

Command Pattern, CommandSpec Registry & panic_hunt

Unify actions into a static CommandSpec registry (review.addPin, review.clearPins, history.undo, session.inspect) with EnabledFn / RunFn function pointers, wire a Key::K Command Palette window, and verify with a Tier 5 panic_hunt fuzzer.

egui Skill: Searchable Key::K Command Palette (egui::Window) & Unified Command Dispatch Rust Concept: Function Pointers (fn(...) -> Result<...>), Static Slice Registries & Adversarial Fuzzing Runnable App: apps/0019-the-command-pattern-and-command-palette
Lesson 0020 255 / 255 Caught

Spatial Viewport Culling (Rect::intersects) & Frame Budgets

Compute stroke-expanded TraceSegment::bounds_mm(), filter pads and traces against pcb_scene_rect via Rect::intersects, surface live ViewportCullStats telemetry, enforce a Tier 7 PerfBudget, and prove equivalence with proptest.

egui Skill: Viewport Frustum Culling (Rect::intersects) & Live ViewportCullStats Telemetry Rust Concept: AABB Geometry Math (Rect::from_two_pos, expand), Vec::with_capacity & proptest Equivalence Runnable App: apps/0020-viewport-culling-and-cached-tessellation
Lesson 0021 269 / 269 Caught

Non-Blocking File Import (mpsc::channel) & ProgressBar

Parse session files on a background worker (std::thread::spawn + mpsc::channel), poll try_recv() on each frame, render a live egui::ProgressBar, request continuous repaints while running, and support instant cancellation.

egui Skill: egui::ProgressBar, Non-Blocking try_recv() Polling & ctx.request_repaint() Rust Concept: std::thread::spawn, std::sync::mpsc::channel & Send + 'static Channel Ownership Runnable App: apps/0021-non-blocking-file-import-and-progress-ui
Lesson 0022 304 / 304 Caught

Offscreen Snapshot Parity (gpu_lock) & wasm32 Readiness

Serialize GPU/snapshot tests with gpu_lock(), compute 64-bit FNV-1a FrameSnapshotDigest hashes over visible layers and DRC overlays, gate #[cfg(target_arch = "wasm32")], and verify release readiness with QualityScorecard.

egui Skill: Offscreen Frame Snapshot Digests (gpu_lock), Visual Baseline Diffing & Scorecard UI Rust Concept: OnceLock<Mutex<()>> (PoisonError::into_inner), FNV-1a Hashing & #[cfg(target_arch = "wasm32")] Runnable App: apps/0022-headless-snapshot-testing-and-wasm-build

Act VI: Real-World KiCad Parsing (nom) & Embedded SQL (Turso) (0023–0026)

Act VI connects our CAD engine to real-world hardware files and relational review databases. We extract a standalone L0 S-expression parser crate (crates/kicad-sexpr) using nom combinators, lower .kicad_pcb S-expression trees into BoardModel verified by a Tier 4 pinned corpus oracle (CORPUS_PASS_FLOOR & CORPUS_ROUNDTRIP_FLOOR), validate SQLite/Turso DDL and DML syntax with turso_parser inside an async-tested TursoReviewStore, and execute atomic BEGIN / COMMIT / ROLLBACK sign-off batches backed by a tamper-evident hash-chained audit trail (verify_audit_chain) and local-first replica sync.

Lesson 0023 342 / 342 Caught

KiCad S-Expression AST & nom Combinators (L0)

Build a standalone L0 kicad-sexpr crate using nom combinators (delimited, many0, alt), enforce validate_l0_standalone_manifest, and inspect recursive SexprNode trees in egui::CollapsingHeader.

egui Skill: Interactive AST Tree Inspector (egui::CollapsingHeader) & Live Parse Telemetry Rust Concept: Parser Combinators (nom::IResult, delimited, many0, alt) & Recursive Enums (SexprNode) Runnable App: apps/0023-sexpr-tokenizer-and-ast-with-nom
Lesson 0024 385 / 385 Caught

KiCad AST Lowering & Tier 4 Corpus Oracles

Lower SexprNode trees into BoardModel (from_kicad_pcb_sexpr / to_kicad_pcb_sexpr), validate KiCad layer names (F.Cu, B.Cu, F.SilkS), and enforce Tier 4 corpus pass & round-trip ratchets.

egui Skill: Live KiCad S-Expression Board Import/Export & Corpus Oracle Telemetry Rust Concept: AST Lowering (Result<T, KicadLowerError>), #[from] Error Chaining & Corpus Floor Ratchets Runnable App: apps/0024-parsing-kicad-pcb-and-sch-into-domain-model
Lesson 0025 425 / 425 Caught

Embedded SQL Review Store (turso_parser & tokio)

Parse and validate SQL migrations and parameterized queries with turso_parser, enforce foreign-key constraints on board_id, and filter SQL review threads in the egui inspector.

egui Skill: Embedded SQL Review Inspector, Live Row Sync & Parameterized Search Filter Rust Concept: SQL AST Validation (turso_parser::parser::Parser), async/await & #[tokio::test] Runnable App: apps/0025-embedded-sql-review-store-with-turso
Lesson 0026 476 / 476 Caught

Local-First Replica Sync & SQL Audit Trails

Execute atomic BEGIN/COMMIT/ROLLBACK sign-off batches, verify hash-chained AuditLogEntry trails (verify_audit_chain), merge remote replica rows by monotonic revision, and audit Act VI release readiness.

egui Skill: Live Replica Sync Indicator, Atomic Sign-Off Batching & SQL Audit Timeline UI Rust Concept: Transactional Rollback Snapshots, Hash-Chained Audit Logs (verify_audit_chain) & Replica Merging Runnable App: apps/0026-local-first-review-sync-and-audit-trail

Act VII: Agentic Hardware Review & Model Context Protocol (rmcp) (0027–0030)

Act VII turns our PCB Design Reviewer into an AI-native hardware verification platform. We design token-efficient, schemars-typed spatial neighborhood, net topology, and custom DRC query engines (query_spatial_neighborhood, query_net_topology, run_custom_drc), build a headless Model Context Protocol (rmcp) server exposing kicad:// resources, #[tool] endpoints, and structured prompts tested over in-memory tokio::io::duplex streams, bridge the MCP server to the live egui desktop viewport over a constant-time bearer-authenticated control channel (verify_bearer_token) with cropped PNG region snapshots (capture_cropped_region_png), and embed an interactive MCP Inspector Workbench inside egui to audit JSON-RPC 2.0 frames and execute multi-step Agent Review Playbooks.

Lesson 0027 497 / 497 Caught

LLM-Native Spatial & Electrical Queries (schemars)

Implement radius neighborhood lookups (query_spatial_neighborhood), net-topology summaries (query_net_topology), and parameterized custom DRC checks (run_custom_drc) with schemars::JsonSchema introspection.

egui Skill: Interactive Agent Query Preview Inspector & Live Telemetry Badges Rust Concept: #[derive(schemars::JsonSchema)], schema_for! JSON Schema Introspection & Euclidean Neighborhood Filtering Runnable App: apps/0027-llm-native-spatial-and-electrical-queries
Lesson 0028 562 / 562 Caught

Headless MCP Server (rmcp) & Duplex Mock Client

Build PcbMcpServer (#[tool_router], #[tool_handler]), expose kicad://board/summary & kicad://bom resources and review_power_integrity prompts, and verify round-trips over tokio::io::duplex.

egui Skill: Live Headless MCP Server Status & Resource/Tool Preview Panel Rust Concept: rmcp::ServerHandler, #[tool_router], Parameters<T>, Arc<Mutex<BoardModel>> & tokio::io::duplex Runnable App: apps/0028-headless-mcp-server-rmcp-and-mock-client
Lesson 0029 532 / 532 Caught

Bridged MCP Control Channel & Live GUI Snapshots

Authenticate loopback control requests in constant time (verify_bearer_token), drive live egui viewport focus and layer state via LoopbackControlBridge, and capture cropped PNG region snapshots (PNG_MAGIC_HEADER).

egui Skill: Live Loopback Control Bridge Telemetry & Cropped Region Snapshot Triggers Rust Concept: Constant-Time XOR Token Auth (verify_bearer_token), LoopbackControlBridge & PNG Magic Header Encoding Runnable App: apps/0029-bridged-mcp-control-channel-and-live-gui-snapshots
Lesson 0030 548 / 548 Caught

egui MCP Inspector Workbench & Agent Playbooks

Toggle between HeadlessDuplex and BridgedLoopback transports in egui, audit RpcFrameRecord JSON-RPC 2.0 logs, execute the 4-step Power Integrity Agent Playbook, and verify the complete 30-lesson course scorecard.

egui Skill: Embedded MCP Inspector Workbench, Transport Switcher & Agent Playbook Runner Rust Concept: Dual-Transport State Machines (McpTransportMode), Auditable JSON-RPC Logs & Multi-Step Agent Playbooks Runnable App: apps/0030-egui-mcp-inspector-workbench-and-agent-playbooks

Reference Sheets & Printable Cheat Sheets

Turns out, having a one-page cheat sheet next to your editor saves a lot of tab-switching. These reference documents compress the core Rust, immediate-mode GUI, and mutation-testing mechanics into quick-lookup tables designed for both screen review and clean paper printing:

Reference Sheet What It Covers
Glossary of Rust & egui Terms Canonical definitions of Immediate-Mode vs. Retained-Mode GUI, &mut borrows, closures, TSTransform, Sense, Arc::make_mut, and PCB domain analogies.
Immediate-Mode GUI Cheat Sheet The 5-step single-frame mental model, panel layout ordering rules (Panel before CentralPanel), and custom 2D CAD painter idioms.
Testing & Mutation Coverage Cheat Sheet Why line coverage lies, how cargo-mutants tests your tests, fast APFS copy-on-write workflows, and the evolutionary verification ladder (proptest, workspace gates, and egui_kittest).

Running the Companion Rust Apps Locally

Every lesson is backed by a standalone, runnable Cargo package or workspace under ./apps/<NNNN-lesson-slug>/ that compiles with zero warnings and passes both cargo test and cargo mutants:

# Launch Lesson 0030's interactive 3-crate PCB Reviewer & MCP Inspector Workbench
cargo run --manifest-path ./apps/0030-egui-mcp-inspector-workbench-and-agent-playbooks/Cargo.toml

# Run workspace unit + proptest + tokio::test suites and fast L0/L1 mutation checks
cargo test --manifest-path ./apps/0030-egui-mcp-inspector-workbench-and-agent-playbooks/Cargo.toml --workspace
cargo mutants --manifest-path ./apps/0030-egui-mcp-inspector-workbench-and-agent-playbooks/Cargo.toml -p kicad-sexpr -p pcb-doc --in-place