kushi 0.1.0

Build-time boilerplate generator for cxx-qt bridges. Declare qproperties and list-model roles once in build.rs for the full bridge generated. Not affiliated with the cxx-qt project or KDAB.
Documentation
  • Coverage
  • 0%
    0 out of 41 items documented0 out of 36 items with examples
  • Size
  • Source code size: 82.72 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 526.35 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 3s Average build duration of successful builds.
  • all releases: 3s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • reakjra/kushi
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • reakjra

kushi (wip)

so basically: every new setting in my launcher cost me the same ~12 lines copy-pasted across 9 different places, because you can't generate cxx-qt bridges with macros. cxx-qt-build reads your source files as literal text and never sees what a macro expands to, so the bridge has to exist as a real file on disk. that's the whole famous "no proc macros with cxx" thing. after adding the 33rd setting by hand i lost it and wrote this instead.

so here's a typist.

// build.rs
let bridge = kushi::ObjectBridge::new("AppSettings")
    .prop("show_hidden", kushi::Kind::Bool, "false")
    .prop("ui_scale", kushi::Kind::F64, "1.0")
    .prop("greeting", kushi::Kind::QString, "hi")
    .write_into(&out_dir);

CxxQtBuilder::new_qml_module(QmlModule::new("app").qml_files(["qml/Main.qml"]))
    .file(bridge)
    .build();
// src/settings.rs
include!(concat!(env!("OUT_DIR"), "/app_settings.rs"));

that's a QML-instantiable AppSettings with camelCase properties, applyShowHidden()-style setters that persist to a toml file, and a reloadFromDisk() invokable.

there's also ListModelBridge for QAbstractListModel subclasses (role consts, data(), roleNames(), row change helpers, computed roles that call your functions) and ObjectBridge::external_data which mirrors a settings struct you already own, with escape hatches for everything that has actual logic in it: custom apply bodies, extra fields, signals, a reload hook

no docs yet. crates/kushi/src/lib.rs is small enough to just read, the goldens in crates/kushi/tests/golden/ show exactly what comes out, and crates/demo is a working app.

(nobody sane reads that but im not gonna make a docs for a thing only me uses)

One thing: cxx-qt-build demands all bridge files of a qml module live in one single directory (QTBUG-93443). the fix is staging your handwritten ones into OUT_DIR next to the generated ones:

let staged = kushi::stage_files(["src/bridge/foo.rs", "src/bridge/bar.rs"], &out_dir);
builder.files(staged).file(bridge).build();

rustc still compiles your originals through the normal module tree, the copies only exist to feed cxx-qt-build's parser.

built for omikuji.

not affiliated with the cxx-qt project or KDAB.

MIT or Apache-2.0.