feat: Add DTR/RTS control for serial ports with GUI toggles
- Assert DTR/RTS after serial port open to prevent wireless modules (HC-12/HC-15/Bluetooth bridges) from entering AT command mode after the unavoidable Linux kernel DTR pulse on every open() call. - Add dtr/rts fields to TransportConfig::Serial (default: false). - Add set_dtr()/set_rts() on SerialTransport, Connection, SessionHandle. - Add SessionCmd::SetDtr/SetRts for live toggling via command channel. - Add DTR/RTS checkboxes to GUI session controls (visible when connected) and to config form for persistence. - Add test_plot_serial.c and test_text_serial.c — standalone C test tools for sending MixedTextPlot frames and plain text over serial. - Update AGENTS.md with build prerequisites, architecture map, testing conventions, env vars, and known quirks.
This commit is contained in:
144
AGENTS.md
144
AGENTS.md
@@ -1,28 +1,134 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
`xserial` is a Rust workspace. The root [Cargo.toml](/D:/Dev/xserial/Cargo.toml) defines four crates in `crates/`:
|
||||
- `xserial-core`: transport, framing, protocol, and pipeline primitives in `src/`, with integration tests in `tests/pipeline.rs`.
|
||||
- `xserial-client`: session management, history, commands, and Lua bindings, with integration tests under `tests/`.
|
||||
- `xserial-tui`: terminal app entrypoint in `src/main.rs`.
|
||||
- `xserial-gui`: egui/eframe app, with UI panels in `src/panels/` and font helpers in `src/ui_fonts.rs`.
|
||||
## Build Prerequisites
|
||||
|
||||
Use `tools/test_plot.py` as a local waveform source for GUI plot testing. Treat `target/` as generated output.
|
||||
- **Linux**: `libudev-dev` (for `serialport`).
|
||||
- **All platforms**: a C compiler (`cc`, `gcc`, `clang`, or MSVC) — `mlua` uses `features = ["vendored"]` which compiles LuaJIT from source at build time.
|
||||
- **No pinned toolchain**: all crates use `edition = "2024"` (requires Rust ≥ 1.85). No `rust-toolchain.toml`; builds with whatever `rustc` is on `PATH`.
|
||||
|
||||
## Project Structure
|
||||
|
||||
`xserial` is a Rust workspace. The root `Cargo.toml` defines four crates in `crates/`, with dependencies flowing:
|
||||
|
||||
```
|
||||
xserial-core (no internal deps — transport, framing, protocol, pipeline)
|
||||
↑
|
||||
xserial-client (depends on xserial-core — sessions, history, commands, Lua)
|
||||
↑ ↑
|
||||
xserial-gui xserial-tui
|
||||
(both depend on xserial-core AND xserial-client)
|
||||
```
|
||||
|
||||
| Crate | Type | What goes here |
|
||||
|-------|------|---------------|
|
||||
| `xserial-core` | library (`src/lib.rs`) | `transport/`, `frame/`, `protocol/`, `pipeline.rs` — protocol and I/O. Integration tests: `tests/pipeline.rs`. |
|
||||
| `xserial-client` | library (`src/lib.rs`) | `session.rs`, `manager.rs`, `config.rs`, `history.rs`, `lua/` — state management and Lua bindings. Integration tests: `tests/session_lifecycle.rs`, `tests/lua_tests.rs`. |
|
||||
| `xserial-gui` | binary (`src/main.rs`) | egui/eframe app. Panels in `src/panels/`. Font helpers in `src/ui_fonts.rs`. Profiling in `src/perf.rs`. |
|
||||
| `xserial-tui` | binary (`src/main.rs`) | ratatui/crossterm app. **Still a placeholder** — zero tests, not at feature parity with GUI. |
|
||||
|
||||
**Module boundaries**: transport/protocol → `xserial-core`. Session/Lua → `xserial-client`. UI state → `xserial-gui` or `xserial-tui`. Never put I/O logic in the UI crates, never put UI state in the client crate.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
- `cargo check --workspace`: fast compile check for all crates.
|
||||
- `cargo test --workspace`: run the workspace test suite, including `crates/xserial-core/tests` and `crates/xserial-client/tests`.
|
||||
- `cargo run -p xserial-gui`: launch the desktop GUI.
|
||||
- `cargo run -p xserial-tui`: launch the terminal UI.
|
||||
- `cargo fmt --all`: apply standard Rust formatting.
|
||||
- `cargo clippy --workspace --all-targets -- -D warnings`: catch lint issues before review.
|
||||
- `python tools/test_plot.py --help`: inspect options for the TCP plot-frame generator.
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
Follow standard Rust formatting: 4-space indentation, trailing commas in multiline literals, and `snake_case` for modules, files, functions, and tests. Use `PascalCase` for structs/enums and `SCREAMING_SNAKE_CASE` for constants. Keep crate boundaries clean: protocol/transport code belongs in `xserial-core`; session and Lua integration belong in `xserial-client`; UI state stays in `xserial-gui` or `xserial-tui`.
|
||||
```bash
|
||||
cargo check --workspace # fast compile check (all crates)
|
||||
cargo test --workspace # full suite (~266 tests)
|
||||
cargo fmt --all # standard Rust formatting
|
||||
cargo clippy --workspace --all-targets -- -D warnings # lint gate
|
||||
```
|
||||
|
||||
**Run specific tests:**
|
||||
|
||||
```bash
|
||||
cargo test -p xserial-core -- tcp_line_text_utf8
|
||||
cargo test -p xserial-client -- session_echo_send_and_read
|
||||
cargo test -p xserial-core -- --nocapture # show test output
|
||||
|
||||
# Integration tests only
|
||||
cargo test -p xserial-core --test pipeline
|
||||
cargo test -p xserial-client --test session_lifecycle
|
||||
cargo test -p xserial-client --test lua_tests
|
||||
```
|
||||
|
||||
**Launch:**
|
||||
|
||||
```bash
|
||||
cargo run -p xserial-gui
|
||||
cargo run -p xserial-tui
|
||||
```
|
||||
|
||||
## Environment & Configuration
|
||||
|
||||
### Tracing (all entrypoints)
|
||||
|
||||
```bash
|
||||
RUST_LOG=info cargo run -p xserial-gui
|
||||
RUST_LOG=xserial_gui::perf=debug cargo run -p xserial-gui
|
||||
```
|
||||
|
||||
`tracing_subscriber::EnvFilter::from_default_env()` reads `RUST_LOG`. The workspace dep `tracing-subscriber` has `features = ["env-filter"]`.
|
||||
|
||||
### GUI Profiling
|
||||
|
||||
```bash
|
||||
RUST_LOG=xserial_gui::perf=info XSERIAL_GUI_PROFILE=1 cargo run -p xserial-gui
|
||||
XSERIAL_GUI_PROFILE_INTERVAL_MS=500 cargo run -p xserial-gui # custom interval (default 1s)
|
||||
```
|
||||
|
||||
Profiling logs go to target `xserial_gui::perf`.
|
||||
|
||||
### State & Config File Paths (runtime, not compile-time)
|
||||
|
||||
Uses `env::consts::OS` + env vars — no `cfg(target_os)` gating for path resolution:
|
||||
|
||||
| Platform | Root config path |
|
||||
|----------|-----------------|
|
||||
| Linux | `$XDG_CONFIG_HOME/xserial/` or `~/.config/xserial/` |
|
||||
| macOS | `~/Library/Application Support/xserial/` |
|
||||
| Windows | `%APPDATA%\xserial\` |
|
||||
|
||||
State files: `gui-state.json`, `tui-state.json`, `font-settings.json`.
|
||||
|
||||
### GUI Plot Testing
|
||||
|
||||
```bash
|
||||
python tools/test_plot.py --wire-format mixed --host 127.0.0.1 --port 8091
|
||||
python tools/test_plot.py --wire-format mixed --format xy --channels 2
|
||||
python tools/test_plot.py --wire-format raw --channels 2 --framelen 256
|
||||
```
|
||||
|
||||
Configure in GUI: Transport `TCP 127.0.0.1:8091`, Framer `MixedTextPlot`, Decoder `MixedTextPlot`.
|
||||
|
||||
The wire format spec lives in `tools/xs_mixed_plot.h` (C header, reference only — not compiled into Rust).
|
||||
|
||||
## Coding Style
|
||||
|
||||
Standard Rust conventions (`cargo fmt`). No crate-level lint attrs, no `[lints]` table in any `Cargo.toml`. Names: `snake_case` for modules/files/functions/tests, `PascalCase` for types, `SCREAMING_SNAKE_CASE` for constants.
|
||||
|
||||
## Testing Guidelines
|
||||
Prefer focused unit tests next to implementation and integration tests in `crates/<crate>/tests/*.rs`. Name tests after behavior, for example `session_lifecycle` or `pipeline`. Run `cargo test --workspace` before opening a PR; add targeted regression tests for transport, framing, parsing, and session-state fixes.
|
||||
|
||||
## Commit & Pull Request Guidelines
|
||||
Recent history uses short, imperative subjects such as `Persist GUI font settings` and `Improve session controls and GUI views`, with occasional `feat:` prefixes for major additions. Keep subjects concise and action-oriented. PRs should state which crate(s) changed, list validation commands, and include screenshots or short recordings for GUI/TUI changes. Call out protocol, transport, or Lua API compatibility impacts explicitly.
|
||||
- **Inline unit tests** (`#[cfg(test)] mod tests`) next to implementation — 24 source files with `#[test]` or `#[tokio::test]`.
|
||||
- **Integration tests** in `crates/<crate>/tests/*.rs` — 3 files covering pipeline, session lifecycle, and Lua bindings.
|
||||
- **~266 tests total** — all active (zero `#[ignore]`). Single `#[should_panic]` in `frame/fixed.rs`.
|
||||
- **All tests are self-contained**: TCP/UDP bind to `127.0.0.1:0` (OS-assigned port). No hardcoded ports. No external services. Serial tests use dummy port names and never open real hardware.
|
||||
- **Async tests** use `#[tokio::test]` (no `async-std`). **No benchmarks** exist.
|
||||
- Run `cargo test --workspace` before opening PRs. Add targeted regression tests for transport, framing, parsing, and session-state fixes.
|
||||
|
||||
## Known Quirks & Constraints
|
||||
|
||||
- **No CI** — no `.github/workflows` or other CI config. Agents must self-verify with `cargo test --workspace` and `cargo clippy --workspace --all-targets -- -D warnings`.
|
||||
- **No feature flags** — zero `[features]` in any `Cargo.toml`. No `#[cfg(feature)]` in any source.
|
||||
- **No build scripts** — zero `build.rs` files. No codegen. No `include!`/`include_str!`/`include_bytes!`.
|
||||
- **All `unsafe` is test-only** — constructing noop wakers for poll-based unit tests in `transport/`. No non-test `unsafe` anywhere.
|
||||
- **`xserial-tui` is a stub** — no tests, minimal implementation. GUI is the primary target.
|
||||
- **Platform font directories** use `#[cfg(target_os)]` in `ui_fonts.rs` (three blocks: Windows, macOS, Linux/BSD).
|
||||
- **`tokio` features differ by build**: `xserial-client` uses `["sync", "time"]` for production, `["full"]` for dev-dependencies (tests need net/IO).
|
||||
|
||||
## Commit & PR Guidelines
|
||||
|
||||
Short, imperative subjects (`Persist GUI font settings`), occasional `feat:` prefix for major additions. PRs: state which crate(s) changed, list validation commands, include screenshots/recordings for GUI/TUI changes. Explicitly call out protocol, transport, or Lua API compatibility impacts.
|
||||
|
||||
## Reference
|
||||
|
||||
- `tools/test_plot.py --help` — TCP plot-frame generator options.
|
||||
- `tools/xs_mixed_plot.h` — wire format spec for MixedTextPlot (COBS-framed binary plot + text on one stream).
|
||||
|
||||
Reference in New Issue
Block a user