Skip to content

Commit 6c50b90

Browse files
committed
Fix loading files from $XDG_DATA_HOME
Closes #11.
1 parent f7a9ebf commit 6c50b90

File tree

4 files changed

+118
-88
lines changed

4 files changed

+118
-88
lines changed

Cargo.lock

+76
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ exclude = ["tests/*", "benches/*/"]
1616
edition = "2021"
1717

1818
[dependencies]
19+
home = "0.5.0"
1920
petgraph = "0.6.0"
2021
nom = "7.0"
2122
fnv = "1.0"
22-
memchr = "2.7"
23+
memchr = "2.0"
2324
once_cell = "1.0"
2425
tree_magic_db = { version = "3.0", path = "./magic_db" , optional = true }
2526

src/fdo_magic/builtin/mod.rs

+8-20
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,19 @@ use fnv::FnvHashMap;
66
use once_cell::sync::Lazy;
77
use petgraph::prelude::*;
88

9-
/// Preload alias list
10-
static ALIASES: Lazy<FnvHashMap<Mime, Mime>> = Lazy::new(init::get_aliaslist);
11-
12-
/// Load magic file before anything else.
13-
static ALL_RULES: Lazy<FnvHashMap<Mime, DiGraph<MagicRule<'static>, u32>>> = Lazy::new(rules);
14-
159
pub mod check;
1610
pub mod init;
1711

1812
#[cfg(not(feature = "with-gpl-data"))]
1913
mod runtime;
2014

21-
fn rules() -> FnvHashMap<Mime, DiGraph<MagicRule<'static>, u32>> {
15+
/// Preload alias list
16+
static ALIASES: Lazy<FnvHashMap<Mime, Mime>> = Lazy::new(init::get_aliaslist);
17+
18+
/// Load magic file before anything else.
19+
static ALL_RULES: Lazy<FnvHashMap<Mime, DiGraph<MagicRule<'static>, u32>>> = Lazy::new(|| {
2220
#[cfg(feature = "with-gpl-data")]
23-
return static_rules();
21+
return super::ruleset::from_u8(tree_magic_db::magic()).unwrap_or_default();
2422
#[cfg(not(feature = "with-gpl-data"))]
25-
return runtime_rules();
26-
}
27-
28-
#[cfg(feature = "with-gpl-data")]
29-
fn static_rules() -> FnvHashMap<Mime, DiGraph<MagicRule<'static>, u32>> {
30-
super::ruleset::from_u8(tree_magic_db::magic()).unwrap_or_default()
31-
}
32-
33-
#[cfg(not(feature = "with-gpl-data"))]
34-
fn runtime_rules() -> FnvHashMap<Mime, DiGraph<MagicRule<'static>, u32>> {
35-
runtime::rules().unwrap_or_default()
36-
}
23+
return runtime::rules().unwrap_or_default();
24+
});

src/fdo_magic/builtin/runtime.rs

+32-67
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Enable loading the magic database files at runtime rather than embedding the GPLed database
22
3-
use std::fs::File;
4-
use std::io::Read;
3+
use std::fs::{read, read_to_string};
4+
use std::path::PathBuf;
55

66
use fnv::FnvHashMap;
77
use once_cell::sync::OnceCell;
@@ -11,83 +11,48 @@ use super::MagicRule;
1111
use crate::fdo_magic::ruleset;
1212
use crate::Mime;
1313

