Expand description
A form file, as Rust the compiler checks.
The engine hands back built.node("who") and resolves message names through
a match on a string. That is right for a kiosk, it is checked when the form
loads, and it is what Form::build does. What it is not
is what Delphi gave you, which was Button1: TButton as a field the compiler
knew about.
This generates that. Point a build.rs at a form file and get a struct whose
fields are the form’s named nodes and an enum whose variants are the form’s
messages:
// build.rs
fn main() {
denise_forms::codegen::to_out_dir("forms/settings.dform").unwrap();
}// src/main.rs
include!(concat!(env!("OUT_DIR"), "/settings.rs"));
let form = Settings::build(&mut ui, root)?;
ui.widget_mut::<TextInput<SettingsMessage>>(form.who); // a field, not a lookupRename a node in the form and the application stops compiling, naming the
field that no longer exists. Add a message to the form and every match on
the enum stops compiling, because it is no longer exhaustive. Both are the
point, and both are what a string lookup cannot do.
And a trait, SettingsHandlers, with one method per message named for it —
fn save(&mut self), fn set_notify(&mut self, on: bool) — plus
SettingsMessage::dispatch, which calls the method a message is named for.
Implement the trait for whatever handles the form and there is no match to
write at all: add an event in the designer and the compiler names the method
that is missing, which is the one the designer writes when asked to open it.
§A build script rather than a proc macro
Chosen deliberately, and #101 said to. The output is a file you can open,
cargo doc sees it, a debugger steps through it, and it needs no second
crate. A macro would read a little better at the call site and cost all four.
§It generates a caller, not a second engine
The generated build calls Form::build with a
generated Wiring. There is one implementation of building
a form, and this is a typed door onto it — so a form that loads at runtime and
the same form generated behave identically, because they are the same code.
Structs§
- Generated
- What one form generated: the text of a module, and what is in it.
Functions§
- generate
- Generates the struct and the enum for a form.
- to_
out_ dir - Generates a form into
OUT_DIRand tells Cargo to watch it.