more reliable matching using libmagic

This commit is contained in:
Gregory 2020-06-12 01:20:31 -04:00
parent 5c49436b62
commit 4f2940135e
No known key found for this signature in database
GPG key ID: 2E44FAEEDC94B1E2
6 changed files with 56 additions and 153 deletions

154
Cargo.lock generated
View file

@ -6,15 +6,6 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
dependencies = [
"nodrop",
]
[[package]]
name = "arrayvec"
version = "0.5.1"
@ -56,6 +47,12 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
[[package]]
name = "bitflags"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
[[package]]
name = "bitflags"
version = "1.2.1"
@ -69,7 +66,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
dependencies = [
"arrayref",
"arrayvec 0.5.1",
"arrayvec",
"constant_time_eq",
]
@ -137,7 +134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "860643c53f980f0d38a5e25dfab6c3c93b2cb3aa1fe192643d17a293c6c41936"
dependencies = [
"atty",
"bitflags",
"bitflags 1.2.1",
"clap_derive",
"indexmap",
"lazy_static",
@ -225,16 +222,6 @@ dependencies = [
"dirs-sys",
]
[[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.5"
@ -300,7 +287,7 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
dependencies = [
"bitflags",
"bitflags 1.2.1",
"fuchsia-zircon-sys",
]
@ -369,12 +356,6 @@ dependencies = [
"wasi",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "h2"
version = "0.2.5"
@ -406,7 +387,7 @@ dependencies = [
"json",
"mime",
"mime-db",
"once_cell",
"mime-detective",
"pest",
"pest_derive",
"regex",
@ -415,7 +396,6 @@ dependencies = [
"thiserror",
"url",
"xdg",
"xdg-mime",
]
[[package]]
@ -575,20 +555,6 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lexical-core"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f86d66d380c9c5a685aaac7a11818bdfa1f733198dfd9ec09c70b762cd12ad6f"
dependencies = [
"arrayvec 0.4.12",
"bitflags",
"cfg-if",
"rustc_version",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.71"
@ -604,6 +570,26 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "magic"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96f74caec41a12630bb8fd9546530a41addb720eb0c10593855f59ce96a779aa"
dependencies = [
"bitflags 0.7.0",
"libc",
"magic-sys",
]
[[package]]
name = "magic-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17442cc60e34d501588c95bc976da04b6a87c51ab02370e95e1c2893a52df16c"
dependencies = [
"libc",
]
[[package]]
name = "maplit"
version = "1.0.2"
@ -640,6 +626,16 @@ dependencies = [
"tokio",
]
[[package]]
name = "mime-detective"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "691f45910296797c90bd9f536428635cf813a59073a3a5af93e208c428c9b4e9"
dependencies = [
"magic",
"mime",
]
[[package]]
name = "mime_guess"
version = "2.0.3"
@ -710,23 +706,6 @@ dependencies = [
"winapi 0.3.8",
]
[[package]]
name = "nodrop"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
name = "nom"
version = "5.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
dependencies = [
"lexical-core",
"memchr",
"version_check",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
@ -737,12 +716,6 @@ dependencies = [
"libc",
]
[[package]]
name = "once_cell"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
[[package]]
name = "opaque-debug"
version = "0.2.3"
@ -755,7 +728,7 @@ version = "0.10.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd"
dependencies = [
"bitflags",
"bitflags 1.2.1",
"cfg-if",
"foreign-types",
"lazy_static",
@ -1054,15 +1027,6 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.5"
@ -1085,7 +1049,7 @@ version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
dependencies = [
"bitflags",
"bitflags 1.2.1",
"core-foundation",
"core-foundation-sys",
"libc",
@ -1102,21 +1066,6 @@ dependencies = [
"libc",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.111"
@ -1202,12 +1151,6 @@ dependencies = [
"winapi 0.3.8",
]
[[package]]
name = "static_assertions"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
[[package]]
name = "strsim"
version = "0.10.0"
@ -1620,16 +1563,3 @@ name = "xdg"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
[[package]]
name = "xdg-mime"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "362780d5ed4fcb81db6460966be8cd691e48419caa84bb8a81063d2abdab7082"
dependencies = [
"dirs",
"glob",
"mime",
"nom",
"unicase",
]

View file

@ -18,13 +18,12 @@ thiserror = "1.0.19"
ascii_table = "3.0.1"
xdg = "2.2.0"
mime = "0.3.16"
once_cell = "1.4.0"
regex = { version = "1.3.9", default-features = false, features = ["std"] }
mime-db = "0.1.5"
atty = "0.2.14"
confy = "0.4.0"
serde = "1.0.111"
xdg-mime = "0.3.0"
mime-detective = "1.0.0"
[profile.release]
opt-level=3

View file

@ -1,9 +1,4 @@
use crate::Result;
use once_cell::sync::Lazy;
use xdg_mime::SharedMimeInfo;
pub static SHARED_MIME_DB: Lazy<SharedMimeInfo> =
Lazy::new(SharedMimeInfo::new);
static CUSTOM_MIMES: &[&'static str] = &[
"inode/directory",

View file

@ -1,5 +1,6 @@
use crate::{common::SHARED_MIME_DB, Error, Result};
use crate::{Error, Result};
use mime::Mime;
use mime_detective::MimeDetective;
use std::{
convert::TryFrom,
path::{Path, PathBuf},
@ -26,38 +27,14 @@ impl TryFrom<&str> for MimeType {
}
}
fn read_mb(path: &Path) -> Result<(std::fs::Metadata, Vec<u8>)> {
let metadata = std::fs::metadata(path)?;
let data = if metadata.len() <= 1024 {
std::fs::read(path)?
} else {
use std::io::prelude::*;
let mut buffer = Vec::with_capacity(1024);
let reader = std::io::BufReader::new(std::fs::File::open(path)?);
reader.take(1024).read_exact(&mut buffer)?;
buffer
};
Ok((metadata, data))
}
impl TryFrom<&Path> for MimeType {
type Error = Error;
fn try_from(path: &Path) -> Result<Self> {
let file_name = path.file_name().unwrap_or_default().to_string_lossy();
match &*SHARED_MIME_DB.get_mime_types_from_file_name(&file_name) {
[t, ..] if t == &mime::APPLICATION_OCTET_STREAM => Ok(Self({
let (meta, data) = read_mb(path)?;
SHARED_MIME_DB
.guess_mime_type()
.metadata(meta)
.data(&data)
.guess()
.mime_type()
.clone()
})),
[other, ..] => Ok(Self(other.clone())),
_ => Err(Error::Ambiguous(path.to_string_lossy().into())),
match MimeDetective::new()?.detect_filepath(path)? {
guess if guess == mime::APPLICATION_OCTET_STREAM => {
Err(Error::Ambiguous(path.to_string_lossy().into()))
}
guess => Ok(Self(guess)),
}
}
}

View file

@ -3,7 +3,7 @@ mod desktop_entry;
mod handler;
mod mime_types;
pub use self::db::{autocomplete as db_autocomplete, SHARED_MIME_DB};
pub use self::db::autocomplete as db_autocomplete;
pub use desktop_entry::{DesktopEntry, Mode as ExecMode, Rule as EntryRule};
pub use handler::Handler;
pub use mime_types::{MimeOrExtension, MimeType};

View file

@ -10,14 +10,16 @@ pub enum Error {
Xdg(#[from] xdg::BaseDirectoriesError),
#[error(transparent)]
Config(#[from] confy::ConfyError),
#[error("no handler defined for .{0}")]
#[error("no handler defined for {0}")]
NotFound(String),
#[error("could not figure out the mime type .{0}")]
#[error("could not figure out the mime type {0}")]
Ambiguous(String),
#[error(transparent)]
BadMimeType(#[from] mime::FromStrError),
#[error("malformed desktop entry at .{0}")]
#[error("malformed desktop entry at {0}")]
BadEntry(std::path::PathBuf),
#[error(transparent)]
MimeDetect(#[from] mime_detective::DetectiveError),
}
pub type Result<T, E = Error> = std::result::Result<T, E>;