Expand description
Template descriptor (D103 / D102 Tier 1) — the data form of a view! tree
for universal hot reload; see the module docs.
Template descriptor (D103 / D102 Tier 1) — the data form of a view!
tree, and the runtime that inflates it back into widgets.
This is the contract at the centre of universal (data-not-code) hot reload:
the view! macro writes a Template in dev builds, and a runtime
interpreter reads it to reconstruct the widget subtree by calling the same
widget constructors the release builder would (the “inflater, not a
renderer” model — see .steering/HOT_RELOAD.md). Because it is pure data —
widget kinds by name, literal props as data, dynamic {expr} bits as
numbered holes — a template can be diffed and swapped at runtime without
recompiling, which is the only reload path that works on iOS device and web.
§Layers built on this
- Step 2 (this file): the descriptor data model —
Template,TemplateNode,PropValue,StaticValue,TemplateKey. - Step 3 (next): the widget registry + interpreter that turn a
TemplateintoBox<dyn Widget>— that is whereRosaceTraceinflate events are emitted (this data model is inert, so it emits none itself). - Step 4: the dev watcher diffs templates by
TemplateKeyand pushes deltas over the control channel.
§Wire form (named-deferred)
The types are deliberately plain data — String widget/prop names, a
primitive-only StaticValue, no borrowed lifetimes — so a
#[derive(Serialize, Deserialize)] drops on cleanly the day the SDUI /
external-DevTools transport needs a JSON form (the plan’s “design it so it
is not foreclosed”). serde is not pulled into the workspace here — it
is a named deferral to the transport step (rollout step 4), consistent with
D121 treating a new dependency as its own decision rather than smuggling it
in with an unrelated change.
Structs§
- Reload
Report - Outcome of reloading one edited file.
- Template
- A full template: the root
TemplateNodeplus the number of hole slots it references, keyed by source location for diffing across hot reloads. - Template
Key - Source-location key identifying a single
view!site, so the dev watcher can match an edited template against the one currently running and diff them (D103’slocation!()key). Stable across a rebuild of the same source. - Template
Node - One node in a template tree: a widget kind by name (the string the registry maps to a constructor), its props, and its children.
Enums§
- Escalation
Reason - Why a diff cannot be hot-swapped as data.
- Inflate
Error - Why an
inflatefailed. All are “escalate, don’t paint garbage” cases. - Parse
Error - Why parsing a
view!body failed at runtime. - Prop
Input - A resolved prop value handed to a build closure: either a template literal, or the compiled value at a hole slot (type-erased).
- Prop
Value - A prop’s value in a template: either a compile-time literal that travels as
data, or a numbered hole filled at runtime by the already-compiled
{expr}at that slot. - Static
Value - A literal prop value that travels as data — the wire-friendly subset of
what a
view!prop can be. Anything that is not one of these (a computed expression, a closure, a struct value) is aPropValue::Holefilled by compiled code, not carried in the template. - Swap
Outcome - The result of trying to apply an edited template to the running app.
- Template
Diff - The verdict for one edited
view!site.
Traits§
Functions§
- apply_
reload - Re-parse an edited file and apply safe swaps to the running app’s registry.
- apply_
swap - Diff an edited template against the running one and, if it is a safe data
swap, install it. Keyed by
new.key. - diff
- Diff the currently-running template (
old) against an edited one (new). - find_
running - Find the running template for a
view!site by(file, line), tolerating path-form and column differences between the runtime file scanner and the macro’sfile!()/column!()key. Matching is line + path-suffix: the watcher’s absolute path and the macro’s package-relativefile!()agree on their trailing segments. Used by the reload runtime (exact keygetfails here because the two producers compute file/column differently). - get
- The template currently registered for
key, if any. - inflate
- Inflate a template into a live widget tree, binding hole slots by index.
- is_
registered - Whether a widget name is registered (diagnostics / tests).
- len
- Number of registered sites (diagnostics / tests).
- parse_
file_ templates - Parse EVERY
view!in a source file into a keyedTemplate— what a dev watcher calls on a changed.rs. Each template’s key is(file, line, col)of itsview!site, so the runtime can match it to the running template. - parse_
template - Parse a
view!body (the text insideview! { … }) into aTemplatekeyed bykey. The hole indices it assigns match the compile-time macro’s, so the running binary’s compiled hole array lines up slot-for-slot. - register
- Register (or replace) the template for its site key. Re-registering the same
key overwrites — a
view!site has exactly one compiled-in shape at a time, and a hot-reload push replaces it. - register_
widget - Register (or replace) a widget build closure by name. Third-party widgets call this — same extensibility path as built-ins, no edit to rosace-* crates.
- snapshot
- A copy of every registered template (diagnostics / tests). Order is unspecified — the caller should match by key or shape.
Type Aliases§
- Handler
- A nullary event handler (e.g.
Button::on_press). Handlers travel through a hole wrapped as this type — concrete (so it round-trips throughBox<dyn Any>), and callable. Arg-taking handlers (Fn(T)) are a future extension.