14-
static RUNTIME_RULES: OnceCell<Vec<Vec<u8>>> = OnceCell::new();
15-
static ALIAS_STRING: OnceCell<String> = OnceCell::new();
16-
static SUBCLASS_STRING: OnceCell<String> = OnceCell::new();
17-
18-
/// Load the magic database from the predefined locations in the XDG standard
19-
fn load_xdg_shared_magic() -> Result<Vec<Vec<u8>>, String> {
20-
const SEARCH_PATHS: &[&str; 3] = &[
21-
"/usr/share/mime/magic",
22-
"/usr/local/share/mime/magic",
23-
"$HOME/.local/share/mime/magic",
14+
fn search_paths(filename: &str) -> Vec<PathBuf> {
15+
let mut search_paths = vec![
16+
PathBuf::from("/usr/share/mime").join(filename),
17+
PathBuf::from("/usr/local/share/mime").join(filename),
2418
];
25-
26-
let files: Vec<Vec<u8>> = SEARCH_PATHS
27-
.iter()
28-
.filter_map(|p| File::open(p).ok())
29-
.map(|mut f| {
30-
let mut buf = vec![];
31-
f.read_to_end(&mut buf)
32-
.map_err(|e| format!("Failed to read magic file bytes: {:#?}", e))?;
33-
Ok(buf)
34-
})
35-
.collect::<Result<_, String>>()?;
36-
37-
if files.is_empty() {
38-
Err("No MIME magic files found in the XDG default paths".to_string())
39-
} else {
40-
Ok(files)
19+
if let Some(home) = home::home_dir() {
20+
search_paths.push(home.join(".local/share/mime").join(filename));
4121
}
22+
dbg!(search_paths)
4223
}
4324

44-
/// Load a number of files at `paths` and concatenate them together with a newline
45-
fn load_concat_strings(paths: &[&str]) -> String {
46-
let strings: Vec<String> = paths
25+
/// Load the magic database from the predefined locations in the XDG standard
26+
fn load_xdg_shared_magic() -> Vec<Vec<u8>> {
27+
search_paths("magic")
4728
.iter()
48-
.filter_map(|p| File::open(p).ok())
49-
.map(|mut f| {
50-
let mut s = String::new();
51-
f.read_to_string(&mut s)
52-
.expect("Failed to read aliases from file");
53-
s
54-
})
55-
.collect();
56-
57-
strings.join("\n")
29+
.map(read)
30+
.filter_map(Result::ok)
31+
.collect()
5832
}
5933

60-
/// Load the magic aliases from the XDG standard locations and concatenate them together
61-
fn load_aliases() -> String {
62-
const SEARCH_PATHS: &[&str; 3] = &[
63-
"/usr/share/mime/aliases",
64-
"/usr/local/share/mime/aliases",
65-
"$HOME/.local/share/mime/aliases",
66-
];
67-
68-
load_concat_strings(SEARCH_PATHS)
69-
}
70-
71-
/// Load the subclass definitions from the XDG standard locations and concatenate them together
72-
fn load_subclasses() -> String {
73-
const SEARCH_PATHS: &[&str; 3] = &[
74-
"/usr/share/mime/subclasses",
75-
"/usr/local/share/mime/subclasses",
76-
"$HOME/.local/share/mime/subclasses",
77-
];
78-
79-
load_concat_strings(SEARCH_PATHS)
34+
/// Load a number of files at `paths` and concatenate them together with a newline
35+
fn load_concat_strings(filename: &str) -> String {
36+
search_paths(filename)
37+
.iter()
38+
.map(read_to_string)
39+
.filter_map(Result::ok)
40+
.collect::<Vec<_>>()
41+
.join("\n")
8042
}
8143

82-
pub(crate) fn aliases() -> &'static str {
83-
ALIAS_STRING.get_or_init(load_aliases)
44+
pub fn aliases() -> &'static str {
45+
static ALIAS_STRING: OnceCell<String> = OnceCell::new();
46+
ALIAS_STRING.get_or_init(|| load_concat_strings("aliases"))
8447
}
8548

86-
pub(crate) fn subclasses() -> &'static str {
87-
SUBCLASS_STRING.get_or_init(load_subclasses)
49+
pub fn subclasses() -> &'static str {
50+
static SUBCLASS_STRING: OnceCell<String> = OnceCell::new();
51+
SUBCLASS_STRING.get_or_init(|| load_concat_strings("subclasses"))
8852
}
8953

90-
pub(crate) fn rules() -> Result<FnvHashMap<Mime, DiGraph<MagicRule<'static>, u32>>, String> {
91-
let files = RUNTIME_RULES.get_or_try_init(load_xdg_shared_magic)?;
54+
pub fn rules() -> Result<FnvHashMap<Mime, DiGraph<MagicRule<'static>, u32>>, String> {
55+
static RUNTIME_RULES: OnceCell<Vec<Vec<u8>>> = OnceCell::new();
56+
let files = RUNTIME_RULES.get_or_init(load_xdg_shared_magic);
9257
ruleset::from_multiple(files)
9358
}

0 commit comments

Comments
 (0)