mirror of
https://github.com/imgurbot12/rmenu.git
synced 2025-01-27 13:28:03 +01:00
feat: better icon collect coverage
This commit is contained in:
parent
a776eededd
commit
a14ce28167
1 changed files with 54 additions and 9 deletions
|
@ -1,4 +1,5 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::fs::FileType;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{fs::read_to_string, path::Path};
|
use std::{fs::read_to_string, path::Path};
|
||||||
|
|
||||||
|
@ -64,18 +65,42 @@ fn calculate_sizes(range: (usize, usize, usize)) -> HashSet<String> {
|
||||||
sizes
|
sizes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn is_valid_icon(name: &str) -> bool {
|
||||||
|
name.ends_with(".png") || name.ends_with(".svg")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse Icon-Name from Filename
|
||||||
|
#[inline]
|
||||||
|
fn icon_name(name: &str) -> String {
|
||||||
|
name.rsplit_once(".")
|
||||||
|
.map(|(i, _)| i)
|
||||||
|
.unwrap_or(&name)
|
||||||
|
.to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse and Categorize Icons Within the Specified Path
|
/// Parse and Categorize Icons Within the Specified Path
|
||||||
fn find_icons(path: &PathBuf, sizes: (usize, usize, usize)) -> Vec<IconGroup> {
|
fn find_icons(path: &PathBuf, sizes: (usize, usize, usize)) -> Vec<IconGroup> {
|
||||||
let sizes = calculate_sizes(sizes);
|
let sizes = calculate_sizes(sizes);
|
||||||
|
let mut extras = IconGroup::new();
|
||||||
let icons: Icons = WalkDir::new(path)
|
let icons: Icons = WalkDir::new(path)
|
||||||
// collect list of directories of icon subdirs
|
// collect list of directories of icon subdirs
|
||||||
.max_depth(1)
|
.max_depth(1)
|
||||||
|
.follow_links(true)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
.filter(|e| e.file_type().is_dir())
|
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
let name = e.file_name().to_str()?.to_string();
|
let name = e.file_name().to_str()?;
|
||||||
Some((name, e.path().to_owned()))
|
let path = e.path().to_owned();
|
||||||
|
match e.file_type().is_dir() {
|
||||||
|
true => Some((name.to_owned(), path)),
|
||||||
|
false => {
|
||||||
|
if is_valid_icon(name) {
|
||||||
|
extras.insert(icon_name(name), path);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
// iterate content within subdirs
|
// iterate content within subdirs
|
||||||
.map(|(name, path)| {
|
.map(|(name, path)| {
|
||||||
|
@ -85,10 +110,9 @@ fn find_icons(path: &PathBuf, sizes: (usize, usize, usize)) -> Vec<IconGroup> {
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
.filter(|e| e.file_type().is_file())
|
.filter(|e| e.file_type().is_file())
|
||||||
.filter_map(|e| {
|
.filter_map(|e| {
|
||||||
let name = e.file_name().to_str()?.to_string();
|
let name = e.file_name().to_str()?;
|
||||||
if name.ends_with(".png") || name.ends_with(".svg") {
|
if is_valid_icon(name) {
|
||||||
let icon = name.rsplit_once(".").map(|(i, _)| i).unwrap_or(&name);
|
return Some((icon_name(name), e.path().to_owned()));
|
||||||
return Some((icon.to_owned(), e.path().to_owned()));
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
|
@ -110,9 +134,27 @@ fn find_icons(path: &PathBuf, sizes: (usize, usize, usize)) -> Vec<IconGroup> {
|
||||||
})
|
})
|
||||||
.last();
|
.last();
|
||||||
priority.append(&mut others);
|
priority.append(&mut others);
|
||||||
|
priority.push(extras);
|
||||||
priority
|
priority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve Extras in Base Icon Directories
|
||||||
|
fn find_icon_extras(path: &PathBuf) -> IconGroup {
|
||||||
|
WalkDir::new(path)
|
||||||
|
.max_depth(1)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|e| e.ok())
|
||||||
|
.filter(|e| e.file_type().is_file())
|
||||||
|
.filter_map(|e| {
|
||||||
|
let name = e.file_name().to_str()?;
|
||||||
|
if is_valid_icon(name) {
|
||||||
|
return Some((icon_name(&name), e.path().to_owned()));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
/// Retrieve XDG-DATA Directories
|
/// Retrieve XDG-DATA Directories
|
||||||
fn data_dirs(dir: &str) -> Vec<PathBuf> {
|
fn data_dirs(dir: &str) -> Vec<PathBuf> {
|
||||||
std::env::var(XDG_DATA_ENV)
|
std::env::var(XDG_DATA_ENV)
|
||||||
|
@ -197,16 +239,19 @@ fn main() {
|
||||||
// build a collection of icons for configured themes
|
// build a collection of icons for configured themes
|
||||||
let cfgdir = config_dir();
|
let cfgdir = config_dir();
|
||||||
let themes = find_theme(&cfgdir);
|
let themes = find_theme(&cfgdir);
|
||||||
let icons: Vec<IconGroup> = data_dirs("icons")
|
let icon_paths = data_dirs("icons");
|
||||||
|
let mut icons: Vec<IconGroup> = icon_paths
|
||||||
// generate list of icon-paths that exist
|
// generate list of icon-paths that exist
|
||||||
.iter()
|
.iter()
|
||||||
.map(|d| themes.iter().map(|t| d.join(t)))
|
.map(|d| themes.iter().map(|t| d.join(t)))
|
||||||
.flatten()
|
.flatten()
|
||||||
.filter(|t| t.exists())
|
.filter(|t| t.exists())
|
||||||
|
// append icon-paths within supported themes
|
||||||
.map(|t| find_icons(&t, sizes))
|
.map(|t| find_icons(&t, sizes))
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
// add extra icons found in base folders
|
||||||
|
icons.extend(icon_paths.iter().map(|p| find_icon_extras(p)));
|
||||||
// retrieve desktop applications and assign icons before printing results
|
// retrieve desktop applications and assign icons before printing results
|
||||||
data_dirs("applications")
|
data_dirs("applications")
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
Loading…
Reference in a new issue