hyprshell_core_lib/util/
path.rs

1use crate::{get_config_dirs, get_config_home, get_data_dirs, get_data_home};
2use std::fs::DirEntry;
3use tracing::{trace, warn};
4
5/// Collects all .desktop files from standard directories
6/// according to the XDG Base Directory Specification.
7pub fn collect_desktop_files() -> Vec<DirEntry> {
8    let mut res = Vec::new();
9    let dirs = {
10        // ensure correct order
11        let mut dirs = Vec::new();
12        dirs.push(get_data_home().join("applications"));
13        get_data_dirs()
14            .iter()
15            .map(|d| d.join("applications"))
16            .for_each(|d| dirs.push(d));
17        dirs
18    };
19    for dir in dirs {
20        if !dir.exists() {
21            continue;
22        }
23        match dir.read_dir() {
24            Ok(dir) => {
25                for entry in dir.flatten() {
26                    let path = entry.path();
27                    if path.is_file()
28                        && path.extension().is_some_and(|e| e == "desktop")
29                        && !res
30                            .iter()
31                            .any(|e: &DirEntry| e.file_name() == entry.file_name())
32                    {
33                        res.push(entry);
34                    }
35                }
36            }
37            Err(e) => {
38                warn!("Failed to read dir {dir:?}: {e}");
39            }
40        }
41    }
42    trace!("found {} desktop files", res.len());
43    res
44}
45
46/// Collects all mimeapps.list files from standard directories
47/// according to the XDG Base Directory Specification.
48pub fn collect_mime_files() -> Vec<DirEntry> {
49    let mut res = Vec::new();
50    let dirs = {
51        // ensure correct order
52        let mut dirs = Vec::new();
53        dirs.push(get_config_home());
54        dirs.append(&mut get_config_dirs());
55        dirs.push(get_data_home().join("applications"));
56        get_data_dirs()
57            .iter()
58            .map(|d| d.join("applications"))
59            .for_each(|d| dirs.push(d));
60        dirs
61    };
62    for dir in dirs {
63        if !dir.exists() {
64            continue;
65        }
66        match dir.read_dir() {
67            Ok(dir) => {
68                for entry in dir.flatten() {
69                    let path = entry.path();
70                    if path.is_file()
71                        && path
72                            .file_name()
73                            .is_some_and(|e| e.to_string_lossy().ends_with("mimeapps.list"))
74                    {
75                        res.push(entry);
76                    }
77                }
78            }
79            Err(e) => {
80                warn!("Failed to read dir {dir:?}: {e}");
81            }
82        }
83    }
84    trace!("found {} mimeapps lists", res.len());
85    res
86}