diff --git a/Cargo.toml b/Cargo.toml index 37b5731..2bea5e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ thiserror = "2.0" xdg = "2.5" tracing = "0.1.0" ini_core = "0.2.0" +memmap2 = "0.9" [dev-dependencies] speculoos = "0.11.0" diff --git a/src/lib.rs b/src/lib.rs index c8a4db6..617660b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -325,9 +325,15 @@ impl<'a> LookupBuilder<'a> { let mut parents = icon_themes .iter() .flat_map(|t| { - let file = theme::read_ini_theme(&t.index); + let Ok(file) = theme::read_ini_theme(&t.index) else { + return Vec::new(); + }; - t.inherits(file.as_ref()) + let Ok(file) = std::str::from_utf8(file.as_ref()) else { + return Vec::new(); + }; + + t.inherits(file) .into_iter() .map(String::from) .collect::>() diff --git a/src/theme/mod.rs b/src/theme/mod.rs index f082cb8..99336c8 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -1,5 +1,6 @@ use crate::theme::error::ThemeError; use crate::theme::paths::ThemePath; +use memmap2::Mmap; pub(crate) use paths::BASE_PATHS; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; @@ -15,8 +16,8 @@ type Result = std::result::Result; pub static THEMES: LazyLock>> = LazyLock::new(get_all_themes); #[inline] -pub fn read_ini_theme(path: &Path) -> String { - std::fs::read_to_string(path).unwrap_or_default() +pub fn read_ini_theme(path: &Path) -> std::io::Result { + std::fs::File::open(path).and_then(|file| unsafe { Mmap::map(&file) }) } #[derive(Debug)] @@ -34,10 +35,10 @@ impl Theme { scale: u16, force_svg: bool, ) -> Option { - eprintln!("try_get_icon: {name}"); - let file = read_ini_theme(&self.index); - self.try_get_icon_exact_size(file.as_str(), name, size, scale, force_svg) - .or_else(|| self.try_get_icon_closest_size(file.as_str(), name, size, scale, force_svg)) + let file = read_ini_theme(&self.index).ok()?; + let file = std::str::from_utf8(file.as_ref()).ok()?; + self.try_get_icon_exact_size(file, name, size, scale, force_svg) + .or_else(|| self.try_get_icon_closest_size(file, name, size, scale, force_svg)) } #[inline] @@ -234,8 +235,9 @@ mod test { println!( "{:?}", themes.iter().find_map(|t| { - let file = crate::theme::read_ini_theme(&t.index); - t.try_get_icon_exact_size(file.as_str(), "edit-delete-symbolic", 24, 1, false) + let file = super::read_ini_theme(&t.index).ok()?; + let file = std::str::from_utf8(file.as_ref()).ok()?; + t.try_get_icon_exact_size(file, "edit-delete-symbolic", 24, 1, false) }) ); } @@ -244,8 +246,9 @@ mod test { fn should_get_png_first() { let themes = THEMES.get("hicolor").unwrap(); let icon = themes.iter().find_map(|t| { - let file = crate::theme::read_ini_theme(&t.index); - t.try_get_icon_exact_size(file.as_str(), "blueman", 24, 1, true) + let file = super::read_ini_theme(&t.index).ok()?; + let file = std::str::from_utf8(file.as_ref()).ok()?; + t.try_get_icon_exact_size(file, "blueman", 24, 1, true) }); assert_that!(icon).is_some().is_equal_to(PathBuf::from( "/usr/share/icons/hicolor/22x22/apps/blueman.png", @@ -256,8 +259,9 @@ mod test { fn should_get_svg_first() { let themes = THEMES.get("hicolor").unwrap(); let icon = themes.iter().find_map(|t| { - let file = crate::theme::read_ini_theme(&t.index); - t.try_get_icon_exact_size(file.as_str(), "blueman", 24, 1, false) + let file = super::read_ini_theme(&t.index).ok()?; + let file = std::str::from_utf8(file.as_ref()).ok()?; + t.try_get_icon_exact_size(file, "blueman", 24, 1, false) }); assert_that!(icon).is_some().is_equal_to(PathBuf::from( "/usr/share/icons/hicolor/22x22/apps/blueman.png", diff --git a/src/theme/parse.rs b/src/theme/parse.rs index ea40bf4..c3e223c 100644 --- a/src/theme/parse.rs +++ b/src/theme/parse.rs @@ -127,8 +127,9 @@ mod test { #[test] fn should_get_theme_parents() { for theme in THEMES.get("Arc").unwrap() { - let file = crate::theme::read_ini_theme(&theme.index); - let parents = theme.inherits(&file); + let file = crate::theme::read_ini_theme(&theme.index).ok().unwrap(); + let file = std::str::from_utf8(file.as_ref()).ok().unwrap(); + let parents = theme.inherits(file); assert_that!(parents).does_not_contain("hicolor");