Implement XDG_DATA_DIRS support | #3

This commit is contained in:
Gregory 2020-05-18 20:04:48 -04:00
parent 22e0d2e4e8
commit 4561ad5dab
No known key found for this signature in database
GPG key ID: 2E44FAEEDC94B1E2
5 changed files with 43 additions and 176 deletions

140
Cargo.lock generated
View file

@ -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"

View file

@ -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

View file

@ -68,18 +68,9 @@ impl Handler {
Self(name)
}
pub fn get_path(name: &str) -> Option<PathBuf> {
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<Self> {
let path = Self::get_path(&name).ok_or(Error::NotFound)?;

View file

@ -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<T, E = Error> = std::result::Result<T, E>;

View file

@ -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<PathBuf> {
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<Self> {
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<Mime, Vec<Handler>>);
pub struct SystemApps(pub HashMap<Mime, Vec<Handler>>);
impl SystemApps {
pub fn get_handlers(&self, mime: &Mime) -> Option<Vec<Handler>> {
Some(self.0.get(mime)?.value().clone())
Some(self.0.get(mime)?.clone())
}
pub fn get_handler(&self, mime: &Mime) -> Option<Handler> {
Some(self.get_handlers(mime)?.get(0).unwrap().clone())
@ -198,20 +190,29 @@ impl SystemApps {
pub fn populate() -> Result<Self> {
use std::convert::TryFrom;
let map = DashMap::<Mime, Vec<Handler>>::with_capacity(50);
let mut map = HashMap::<Mime, Vec<Handler>>::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()));
});
});
});