diff --git a/Cargo.lock b/Cargo.lock index 7fd0041..8ce45e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -725,6 +725,27 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "object" version = "0.36.2" @@ -1079,6 +1100,7 @@ dependencies = [ "lazy_static", "libc", "nix", + "num_enum", "regex", "serde", "strum", diff --git a/Cargo.toml b/Cargo.toml index 59b5ef7..3b48944 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ lazy_static = "1" libc = "0.2" itertools = "0.13" nix = { version = "0.29", default-features = false, features = ["fs", "poll", "signal"] } +num_enum = "0.7" regex = "1" serde = { version = "1.0", default-features = false, features = ["derive"] } tokio = { version = "1", default-features = false, features = ["fs", "io-std", "io-util", "macros", "process", "rt-multi-thread", "signal", "sync"] } diff --git a/src/cec.rs b/src/cec.rs index 19a26b1..e103d91 100644 --- a/src/cec.rs +++ b/src/cec.rs @@ -6,32 +6,22 @@ * SPDX-License-Identifier: MIT */ -use anyhow::{anyhow, bail, Error, Result}; +use anyhow::{bail, Error, Result}; +use num_enum::TryFromPrimitive; use std::fmt; use std::str::FromStr; use zbus::Connection; use crate::systemd::{daemon_reload, EnableState, SystemdUnit}; -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Debug, Copy, Clone, TryFromPrimitive)] +#[repr(u32)] pub enum HdmiCecState { Disabled = 0, ControlOnly = 1, ControlAndWake = 2, } -impl TryFrom for HdmiCecState { - type Error = Error; - fn try_from(v: u32) -> Result { - match v { - x if x == HdmiCecState::Disabled as u32 => Ok(HdmiCecState::Disabled), - x if x == HdmiCecState::ControlOnly as u32 => Ok(HdmiCecState::ControlOnly), - x if x == HdmiCecState::ControlAndWake as u32 => Ok(HdmiCecState::ControlAndWake), - _ => Err(anyhow!("No enum match for value {v}")), - } - } -} - impl FromStr for HdmiCecState { type Err = Error; fn from_str(input: &str) -> Result { diff --git a/src/hardware.rs b/src/hardware.rs index ef7a0b0..2c83f96 100644 --- a/src/hardware.rs +++ b/src/hardware.rs @@ -5,7 +5,8 @@ * SPDX-License-Identifier: MIT */ -use anyhow::{anyhow, bail, ensure, Error, Result}; +use anyhow::{bail, ensure, Error, Result}; +use num_enum::TryFromPrimitive; use std::fmt; use std::str::FromStr; use tokio::fs; @@ -27,7 +28,7 @@ pub(crate) enum HardwareVariant { Galileo, } -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Debug, Copy, Clone, TryFromPrimitive)] #[repr(u32)] pub(crate) enum HardwareCurrentlySupported { Unknown = 0, @@ -35,7 +36,7 @@ pub(crate) enum HardwareCurrentlySupported { Supported = 2, } -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, Debug, Copy, Clone, TryFromPrimitive)] #[repr(u32)] pub enum FanControlState { Bios = 0, @@ -53,24 +54,6 @@ impl FromStr for HardwareVariant { } } -impl TryFrom for HardwareCurrentlySupported { - type Error = anyhow::Error; - fn try_from(v: u32) -> Result { - match v { - x if x == HardwareCurrentlySupported::Unknown as u32 => { - Ok(HardwareCurrentlySupported::Unknown) - } - x if x == HardwareCurrentlySupported::UnsupportedPrototype as u32 => { - Ok(HardwareCurrentlySupported::UnsupportedPrototype) - } - x if x == HardwareCurrentlySupported::Supported as u32 => { - Ok(HardwareCurrentlySupported::Supported) - } - _ => Err(anyhow!("No enum match for value {v}")), - } - } -} - impl fmt::Display for HardwareCurrentlySupported { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { @@ -81,17 +64,6 @@ impl fmt::Display for HardwareCurrentlySupported { } } -impl TryFrom for FanControlState { - type Error = Error; - fn try_from(v: u32) -> Result { - match v { - x if x == FanControlState::Bios as u32 => Ok(FanControlState::Bios), - x if x == FanControlState::Os as u32 => Ok(FanControlState::Os), - _ => Err(anyhow!("No enum match for value {v}")), - } - } -} - impl FromStr for FanControlState { type Err = Error; fn from_str(input: &str) -> Result { @@ -172,7 +144,7 @@ impl FanControl { }) => { let res = script_exit_code(&status.script, &status.script_args).await?; ensure!(res >= 0, "Script exited abnormally"); - FanControlState::try_from(res as u32) + Ok(FanControlState::try_from(res as u32)?) } None => bail!("Fan control not configured"), } diff --git a/src/power.rs b/src/power.rs index 6723775..b5d0c71 100644 --- a/src/power.rs +++ b/src/power.rs @@ -7,6 +7,7 @@ use anyhow::{anyhow, bail, ensure, Result}; use lazy_static::lazy_static; +use num_enum::TryFromPrimitive; use regex::Regex; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -43,8 +44,9 @@ lazy_static! { Regex::new(r"^\s*(?[0-9]+): (?[0-9]+)Mhz").unwrap(); } -#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone)] +#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone, TryFromPrimitive)] #[strum(serialize_all = "snake_case")] +#[repr(u32)] pub enum GPUPowerProfile { // Currently firmware exposes these values, though // deck doesn't support them yet @@ -60,22 +62,6 @@ pub enum GPUPowerProfile { Uncapped = 9, } -impl TryFrom for GPUPowerProfile { - type Error = &'static str; - fn try_from(v: u32) -> Result { - match v { - x if x == GPUPowerProfile::FullScreen as u32 => Ok(GPUPowerProfile::FullScreen), - x if x == GPUPowerProfile::Video as u32 => Ok(GPUPowerProfile::Video), - x if x == GPUPowerProfile::VR as u32 => Ok(GPUPowerProfile::VR), - x if x == GPUPowerProfile::Compute as u32 => Ok(GPUPowerProfile::Compute), - x if x == GPUPowerProfile::Custom as u32 => Ok(GPUPowerProfile::Custom), - x if x == GPUPowerProfile::Capped as u32 => Ok(GPUPowerProfile::Capped), - x if x == GPUPowerProfile::Uncapped as u32 => Ok(GPUPowerProfile::Uncapped), - _ => Err("No GPUPowerProfile for value"), - } - } -} - #[derive(Display, EnumString, PartialEq, Debug, Copy, Clone)] #[strum(serialize_all = "snake_case")] pub enum GPUPerformanceLevel { diff --git a/src/wifi.rs b/src/wifi.rs index 756ac6d..e59bd2e 100644 --- a/src/wifi.rs +++ b/src/wifi.rs @@ -5,9 +5,10 @@ * SPDX-License-Identifier: MIT */ -use anyhow::{anyhow, bail, ensure, Error, Result}; +use anyhow::{bail, ensure, Result}; use config::builder::AsyncState; use config::{ConfigBuilder, FileFormat}; +use num_enum::TryFromPrimitive; use std::str::FromStr; use strum::{Display, EnumString}; use tokio::fs; @@ -37,7 +38,7 @@ const WIFI_BACKEND_PATHS: &[&str] = &[ "/etc/NetworkManager/conf.d", ]; -#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone)] +#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone, TryFromPrimitive)] #[strum(serialize_all = "snake_case", ascii_case_insensitive)] #[repr(u32)] pub enum WifiDebugMode { @@ -51,7 +52,7 @@ pub enum WifiDebugMode { Tracing = 1, } -#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone)] +#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone, TryFromPrimitive)] #[strum(ascii_case_insensitive)] #[repr(u32)] pub enum WifiPowerManagement { @@ -71,7 +72,7 @@ pub enum WifiPowerManagement { Enabled = 1, } -#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone)] +#[derive(Display, EnumString, PartialEq, Debug, Copy, Clone, TryFromPrimitive)] #[strum(serialize_all = "snake_case", ascii_case_insensitive)] #[repr(u32)] pub enum WifiBackend { @@ -79,39 +80,6 @@ pub enum WifiBackend { WPASupplicant = 1, } -impl TryFrom for WifiDebugMode { - type Error = Error; - fn try_from(v: u32) -> Result { - match v { - x if x == WifiDebugMode::Off as u32 => Ok(WifiDebugMode::Off), - x if x == WifiDebugMode::Tracing as u32 => Ok(WifiDebugMode::Tracing), - _ => Err(anyhow!("No enum match for value {v}")), - } - } -} - -impl TryFrom for WifiPowerManagement { - type Error = Error; - fn try_from(v: u32) -> Result { - match v { - x if x == WifiPowerManagement::Disabled as u32 => Ok(WifiPowerManagement::Disabled), - x if x == WifiPowerManagement::Enabled as u32 => Ok(WifiPowerManagement::Enabled), - _ => Err(anyhow!("No enum match for value {v}")), - } - } -} - -impl TryFrom for WifiBackend { - type Error = Error; - fn try_from(v: u32) -> Result { - match v { - x if x == WifiBackend::Iwd as u32 => Ok(WifiBackend::Iwd), - x if x == WifiBackend::WPASupplicant as u32 => Ok(WifiBackend::WPASupplicant), - _ => Err(anyhow!("No enum match for WifiBackend value {v}")), - } - } -} - pub(crate) async fn setup_iwd_config(want_override: bool) -> std::io::Result<()> { // Copy override.conf file into place or out of place depending // on install value