use crate::themes::theme::{CursorMapping, CursorType};
use std::{fs, path::Path};
use anyhow::{Result, anyhow, bail};
use configparser::ini::Ini;
fn section_to_type(section: &str) -> Option<CursorType> {
use CursorType::*;
Some(match section {
"arrow" | "default" => Arrow, "help" => Help,
"appstarting" => LeftPtrWatch,
"wait" => Watch,
"crosshair" => Crosshair,
"ibeam" => Text,
"nwpen" => Pencil,
"no" => Forbidden,
"sizenesw" => NeswResize,
"sizens" => NsResize,
"sizewe" => EwResize,
"sizenwse" => NwseResize,
"sizeall" => Move,
"uparrow" => CenterPtr,
"hand" => Hand,
_ => {
return None;
}
})
}
pub fn parse_crs_installer(crs_path: &Path, theme_dir: &Path) -> Result<Vec<CursorMapping>> {
let crs_string = fs::read_to_string(crs_path)?;
let crs = Ini::new()
.read(crs_string)
.map_err(|e| anyhow!("failed to read crs, error e={e}"))?;
let mut mappings = Vec::with_capacity(CursorType::NUM_VARIANTS);
for section_name in crs.keys() {
let Some(r#type) = section_to_type(section_name) else {
bail!("unexpected section in crs file (please report), section={section_name}");
};
let relative_path = crs.get(section_name).and_then(|s| s.get("path"));
let Some(Some(relative_path)) = relative_path else {
eprintln!("[warning] skipping section_name={section_name}");
continue;
};
let path = theme_dir.join(relative_path);
mappings.push(CursorMapping { r#type, path });
}
Ok(mappings)
}