Generated bridges
Two bridges are not written by hand: UiSettingsBridge and DownloadModel. Their bridge modules are generated by kushi from declarations in crates/omikuji/build.rs and written into OUT_DIR at build time. The declarations list every property, role, signal, and invokable; changing the bridge means changing the declaration.
The two halves
Each generated bridge has a handwritten half in src/bridge/ that pulls the generated module in and implements everything with logic in it:
#![allow(unused)]
fn main() {
include!(concat!(env!("OUT_DIR"), "/ui_settings_bridge.rs"));
}
src/bridge/ui_settings.rs: thepersistimplementation (the watcher suppress window), the custom apply bodies (apply_ui_scale,apply_card_flow, …), the reload hook, the file watcher, and the misc invokables (fonts, icons, color overrides).src/bridge/download_model.rs: the customDefault(counts viarecompute), the enqueue/pause/resume invokable bodies,drain_events, and therole_*helpers behind computed roles (status label, byte casts).
The generated half calls into the handwritten one where the declaration says so: .prop_custom_apply declares an invokable without generating a body, .role_fn points a role at a function, .custom_invokable declares any signature. A missing implementation is a compile error.
Rules
- Generated files live in
OUT_DIRand are rewritten every build. Never edit them; edit the declaration or the handwritten half. The current output is inspectable attarget/debug/build/omikuji-*/out/. - The strings passed to the builders are QML API. Property and role names come out camelCased (
show_hiddenbecomesshowHidden). Signatures passed toqsignal_rawandcustom_invokable_raware exposed under their literal snake_case names, which is what the existing QML calls.