Skip to main content

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.