Expand description
Host-side dev server for whisker run.
Owns the long-running dev loop: file watch, cargo rebuild, install
to the device, subsecond patch construction, and WebSocket push.
whisker-cli’s run subcommand is a thin wrapper that builds a
Config and calls DevServer::run — every piece of
UX-shaped logic lives here so future host shells (an editor
plugin, a notebook, a remote-controlled CI build) can reuse it.
§Architecture
Constructed once via Config, the dev server spins up six
cooperating pieces:
builder— translatesConfiginto awhisker-buildinvocation (cargo + per-platform packaging) and runs it. HonoursRUSTC_WORKSPACE_WRAPPER+ linker shim env so the fat build doubles as a capture pass for Tier 1.installer— for the cold-rebuild path: shells out toadb install/simctl install + launch. Identity (bundle id, applicationId, scheme, …) comes in flat viaAndroidParams/IosParams; the cli resolves these from the user’swhisker.rs::configure(&mut Config). This crate never depends onwhisker-config.watcher—notify-based, debounced, classifies events intoChangeKind::{RustCode, CargoToml, Other}.server—axumWebSocket endpoint atws://<bind>/whisker-dev. Devices dial in, send ahellocarrying theirsubsecond::aslr_reference(), then receive patch envelopes.hotpatch— Tier 1 implementation. Builds a thin.ofrom the changed user crate via captured rustc args, links it into a patch dylib with a stub-object of host-symbol jumps, ships the resultingsubsecond_types::JumpTableto connected clients.lib.rs::run— the orchestrator: file event →decide_action(Tier 1 patch vs Tier 2 rebuild) → builder/hotpatch/sender.
§Layering
Stays manifest-agnostic on purpose. The cli does the
whisker.rs → Config translation; this crate accepts only
flat String / PathBuf fields. That keeps the dev-server
reusable from any host shell that can produce the same flat
Config (the cli is one; an editor plugin could be another).
Re-exports§
pub use builder::Builder;pub use installer::Installer;pub use server::Patch;pub use server::PatchSender;pub use watcher::Change;pub use watcher::ChangeKind;pub use workspace::discover_path_deps;pub use workspace::identify_crate_for_paths;pub use workspace::PathDepCrate;
Modules§
- builder
- Tier 2 cold rebuild: produce a fresh artifact + (re)install it on
the active
Target. - hotpatch
- Tier 1 (subsecond) hot-reload pipeline.
- installer
- Tier 2 install + relaunch.
- server
- WebSocket dev server.
- watcher
- File watcher + change classifier for the dev loop.
- workspace
- Workspace path-dep walker.
Structs§
- Android
Params - Flat Android install/launch parameters. Populated by
whisker-clifrom the user’swhisker.rs::configure(&mut Config)plus a few hard defaults (jniLibs lives at<project_dir>/app/src/main/jniLibs, APK at<project_dir>/app/build/outputs/apk/debug/app-debug.apk, etc.). The dev-server never invents these values — if any are missing the cli is expected to error out before constructingConfig. - Capture
Shims - Shim wiring that turns a plain cargo invocation into a Tier 1
fat build. All paths are absolute; the dev-server creates the
cache dirs on demand.
real_linkeris what the linker shim forwards to (typically the samecc/clangcargo would have used). - Config
- Where the dev loop should run, what to build, and how to behave.
Constructed by
whisker-clifrom CLI flags + the user’swhisker.rs(via the cli’s manifest/probe pipeline); or by an editor plugin / test harness directly. - DevServer
- The dev loop. Construct with
DevServer::new, then drive withDevServer::run(which returns when the server shuts down). - IosParams
- Flat iOS Simulator install/launch parameters. Same pattern as
AndroidParams— populated by the cli, consumed by the dev-server’s installer.
Enums§
- Event
- Observable events that bubble out of the dev loop.
whisker-cliuses these to render terminal UI; an editor plugin would use them to drive its own UX. - HotPatch
Mode - How aggressive the dev loop is about reflecting edits.
- Loop
Action - Decision the change loop makes for one debounced change.
- Target
- What kind of binary the dev server is rebuilding.
Functions§
- decide_
action - Pure decision helper for the change loop. Tier 1 only handles
ChangeKind::RustCodeand only when a Patcher is available;Cargo.tomlalways needs a full rebuild because the dependency graph may have shifted; everything else is ignored.