diff --git a/src/io_err.rs b/src/io_err.rs new file mode 100644 index 0000000..2962c52 --- /dev/null +++ b/src/io_err.rs @@ -0,0 +1,14 @@ +use std::io::Error as IoErr; +use std::io::ErrorKind; + +pub fn invalid_data() -> IoErr { + IoErr::from(ErrorKind::InvalidData) +} + +pub fn not_found() -> IoErr { + IoErr::from(ErrorKind::NotFound) +} + +pub fn invalid_input() -> IoErr { + IoErr::from(ErrorKind::NotFound) +} diff --git a/src/main.rs b/src/main.rs index 48bea10..510b647 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,13 @@ mod config; +mod io_err; +mod monitor; extern crate log; -use std::io::Error as IoErr; use std::io::ErrorKind; use crate::config::{load_config, Card, Config}; +use crate::io_err::{invalid_data, not_found}; use gumdrop::Options; use std::fmt::Formatter; @@ -58,11 +60,9 @@ pub struct HwMon { } mod hw_mon { - use std::io::Error as IoErr; - use crate::config::Card; + use crate::io_err::{invalid_input, not_found}; use crate::{linear_map, AmdFanError, HwMon, HW_MON_DIR, ROOT_DIR}; - use std::io::ErrorKind; /// pulse width modulation fan control minimum level (0) const PULSE_WIDTH_MODULATION_MIN: &str = "pwm1_min"; @@ -101,7 +101,7 @@ mod hw_mon { .last() .copied() .map(|temp| temp as f64 / 1000f64) - .ok_or_else(|| IoErr::from(ErrorKind::InvalidInput)) + .ok_or_else(invalid_input) } pub fn gpu_temp(&self) -> Vec<(String, std::io::Result)> { @@ -120,7 +120,7 @@ mod hw_mon { fn read_gpu_temp(&self, name: &str) -> std::io::Result { self.read(name)?.parse::().map_err(|e| { log::warn!("Read from gpu monitor failed. Invalid temperature. {}", e); - IoErr::from(ErrorKind::InvalidInput) + invalid_input() }) } @@ -146,7 +146,7 @@ mod hw_mon { pub fn pwm(&self) -> std::io::Result { self.read(PULSE_WIDTH_MODULATION)?.parse().map_err(|_e| { log::warn!("Read from gpu monitor failed. Invalid pwm value"); - IoErr::from(ErrorKind::InvalidInput) + invalid_input() }) } @@ -266,7 +266,7 @@ mod hw_mon { }) .take(1) .last() - .ok_or_else(|| IoErr::from(ErrorKind::NotFound))?; + .ok_or_else(not_found)?; Ok(HwMon::new(&card, &name)) } } @@ -320,10 +320,6 @@ pub struct Opts { command: Option, } -fn invalid_data() -> IoErr { - IoErr::from(ErrorKind::InvalidData) -} - fn read_cards() -> std::io::Result> { let mut cards = vec![]; let entries = std::fs::read_dir(ROOT_DIR)?; @@ -397,7 +393,7 @@ fn change_mode(switcher: Switcher, mode: FanMode, config: Config) -> std::io::Re for hw_mon in controllers { eprintln!(" * {}", *hw_mon.card); } - return Err(IoErr::from(ErrorKind::NotFound)); + return Err(not_found()); } }, None => controllers, @@ -420,106 +416,6 @@ fn change_mode(switcher: Switcher, mode: FanMode, config: Config) -> std::io::Re Ok(()) } -mod monitor { - use crate::config::Config; - use crate::{controllers, AmdFanError}; - use std::str::FromStr; - - #[derive(Debug)] - pub enum MonitorFormat { - Short, - Verbose, - } - - impl Default for MonitorFormat { - fn default() -> Self { - MonitorFormat::Short - } - } - - impl FromStr for MonitorFormat { - type Err = AmdFanError; - - fn from_str(s: &str) -> Result { - match s { - "short" | "s" => Ok(MonitorFormat::Short), - "verbose" | "v" | "long" | "l" => Ok(MonitorFormat::Verbose), - _ => Err(AmdFanError::InvalidMonitorFormat), - } - } - } - - #[derive(Debug, gumdrop::Options)] - pub struct Monitor { - #[options(help = "Help message")] - help: bool, - #[options(help = "Help message")] - format: MonitorFormat, - } - - pub fn run(monitor: Monitor, config: Config) -> std::io::Result<()> { - match monitor.format { - MonitorFormat::Short => short(config), - MonitorFormat::Verbose => verbose(config), - } - } - - pub fn verbose(config: Config) -> std::io::Result<()> { - let mut controllers = controllers(&config, true)?; - loop { - print!("{esc}[2J{esc}[1;1H", esc = 27 as char); - for hw_mon in controllers.iter_mut() { - println!("Card {:3}", hw_mon.card.to_string().replace("card", "")); - println!(" MIN | MAX | PWM | %"); - println!( - " {:>4} | {:>4} | {:>6} | {:>3}", - hw_mon.pwm_min(), - hw_mon.pwm_max(), - hw_mon - .pwm() - .map_or_else(|_e| String::from("FAILED"), |f| f.to_string()), - (hw_mon.pwm().unwrap_or_default() as f32 / 2.55).round(), - ); - - println!(); - println!(" Current temperature"); - hw_mon.gpu_temp().into_iter().for_each(|(name, temp)| { - println!( - " {:6} | {:>9.2}", - name.replace("_input", ""), - temp.unwrap_or_default(), - ); - }); - } - println!(); - println!("> PWM may be 0 even if RPM is higher"); - std::thread::sleep(std::time::Duration::from_secs(4)); - } - } - - pub fn short(config: Config) -> std::io::Result<()> { - let mut controllers = controllers(&config, true)?; - loop { - print!("{esc}[2J{esc}[1;1H", esc = 27 as char); - for hw_mon in controllers.iter_mut() { - println!( - "Card {:3} | Temp | MIN | MAX | PWM | %", - hw_mon.card.to_string().replace("card", "") - ); - println!( - " | {:>5.2} | {:>4} | {:>4} | {:>4} | {:>3}", - hw_mon.max_gpu_temp().unwrap_or_default(), - hw_mon.pwm_min(), - hw_mon.pwm_max(), - hw_mon.pwm().unwrap_or_default(), - (hw_mon.pwm().unwrap_or_default() as f32 / 2.55).round(), - ); - } - std::thread::sleep(std::time::Duration::from_secs(4)); - } - } -} - fn main() -> std::io::Result<()> { if std::fs::read(CONFIG_DIR).map_err(|e| e.kind() == ErrorKind::NotFound) == Err(true) { std::fs::create_dir_all(CONFIG_DIR)?; diff --git a/src/monitor.rs b/src/monitor.rs new file mode 100644 index 0000000..c5a40c3 --- /dev/null +++ b/src/monitor.rs @@ -0,0 +1,97 @@ +use crate::config::Config; +use crate::{controllers, AmdFanError}; +use std::str::FromStr; + +#[derive(Debug)] +pub enum MonitorFormat { + Short, + Verbose, +} + +impl Default for MonitorFormat { + fn default() -> Self { + MonitorFormat::Short + } +} + +impl FromStr for MonitorFormat { + type Err = AmdFanError; + + fn from_str(s: &str) -> Result { + match s { + "short" | "s" => Ok(MonitorFormat::Short), + "verbose" | "v" | "long" | "l" => Ok(MonitorFormat::Verbose), + _ => Err(AmdFanError::InvalidMonitorFormat), + } + } +} + +#[derive(Debug, gumdrop::Options)] +pub struct Monitor { + #[options(help = "Help message")] + help: bool, + #[options(help = "Help message")] + format: MonitorFormat, +} + +pub fn run(monitor: Monitor, config: Config) -> std::io::Result<()> { + match monitor.format { + MonitorFormat::Short => short(config), + MonitorFormat::Verbose => verbose(config), + } +} + +pub fn verbose(config: Config) -> std::io::Result<()> { + let mut controllers = controllers(&config, true)?; + loop { + print!("{esc}[2J{esc}[1;1H", esc = 27 as char); + for hw_mon in controllers.iter_mut() { + println!("Card {:3}", hw_mon.card.to_string().replace("card", "")); + println!(" MIN | MAX | PWM | %"); + println!( + " {:>4} | {:>4} | {:>6} | {:>3}", + hw_mon.pwm_min(), + hw_mon.pwm_max(), + hw_mon + .pwm() + .map_or_else(|_e| String::from("FAILED"), |f| f.to_string()), + (hw_mon.pwm().unwrap_or_default() as f32 / 2.55).round(), + ); + + println!(); + println!(" Current temperature"); + hw_mon.gpu_temp().into_iter().for_each(|(name, temp)| { + println!( + " {:6} | {:>9.2}", + name.replace("_input", ""), + temp.unwrap_or_default(), + ); + }); + } + println!(); + println!("> PWM may be 0 even if RPM is higher"); + std::thread::sleep(std::time::Duration::from_secs(4)); + } +} + +pub fn short(config: Config) -> std::io::Result<()> { + let mut controllers = controllers(&config, true)?; + loop { + print!("{esc}[2J{esc}[1;1H", esc = 27 as char); + for hw_mon in controllers.iter_mut() { + println!( + "Card {:3} | Temp | MIN | MAX | PWM | %", + hw_mon.card.to_string().replace("card", "") + ); + println!( + " | {:>5.2} | {:>4} | {:>4} | {:>4} | {:>3}", + hw_mon.max_gpu_temp().unwrap_or_default(), + hw_mon.pwm_min(), + hw_mon.pwm_max(), + hw_mon.pwm().unwrap_or_default(), + (hw_mon.pwm().unwrap_or_default() as f32 / 2.55).round(), + ); + } + std::thread::sleep(std::time::Duration::from_secs(4)); + } +}