From e084ef469cb8b90d1ecbe7f4b13bdcbc06f1be47 Mon Sep 17 00:00:00 2001 From: Jens Korinth Date: Fri, 19 Apr 2024 23:10:41 +0200 Subject: [PATCH] Improve error precision --- src/themes/color.rs | 25 ++++++++++---------- src/themes/xresources.rs | 50 ++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/themes/color.rs b/src/themes/color.rs index 9c6f03d269..acfe91de08 100644 --- a/src/themes/color.rs +++ b/src/themes/color.rs @@ -218,19 +218,20 @@ impl FromStr for Color { Color::Hsva(Hsva::new(h, s / 100., v / 100., (a / 100. * 255.) as u8)) } else if color.starts_with("x:") { let name = color.split_at(2).1; - let colors = super::xresources::COLORS - .as_ref() - .or_error(|| format!("error reading ~/.Xresources"))?; - let hex = colors - .get(name) - .or_error(|| format!("color '{name}' is not defined in .Xresources"))?; + let hex = super::xresources::get_color(name) + .map_err(|e| Self::Err::new(e))? + .ok_or_else(|| { + Self::Err::new(format!("color {} not defined in ~/.Xresources", name)) + })?; let err_msg = || format!("'{name}' def '{hex}' cannot be parsed as RGB"); - let rgb = hex.get(1..7).or_error(err_msg)?; - let a = hex.get(7..9).unwrap_or("FF"); - Color::Rgba(Rgba::from_hex( - (u32::from_str_radix(rgb, 16).or_error(err_msg)? << 8) - + u32::from_str_radix(a, 16).or_error(err_msg)?, - )) + let rgb = hex + .get(1..7) + .map(|rgb| u32::from_str_radix(rgb, 16).ok()) + .flatten(); + let a = u32::from_str_radix(hex.get(7..9).unwrap_or("FF"), 16).ok(); + rgb.map(|rgb| a.map(|a| Color::Rgba(Rgba::from_hex((rgb << 8) + a)))) + .flatten() + .or_error(err_msg)? } else { let err_msg = || format!("'{color}' is not a valid RGBA color"); let rgb = color.get(1..7).or_error(err_msg)?; diff --git a/src/themes/xresources.rs b/src/themes/xresources.rs index 38121f23a4..45ef46812d 100644 --- a/src/themes/xresources.rs +++ b/src/themes/xresources.rs @@ -2,11 +2,16 @@ use log::*; use once_cell::sync::Lazy; use regex::Regex; -use std::{collections::HashMap, env, path::PathBuf}; +use std::collections::HashMap; + +#[cfg(not(test))] +use std::{env, path::PathBuf}; #[cfg(not(test))] fn read_xresources() -> std::io::Result { - let home = env::var("HOME").expect("HOME env var was not set?!"); + use std::io::{Error, ErrorKind}; + let home = env::var("HOME") + .map_err(|_| Error::new(ErrorKind::Other, "HOME env var was not set"))?; let xresources = PathBuf::from(home + "/.Xresources"); debug!(".Xresources @ {:?}", xresources); std::fs::read_to_string(xresources) @@ -18,26 +23,27 @@ use tests::read_xresources; static COLOR_REGEX: Lazy = Lazy::new(|| Regex::new(r"^\s*\*(?[^: ]+)\s*:\s*(?#[a-f0-9]{6}).*$").unwrap()); -pub static COLORS: Lazy, env::VarError>> = Lazy::new(|| { - let home = env::var("HOME")?; - let xresources = PathBuf::from(home + "/.Xresources"); - debug!(".Xresources @ {:?}", xresources); - if let Ok(content) = read_xresources() { - debug!(".Xresources content:\n{}", content); - return Ok(HashMap::from_iter( - content - .lines() - .map(|line| { - COLOR_REGEX - .captures(line) - .map(|caps| (caps["name"].to_string(), caps["color"].to_string())) - }) - .flatten(), - )); - } - warn!(".Xresources not found"); - Ok(HashMap::new()) -}); +static COLORS: Lazy, String>> = + Lazy::new(|| match read_xresources() { + Ok(content) => { + debug!(".Xresources content:\n{}", content); + return Ok(HashMap::from_iter( + content + .lines() + .map(|line| { + COLOR_REGEX + .captures(line) + .map(|caps| (caps["name"].to_string(), caps["color"].to_string())) + }) + .flatten(), + )); + } + Err(e) => Err(format!("could not read .Xresources: {}", e)), + }); + +pub fn get_color(name: &str) -> Result, String> { + Ok(COLORS.as_ref().map(|cmap| cmap.get(name))?) +} #[cfg(test)] mod tests {