feat(ipc): enum-типы Power/Ignition/Source/Reason (string round-trip)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Alexander <akotenev2003@gmail.com>
This commit is contained in:
2026-06-24 12:10:07 +03:00
parent d91d218ade
commit 0d630dde84
2 changed files with 128 additions and 0 deletions
+2
View File
@@ -4,5 +4,7 @@
pub mod error;
pub mod names;
pub mod types;
pub use error::Error;
pub use types::{IgnitionState, PowerSource, PowerState, ShutdownReason};
+126
View File
@@ -0,0 +1,126 @@
//! Enum-типы шины (data-model / spec §5.2): на проводе — строки (snake_case).
//! D-Bus-сигнатуры используют `String` (см. `proxy`); Rust-сторона конвертит через `as_str`/`FromStr`.
/// Генерирует enum с `as_str`/`FromStr`/`Display` (строка на проводе).
macro_rules! str_enum {
($(#[$m:meta])* $name:ident { $($variant:ident => $s:literal),+ $(,)? }) => {
$(#[$m])*
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum $name { $($variant),+ }
impl $name {
pub fn as_str(&self) -> &'static str {
match self { $(Self::$variant => $s),+ }
}
}
impl core::str::FromStr for $name {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
match s {
$($s => Ok(Self::$variant),)+
_ => Err(()),
}
}
}
impl core::fmt::Display for $name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}
};
}
str_enum!(
/// Состояние питания (`Power.GetPowerState`, B §2).
PowerState {
Off => "off",
Accessory => "accessory",
Running => "running",
ShuttingDown => "shutting_down",
Sleep => "sleep",
BatteryCutoff => "battery_cutoff",
}
);
str_enum!(
/// Ось зажигания — канон (`Power.IgnitionState`, B §1; E зеркалит, не дублирует).
IgnitionState {
Off => "off",
Accessory => "accessory",
Running => "running",
}
);
str_enum!(
/// Источник питания (`Power.PowerSource`).
PowerSource {
Vehicle12v => "vehicle_12v",
HoldupCap => "holdup_cap",
SleepRail => "sleep_rail",
LowBattery => "low_battery",
}
);
str_enum!(
/// Причина выключения (`Power.ShutdownImminent`).
ShutdownReason {
AccOff => "acc_off",
UnderVoltage => "under_voltage",
Thermal => "thermal",
BatteryCutoff => "battery_cutoff",
}
);
#[cfg(test)]
mod tests {
use super::*;
use core::str::FromStr;
#[test]
fn power_state_round_trip() {
for v in [
PowerState::Off,
PowerState::Accessory,
PowerState::Running,
PowerState::ShuttingDown,
PowerState::Sleep,
PowerState::BatteryCutoff,
] {
assert_eq!(PowerState::from_str(v.as_str()), Ok(v));
}
assert!(PowerState::from_str("nonsense").is_err());
}
#[test]
fn ignition_round_trip() {
for v in [
IgnitionState::Off,
IgnitionState::Accessory,
IgnitionState::Running,
] {
assert_eq!(IgnitionState::from_str(v.as_str()), Ok(v));
}
}
#[test]
fn source_and_reason_round_trip() {
for v in [
PowerSource::Vehicle12v,
PowerSource::HoldupCap,
PowerSource::SleepRail,
PowerSource::LowBattery,
] {
assert_eq!(PowerSource::from_str(v.as_str()), Ok(v));
}
for v in [
ShutdownReason::AccOff,
ShutdownReason::UnderVoltage,
ShutdownReason::Thermal,
ShutdownReason::BatteryCutoff,
] {
assert_eq!(ShutdownReason::from_str(v.as_str()), Ok(v));
}
}
}