nros_platform/board/config.rs
1//! Cross-board configuration trait.
2//!
3//! Every board crate (`nros-board-mps2-an385`, `nros-board-stm32f4`,
4//! `nros-board-esp32-qemu`, …) declares its own `Config` / `NodeConfig`
5//! struct with board-specific fields (MAC, IP, gateway, UART base,
6//! WiFi SSID, etc.). The structs share a few universal fields —
7//! transport locator, ROS 2 domain ID — but cross-board generic code
8//! (a benchmark harness, a multi-target test driver) had no way to
9//! reach those without `cfg`-gating the type name.
10//!
11//! [`BoardConfig`] is the trait every board's config implements so
12//! generic code can read the universal fields uniformly:
13//!
14//! ```ignore
15//! fn print_config<C: nros_platform::BoardConfig>(c: &C) {
16//! println!("locator: {}", c.locator());
17//! println!("domain: {}", c.domain_id());
18//! }
19//! ```
20//!
21//! The trait stays minimal on purpose: each board's transport-specific
22//! knobs (MAC address, WiFi credentials, UART base) remain on the
23//! concrete `Config` struct as ordinary fields. Adding
24//! transport-specific extension traits (e.g. `EthernetConfig`,
25//! `WifiConfig`, `SerialConfig`) is a follow-up that can land
26//! without changing this trait.
27
28/// Universal board configuration accessors.
29///
30/// Implemented by every board crate's top-level config struct
31/// (`Config`, `NodeConfig`, etc.). Generic code that needs to read the
32/// transport locator or the ROS 2 domain ID can take `&impl BoardConfig`
33/// instead of `cfg`-gating on each board type.
34pub trait BoardConfig {
35 /// Transport locator string the RMW backend connects through
36 /// (e.g. `"tcp/192.168.1.50:7447"`, `"serial/UART_0#baudrate=115200"`,
37 /// `"ivc/2"`).
38 ///
39 /// The name matches the RMW vtable's own `locator` parameter and
40 /// `ExecutorConfig::new`. It is deliberately backend-neutral: this is a
41 /// core, RMW-agnostic trait, so it must not name a concrete backend
42 /// (issue 0330 — the same class as issue 0225).
43 fn locator(&self) -> &str;
44
45 /// ROS 2 domain ID (default `0`).
46 fn domain_id(&self) -> u32;
47
48 /// Deprecated alias for [`locator`](BoardConfig::locator).
49 ///
50 /// Kept as a defaulted method (not a required one) so out-of-tree board
51 /// crates that still spell the old name keep compiling: they get the
52 /// forwarding default for free once they rename their own impl, and
53 /// callers of the old name keep working with a deprecation warning.
54 #[deprecated(
55 since = "0.6.0",
56 note = "renamed to `locator()` — the core trait must not name a backend (issue 0330)"
57 )]
58 fn zenoh_locator(&self) -> &str {
59 self.locator()
60 }
61}
62
63// `BoardTransportConfig` was removed here (issue 1064). It carried
64// `set_ipv4` / `set_baudrate` — five and two real board implementations, and
65// ZERO callers: its only writer was the orchestration generator deleted with
66// the standalone-package pipeline in `11a00b0f8` (#202).
67//
68// The live path is the DEPLOY OVERLAY, and it is strictly better: `DeployOverlay`
69// carries `ip`, `gateway`, `netmask`, `locator`, `domain_id` and `transport`
70// (a superset — `gateway` is what the removed `set_gateway` was for), it is
71// applied by `BoardEntry::run_with_deploy`, and it is actually READ —
72// `nros-board-common/src/base_config.rs` does it for the whole family, and
73// esp32-qemu, mps2-an385 and nuttx-qemu read it directly.
74//
75// So this was not a seam awaiting a caller; it was the dead twin of a live one.
76// Same finding as phase-206 W4 (issue 1067) one layer over: the discoverable
77// contract and the executed contract were different things.