- Set up your development environment (see §2 Development Environment Setup). Ensure environment variables are set if using system packages or conda.
- Follow existing module organisation; large viewer subsystems live under
ui/shell/src/<area>/. Under winit 0.30 the desktop entry points are ViewerLoop::{window_event, device_event, about_to_wait} (ui/shell/src/viewer_loop/runtime/runner.rs), driven by event_loop.run_app in ui/shell/src/runner.rs. When adding new functionality, prefer a dedicated module over expanding those handlers.
- Error handling uses
anyhow::Result at the binary/application level and typed thiserror::Error enums inside core crates.
- Avoid
unwrap()/expect() in production paths; prefer early Result returns or explicit fallbacks. Core crates deny clippy::unwrap_used/clippy::expect_used, while tests may allow them when a panic is the expected outcome.
- Instrument long-running tasks with
tracing::instrument where span context helps diagnose renderer, parser, selection, or background-worker behavior.
- A comment says what holds, not how it got there: the invariant, the units or convention, why the obvious alternative is wrong, or where an empirical constant comes from. What the code did before, the commit that changed it and before-and-after numbers belong in the commit message. A test’s doc comment may name the defect it guards against (“a chain hidden in Cartoon came back”).
- Before changing behaviour, say what the current code does and why it is wrong, in the issue or the pull request.
- Keep documentation up to date: public APIs must have doc comments, and significant behavioural changes should be reflected in the user guide and this guide.
scripts/check-rust-lints.sh is the authoritative lint entry point. It runs general workspace checks plus stricter production-target checks; do not add broad lint allowances to bypass it.
12.1 Error Handling Patterns
- Use
anyhow::Context at CLI/UI boundaries so errors report the path or operation that failed.
- Prefer typed errors in core crates (
IoPipelineError, EditError, etc.) and convert to anyhow only at edges.
- Treat optional parse fields as
Option<T> and log/record warnings rather than panicking on missing data.
- For malformed input, return
ParseError { path, message } with enough detail to debug fixtures.
- Avoid
unwrap/expect in non-test code; use ?, ok_or_else, or a documented fallback.
- The production-target Clippy pass denies
unwrap_used and expect_used. Tests may use panic helpers when failure should abort the test.