diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 2d84f2f..d19b536 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -8,6 +8,7 @@ version = "0.0.1" dependencies = [ "anyhow", "log", + "regex", "serde", "serde_json", "tauri", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 9d5fced..1fd0d38 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -24,6 +24,7 @@ tauri-build = { version = "2.1.0", features = [] } log = "0.4.26" serde_json = "1.0.140" serde = { version = "1.0.219", features = ["derive"] } +regex = "1.11.1" tauri = { version = "2.4.0", features = [ "macos-private-api", "tray-icon" ] } diff --git a/src-tauri/src/tool/powerplan.rs b/src-tauri/src/tool/powerplan.rs index 1296b62..d0fb5d7 100644 --- a/src-tauri/src/tool/powerplan.rs +++ b/src-tauri/src/tool/powerplan.rs @@ -1,8 +1,109 @@ -pub fn get_powerplan<'a>() -> Result { - Ok(String::from("")) +use std::collections::HashMap; +use std::process::Command; + +pub struct PowerPlan { + power_plan_map: HashMap, } -pub fn set_powerplan<'a>(plan: &str) -> Result { - println!("{}", plan); - Ok(String::from("")) +impl PowerPlan { + pub fn new() -> Self { + let mut power_plan_map = HashMap::new(); + power_plan_map.insert(PowerPlanMode::PowerSaving as i32, "a1841308-3541-4fab-bc81-f71556f20b4a".to_string()); + power_plan_map.insert(PowerPlanMode::Balanced as i32, "381b4222-f694-41f0-9685-ff5bb260df2e".to_string()); + power_plan_map.insert(PowerPlanMode::HighPerformance as i32, "8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c".to_string()); + power_plan_map.insert(PowerPlanMode::Extreme as i32, "e9a42b02-d5df-448d-aa00-03f14749eb61".to_string()); + + PowerPlan { power_plan_map } + } + + pub fn set(&self, mode: i32) -> Result<(), String> { + let guid = self.power_plan_map.get(&mode).ok_or("Invalid power plan number (expect from 1 to 4)")?; + + let output = Command::new("powercfg") + .arg("/S") + .arg(guid) + .output() + .map_err(|e| format!("Failed to execute powercfg command: {}", e))?; + + if !output.status.success() { + return Err(format!("Powercfg command failed: {}", String::from_utf8_lossy(&output.stderr))); + } + + Ok(()) + } + + pub fn get(&self) -> Result { + let output = Command::new("powercfg") + .arg("/L") + .output() + .map_err(|e| format!("Failed to execute powercfg command: {}", e))?; + + let output_str = String::from_utf8_lossy(&output.stdout); + let re = regex::Regex::new(r"GUID:\s+(\S+)\s+\(\S+\)\s+\*") + .map_err(|e| format!("Failed to compile regex: {}", e))?; + + let res = re.captures(&output_str).ok_or("No matching power plan found")?; + let guid = res.get(1).ok_or("No GUID found in power plan output")?.as_str(); + + for (k, v) in &self.power_plan_map { + if guid == v { + return Ok(*k); + } + } + + Err("No matching power plan found in map".to_string()) + } } + +#[allow(dead_code)] +pub enum PowerPlanMode { + Other = 0, + PowerSaving = 1, + Balanced = 2, + HighPerformance = 3, + Extreme = 4, +} + +pub fn get_powerplan() -> Result { + let power_plan = PowerPlan::new(); + let mode = power_plan.get()?; + Ok(mode.to_string()) +} + +pub fn set_powerplan(plan: &str) -> Result { + let mode: i32 = plan.parse().map_err(|_| "Invalid power plan number")?; + let power_plan = PowerPlan::new(); + power_plan.set(mode)?; + Ok("Power plan set successfully".to_string()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_set_power_plan() { + let power_plan = PowerPlan::new(); + // 测试设置节能模式 + let result = power_plan.set(PowerPlanMode::PowerSaving as i32); + assert!(result.is_ok(), "Failed to set power saving plan"); + + // 测试设置无效模式 + let result = power_plan.set(99); + assert!(result.is_err(), "Setting invalid power plan should fail"); + } + + #[test] + fn test_get_power_plan() { + let power_plan = PowerPlan::new(); + // 测试获取当前电源计划 + let result = power_plan.get(); + assert!(result.is_ok(), "Failed to get current power plan"); + + // 验证返回的模式是否在有效范围内 + let mode = result.unwrap(); + assert!((1..=4).contains(&mode), "Invalid power plan mode returned"); + println!("Mode: {} - {}", mode, PowerPlan::new().power_plan_map[&mode]); + + } +} \ No newline at end of file