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:
@@ -4,5 +4,7 @@
|
||||
|
||||
pub mod error;
|
||||
pub mod names;
|
||||
pub mod types;
|
||||
|
||||
pub use error::Error;
|
||||
pub use types::{IgnitionState, PowerSource, PowerState, ShutdownReason};
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user