From 7c4e5e97cfca92e193dc79b3241dc24e7f9e7279 Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Tue, 29 Jan 2019 01:00:12 +0100 Subject: Improve error handling --- src/main.rs | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/main.rs b/src/main.rs index 112b7a5..dbf2a81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,61 +10,73 @@ const PATH_ENERGY_NOW: &str = "/sys/class/power_supply/BAT0/energy_now"; const PATH_ENERGY_FULL: &str = "/sys/class/power_supply/BAT0/energy_full_design"; const PATH_LIGHT: &str = "/sys/devices/platform/thinkpad_acpi/leds/tpacpi::power/brightness"; +fn error(msg: &str) -> Error { + Error::new(ErrorKind::Other, msg) +} + +macro_rules! mytry { + ($expr : expr, $msg : expr) => (match $expr { + Ok(val) => val, + Err(err) => { + return Err(Error::new(ErrorKind::Other, format!("{}: {:?}", $msg, err))) + } + }); +} + fn file_read_integer>(path: P) -> Result { let mut buf = [0; 20]; - let mut file = OpenOptions::new().read(true).open(path.as_ref())?; - let len = file.read(&mut buf)?; + let mut file = mytry!(OpenOptions::new().read(true).open(path.as_ref()), + "Failed to open file"); + let len = mytry!(file.read(&mut buf), "Failed to read from file"); if len < 1 { - return Err(Error::new(ErrorKind::Other, "Empty file")); - }; + return Err(error("Failed to read value, file is empty")); + } - let s = str::from_utf8(&buf[0..len]) - .map_err(|e| Error::new(ErrorKind::Other, e))?; - s.trim().parse() - .map_err(|err| Error::new(ErrorKind::Other, format!("String parse failed: {}", err))) + let s = mytry!(str::from_utf8(&buf[0..len]), "UTF-8 error when reading file"); + Ok(mytry!(s.trim().parse(), "Failed to parse String")) } fn read_battery_percentage() -> Result { - let now = file_read_integer(PATH_ENERGY_NOW)?; - let full = file_read_integer(PATH_ENERGY_FULL)?; + let now = mytry!(file_read_integer(PATH_ENERGY_NOW), "Failed to read energy_now"); + let full = mytry!(file_read_integer(PATH_ENERGY_FULL), "Failed to read energy_full"); Ok(((now * 100) / full) as u32) } fn write_brightness(level: u8) -> Result<()> { let string = format!("{}\n", level); - let mut file = OpenOptions::new().write(true).open(PATH_LIGHT)?; - if file.write(string.as_bytes())? == string.len() { + let mut file = mytry!(OpenOptions::new().write(true).open(PATH_LIGHT), "Failed to open PATH_LIGHT"); + let bytes_written = mytry!(file.write(string.as_bytes()), "Failed to write brightness file"); + if bytes_written == string.len() { Ok(()) } else { - Err(Error::new(ErrorKind::Other, "Failed to write brightness")) + Err(error("Failed to write all bytes to brightness file")) } } fn read_brightness() -> Result { - let level = file_read_integer(PATH_LIGHT)?; + let level = mytry!(file_read_integer(PATH_LIGHT), "Failed to read PATH_LIGHT"); Ok(level as u8) } fn indicate_battery_level(level: u32) -> Result<()> { - let led_state = read_brightness()?; + let led_state = mytry!(read_brightness(), "Reading brightness failed"); let flashing_time: u32 = 10000; let offtime: u32 = 40; let ontime: u32 = 20; let n = flashing_time / (level * offtime + level * ontime); for _ in 0..n { - write_brightness(0)?; + mytry!(write_brightness(0), "Failed to switch off brightness"); sleep(Duration::from_millis(u64::from(level * offtime))); - write_brightness(1)?; + mytry!(write_brightness(1), "Failed to switch on brightness"); sleep(Duration::from_millis(u64::from(level * ontime))); } - write_brightness(led_state)?; + mytry!(write_brightness(led_state), "Failed to re-set brightness"); Ok(()) } fn main() { loop { - let p = read_battery_percentage(); - match p { + match read_battery_percentage() { Ok(level) => { if level < 20 { if let Err(e) = indicate_battery_level(level) { -- cgit v1.2.1