luciders/src/icons.rs
Compositr 2d6df9f737 refactor: various clippy-suggested improvements
most notably, change a lot fo match in main.rs to if-let
2024-11-06 17:00:54 +11:00

77 lines
2.7 KiB
Rust

use std::{env, ffi::OsString, fs};
const ICON_FILE_EXTENSION: &str = ".svg";
pub const ICON_FILE_EXTENSION_LEN: usize = ICON_FILE_EXTENSION.len();
pub struct Icons {
icons_dir_path: String,
icon_filenames: Vec<OsString>,
}
impl Icons {
/// Build the Icons (handler) struct
///
/// Returns a result with the Icons struct or an error message
pub fn build() -> Result<Self, &'static str> {
let icons_dir_arg = env::args()
.nth(1)
.unwrap_or(String::from("vendor/lucide/icons"));
let icon_dir = match fs::read_dir(&icons_dir_arg) {
Ok(dir) => dir,
Err(_) => return Err("Failed to read icon directory"),
};
let icon_filenames: Vec<_> = icon_dir
.map(|entry| entry.unwrap().file_name())
.filter(|entry| entry.to_str().unwrap_or("").ends_with(".svg"))
.collect();
Ok(Icons {
icons_dir_path: icons_dir_arg,
icon_filenames,
})
}
/// Check if the icon exists
///
/// Cheap; does not actually call the fs - instead checks against the cached filenames in the Vec internal to this struct.
/// Therefore, it is not guaranteed to be up-to-date with the actual filesystem
///
/// icon: the icon name to check (no .svg extension)
pub fn has_iconname(&self, icon: &str) -> bool {
self.icon_filenames
.iter()
.any(|i| match i.to_str() {
Some(i) => &i[..i.len() - ICON_FILE_EXTENSION_LEN] == icon,
None => false,
})
}
/// Get the number of icons
///
/// Cheap; does not actually call the fs - instead returns the length of the cached filenames in the Vec internal to this struct.
pub fn icons_len(&self) -> usize {
self.icon_filenames.len()
}
/// Read an .svg icon from disk to a Vec<u8>
///
/// You may want to check if the icon exists first with has_iconname(), although that method does not guarantee the icon is still present on the disk.
///
/// icon: the icon name to read (no .svg extension)
pub fn get_icon(&self, icon: &str) -> Option<Vec<u8>> {
let icon_path = format!("{}/{}.svg", self.icons_dir_path, icon);
fs::read(icon_path).ok()
}
/// Read an .svg icon from disk to a String, instead of a Vec<u8>
///
/// You may want to check if the icon exists first with has_iconname(), although that method does not guarantee the icon is still present on the disk.
///
/// icon: the icon name to read (no .svg extension)
pub fn get_icon_string(&self, icon: &str) -> Option<String> {
let icon_path = format!("{}/{}.svg", self.icons_dir_path, icon);
fs::read_to_string(icon_path).ok()
}
}