Tag Monitor (Rust)
A port of qtmonitor to Rust, built the way Tag Programmer was:
- a toolkit-free
core/crate with the model and an engine; - a generic web UI on
host/ui-kit; - a thin Tauri shell.
It follows the structure qtmonitor was given for this purpose (architecture, decision 0036).
Status: complete on the tagmonitor-rs branch; shipped as tagmonitor beside qtmonitor (decision 0037).
| Phase | What | State |
|---|---|---|
| 1 | Model: the port of qtmon/core |
done |
| 2 | Engine on tagcore-rs, view state, Tauri shell, UI | done; a full session passed on an IMUTag |
| 3 | Configuration tab: the panels' rules as a field spec | done; all 710 probe goldens match |
| 4 | Design docs, CMake and packaging | done: build and packaging |
Documents
| Document | Read it for |
|---|---|
| design/architecture.md | The layers and threads, a map of every file and the qtmonitor code it ports, how a command and an edit travel, and where to make common changes |
| design/adding-a-tag-type.md | Supporting a new tag type, in Tag Monitor and qtmonitor together |
| design/ui-engine-contract.md | The view state, prompts, commands and queries between engine and page, and the deliberate differences from qtmonitor |
| design/build-and-packaging.md | Building with cargo and CMake, tagcore_c, the install layout, CI and notices |
| decision 0037 | Why it was built this way |
The model
core/src/model/ ports host/applications/qtmon/core/ module for module:
| Rust | C++ | Holds |
|---|---|---|
commands.rs |
commands.h |
The commands and the one rule for when each is available |
startchecks.rs |
startchecks.h |
The start checks and their sentences |
tagrules.rs |
tagrules.h |
Downloadable states, erase size, clock offset, version floor, base names |
monitormodel.rs |
monitormodel.h |
The attached tag as known, and what each status settles |
configdocument.rs |
configdocument.h |
The configuration document, its file format and approval |
menus.rs |
menus.h |
The menus as data |
configform.rs |
tagconfiguration/*panel*, hibernate, hourtime.h |
The panels, and the Qt widget behaviour they rely on |
configeditor.rs |
tagconfiguration/configtab.cpp |
The document and the form together: load, New, Open, Reset, editable |
The engine, shell and page
core/src/engine/ is qtmonitor's MainWindow and LiveTagSession without
Qt: a tag thread that owns the Tag, and an engine thread that owns the
model, the document and the view state. app/ is the Tauri shell and ui/
the page. The protocol between them, and where this port differs from
qtmonitor, is design/ui-engine-contract.md.
Building and running
cargo run -p tagmonitor # the app; attaches to a tag at once
TAGMONITOR_NO_ATTACH=1 cargo run -p tagmonitor # the app, without attaching
open ui/index.html # the page alone, against ui/mock-engine.js
Download Data... writes SQLite through the C++ writer, so it is built only
with the sqlitelog feature and libtagcore_c from a CMake build (built
with BUILD_RUST_APPS or -DBUILD_TAGCORE_C=ON; see
taglogwriter-rs):
TAGCORE_C_LIB_DIR=<build-dir>/Release/lib cargo run -p tagmonitor --features sqlitelog
The CMake build (cmake --build <build-dir> --target tagmonitor) does all of
this and installs the app into the host package; see
design/build-and-packaging.md.
Checking
cargo test
tests/oracles.rschecks that the command rule and the start checks print exactly qtmonitor'stest/action-states.txtandtest/start-checks.txt.-
tests/core_check.rsrepeatsqtmon_core_check's assertions: the document, the monitor model, and the window's remaining rules. It also compares the menu bar with the menu-bar part oftest/menus.txt. -
tests/panels.rschecks the panel table against every tag type's default configuration, asqtmonitor --check-config-panelsdoes. tests/config_probe.rsreplays all 710 configuration probe cases (test/cases/) and matches the goldens (test/golden/): the bytes Start sends, the document, the panels shown, the dialogs, and every control's value, range, step, decimals and enabled state.examples/session_check.rsruns one whole tag cycle through the engine, asqtmon_session_checkdoes; it changes the tag (see its header).
These are the same files that hold qtmonitor fixed, so the two implementations cannot drift apart without a test failing.