diff --git a/Cargo.lock b/Cargo.lock index 9256099..482a849 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,14 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "ahash" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c251dce3391a07b43218ca070203ecb8f9f520d35ab71312296a59dbceab154" -dependencies = [ - "const-random", -] - [[package]] name = "ansi_term" version = "0.11.0" @@ -18,18 +9,6 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - [[package]] name = "ascii_table" version = "3.0.0" @@ -65,17 +44,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "blake2b_simd" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - [[package]] name = "block-buffer" version = "0.7.3" @@ -148,32 +116,6 @@ dependencies = [ "vec_map", ] -[[package]] -name = "const-random" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f1af9ac737b2dd2d577701e59fd09ba34822f6f2ebdb30a7647405d9e55e16a" -dependencies = [ - "const-random-macro", - "proc-macro-hack", -] - -[[package]] -name = "const-random-macro" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e4c606eb459dd29f7c57b2e0879f2b6f14ee130918c2b78ccb58a9624e6c7a" -dependencies = [ - "getrandom", - "proc-macro-hack", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - [[package]] name = "core-foundation" version = "0.7.0" @@ -190,28 +132,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "dashmap" -version = "3.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f87a04c37da1d3d27db1fb7f372802b72fb8c3ff3e9c0914530995127f4a6a1" -dependencies = [ - "ahash", - "cfg-if", - "num_cpus", -] - [[package]] name = "digest" version = "0.8.1" @@ -221,28 +141,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "dirs" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" -dependencies = [ - "cfg-if", - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" -dependencies = [ - "cfg-if", - "libc", - "redox_users", - "winapi 0.3.8", -] - [[package]] name = "dtoa" version = "0.4.5" @@ -390,8 +288,6 @@ name = "handlr" version = "0.2.1" dependencies = [ "ascii_table", - "dashmap", - "dirs", "itertools", "json", "mime-db", @@ -402,6 +298,7 @@ dependencies = [ "structopt", "thiserror", "url 2.1.1", + "xdg", ] [[package]] @@ -877,12 +774,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" - [[package]] name = "proc-macro2" version = "1.0.13" @@ -948,17 +839,6 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -[[package]] -name = "redox_users" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431" -dependencies = [ - "getrandom", - "redox_syscall", - "rust-argon2", -] - [[package]] name = "remove_dir_all" version = "0.5.2" @@ -1004,18 +884,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "rust-argon2" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017" -dependencies = [ - "base64", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - [[package]] name = "ryu" version = "1.0.4" @@ -1542,3 +1410,9 @@ dependencies = [ "winapi 0.2.8", "winapi-build", ] + +[[package]] +name = "xdg" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" diff --git a/Cargo.toml b/Cargo.toml index 65e0ea3..2f6e76a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,8 @@ license = "MIT" description = "Manage mimeapps.list and default applications with ease" [dependencies] -dirs = "2.0.2" pest = "2.1.3" pest_derive = "2.1.0" -dashmap = "3.11.1" structopt = "0.3.14" url = "2.1.1" itertools = "0.9.0" @@ -20,6 +18,7 @@ thiserror = "1.0.18" ascii_table = "3.0.0" mime-db = "0.1.5" mime-sniffer = "0.1.2" +xdg = "2.2.0" [profile.release] opt-level=3 diff --git a/src/common.rs b/src/common.rs index 9a81ae2..29d8d38 100644 --- a/src/common.rs +++ b/src/common.rs @@ -68,18 +68,9 @@ impl Handler { Self(name) } pub fn get_path(name: &str) -> Option { - let locally = { - let mut local_dir = dirs::data_dir()?; - local_dir.push("applications"); - local_dir.push(name); - Some(local_dir).filter(|p| p.exists()) - }; - let system = { - let mut sys = std::path::PathBuf::from("/usr/share/applications"); - sys.push(name); - Some(sys).filter(|p| p.exists()) - }; - locally.or(system) + xdg::BaseDirectories::new() + .ok()? + .find_data_file(&format!("applications/{}", name)) } pub fn resolve(name: String) -> Result { let path = Self::get_path(&name).ok_or(Error::NotFound)?; diff --git a/src/error.rs b/src/error.rs index 53603f7..b4de979 100644 --- a/src/error.rs +++ b/src/error.rs @@ -18,6 +18,8 @@ pub enum Error { BadMime(String), #[error("either mime (via -m) or extension (via -e) must be provided")] MissingMimeOrExt, + #[error(transparent)] + Xdg(#[from] xdg::BaseDirectoriesError), } pub type Result = std::result::Result; diff --git a/src/mimeapps.rs b/src/mimeapps.rs index 824c4a5..029c0ab 100644 --- a/src/mimeapps.rs +++ b/src/mimeapps.rs @@ -1,5 +1,4 @@ use crate::{DesktopEntry, Error, Handler, Mime, Result}; -use dashmap::DashMap; use pest::Parser; use std::{ collections::{HashMap, VecDeque}, @@ -53,12 +52,9 @@ impl MimeApps { Ok(()) } pub fn path() -> Result { - dirs::config_dir() - .map(|mut config_dir| { - config_dir.push("mimeapps.list"); - config_dir - }) - .ok_or(Error::NoConfigDir) + let mut config = xdg::BaseDirectories::new()?.get_config_home(); + config.push("mimeapps.list"); + Ok(config) } pub fn read() -> Result { let raw_conf = std::fs::read_to_string(Self::path()?)?; @@ -166,14 +162,10 @@ impl MimeApps { let stdout = std::io::stdout(); let mut stdout = stdout.lock(); - std::fs::read_dir("/usr/share/applications")? - .chain(std::fs::read_dir({ - let mut dir = dirs::data_dir().ok_or(Error::NoConfigDir)?; - dir.push("applications"); - dir - })?) - .filter_map(Result::ok) - .filter_map(|p| DesktopEntry::try_from(p.path()).ok()) + xdg::BaseDirectories::new()? + .list_data_files_once("applications") + .into_iter() + .filter_map(|p| DesktopEntry::try_from(p).ok()) .for_each(|e| { stdout.write_all(e.file_name.as_bytes()).unwrap(); stdout.write_all(b"\t").unwrap(); @@ -186,11 +178,11 @@ impl MimeApps { } #[derive(Debug)] -pub struct SystemApps(pub DashMap>); +pub struct SystemApps(pub HashMap>); impl SystemApps { pub fn get_handlers(&self, mime: &Mime) -> Option> { - Some(self.0.get(mime)?.value().clone()) + Some(self.0.get(mime)?.clone()) } pub fn get_handler(&self, mime: &Mime) -> Option { Some(self.get_handlers(mime)?.get(0).unwrap().clone()) @@ -198,20 +190,29 @@ impl SystemApps { pub fn populate() -> Result { use std::convert::TryFrom; - let map = DashMap::>::with_capacity(50); + let mut map = HashMap::>::with_capacity(50); - std::fs::read_dir("/usr/share/applications")? - .filter_map(|path| { - path.ok() - .map(|p| DesktopEntry::try_from(p.path()).ok()) - .flatten() + xdg::BaseDirectories::new()? + .get_data_dirs() + .into_iter() + .map(|mut data_dir| { + data_dir.push("applications"); + data_dir }) - .for_each(|entry| { - let (file_name, mimes) = (entry.file_name, entry.mimes); - mimes.into_iter().for_each(|mime| { - map.entry(mime) - .or_default() - .push(Handler::assume_valid(file_name.clone())); + .filter_map(|data_dir| std::fs::read_dir(data_dir).ok()) + .for_each(|dir| { + dir.filter_map(|path| { + path.ok() + .map(|p| DesktopEntry::try_from(p.path()).ok()) + .flatten() + }) + .for_each(|entry| { + let (file_name, mimes) = (entry.file_name, entry.mimes); + mimes.into_iter().for_each(|mime| { + map.entry(mime) + .or_default() + .push(Handler::assume_valid(file_name.clone())); + }); }); });