From 81347a765860850a5f407541670dfe6e8d79016d Mon Sep 17 00:00:00 2001 From: Lynne Date: Sat, 8 May 2021 00:32:44 +1000 Subject: [PATCH] mime_extension_lookup takes essence_str directly, videos aliases to video --- CHANGELOG.md | 2 ++ src/findings.rs | 2 +- src/inspectors.rs | 27 ++++++++++++--------------- src/main.rs | 2 +- src/parameters.rs | 1 + src/tests/mod.rs | 10 +++++----- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 345df22..99e8446 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Dates are given in YYYY-MM-DD format. ### v0.3.1 (2021-xx-yy) #### Features - Added JSON output support via `-o json` +#### Other +- `videos` is now an alias for `video` ### v0.3.0 (2021-04-28) #### Features diff --git a/src/findings.rs b/src/findings.rs index 6b1edc6..4c9d8f8 100644 --- a/src/findings.rs +++ b/src/findings.rs @@ -38,7 +38,7 @@ impl<'a> serde::Serialize for Findings<'a> { impl<'a> Findings<'a> { pub fn recommended_extension(&self) -> Option { - mime_extension_lookup(self.mime.clone()).map(|extensions| extensions[0].clone()) + mime_extension_lookup(self.mime.essence_str().into()).map(|extensions| extensions[0].clone()) } } diff --git a/src/inspectors.rs b/src/inspectors.rs index ecd4bb8..e061d6d 100644 --- a/src/inspectors.rs +++ b/src/inspectors.rs @@ -61,20 +61,17 @@ pub fn mime_type(db: &T, path: &Path) -> io::Result> { Ok(db.get_type(&buffer)) } -// TODO: avoid cloning mime if possible, although i don't really see how it would be - maybe instead of passing the mime -// object, pass a hash of it? - cached! { MIMEXT; - fn mime_extension_lookup(mime: Mime) -> Option> = { + fn mime_extension_lookup(essence: String) -> Option> = { // Returns a list of known extensions for this mime type, if any. - // ↑ this is supposed to be a doc comment, but the cached! macro doesn't support that... maybe i should switch to - // the derive macro + // This function uses the [Mime]'s "essence" rather than the [Mime] itself - mime_guess::get_mime_extensions ignores + // the type suffix, treating "image/svg+xml" as "image/svg", and thus fails to find any extensions. Passing the + // essence_str (which includes the suffix) fixes this. + // ↑ this is supposed to be a doc comment, but the cached! macro doesn't support that... i would switch to the + // proc_macro version of cached, but it has a huge number of deps :c - // match on the mime's `essence_str` rather than the mime itself - mime_guess::get_mime_extensions ignores the type - // suffix, treating "image/svg+xml" as "image/svg", and thus fails to find any extensions. passing the essence_str - // (which includes the suffix) fixes this. - let essence = mime.essence_str(); + let essence = essence.as_str(); let mut exts = mime_guess::get_mime_extensions_str(essence); if exts.is_none() { // no matches :c @@ -95,13 +92,13 @@ cached! { Some(exts) => { let possible_exts: Vec = exts.iter().map(|e| String::from(*e)).collect(); - Some(if mime == mime_guess::mime::IMAGE_JPEG { + Some(if essence == mime_guess::mime::IMAGE_JPEG.essence_str() { // possible_exts starts with "jpe", because it's alphabetically before "jpeg" and "jpg". however, jpg/jpeg are // far more common than jpe, so it makes sense to suggest one of those rather than jpe. to do this, we can // add "jpg" to the start of the possible_exts list, ensuring that it will be the extension suggested by fif. [vec![String::from("jpg")], possible_exts].concat() - } else if mime == mime_guess::mime::TEXT_XML || mime == Mime::from_str("application/xml").unwrap() { + } else if essence == mime_guess::mime::TEXT_XML.essence_str() || essence == "application/xml" { // a somewhat similar case arises with XML files - the first suggested extension is "asa", when it should // (in my opinion) be "xml". // there's also another problem: SVG files can easily be misidentified as XML files, because they usually @@ -114,15 +111,15 @@ cached! { // extension is classes as application/*+xml, consider it OK [vec![String::from("xml"), String::from("svg")], possible_exts].concat() - } else if mime == Mime::from_str("application/msword").unwrap() { + } else if essence == "application/msword" { // classic office files considered harmful vec![String::from("doc"), String::from("xls"), String::from("ppt")] - } else if mime == Mime::from_str("application/zip").unwrap() { + } else if essence == "application/zip" { // neither xdg-mime nor infer seem to be able to detect office XML files properly... [vec![String::from("zip"), String::from("docx"), String::from("xlsx"), String::from("pptx")], possible_exts].concat() - } else if mime == Mime::from_str("application/x-ms-dos-executable").unwrap() { + } else if essence == "application/x-ms-dos-executable" { // both .dll and .exe files are given the same mime type... but you definitely don't want to rename one to the // other! [vec![String::from("dll"), String::from("exe")], possible_exts].concat() diff --git a/src/main.rs b/src/main.rs index 3e2163e..7e9db6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -254,7 +254,7 @@ fn scan_file(entry: &DirEntry) -> Result { let result = result.unwrap(); // set of known extensions for the given mimetype - let known_exts = inspectors::mime_extension_lookup(result.clone()); + let known_exts = inspectors::mime_extension_lookup(result.essence_str().into()); // file extension for this particular file let entry_ext = extension_from_path(entry.path()); diff --git a/src/parameters.rs b/src/parameters.rs index 7c7ad2b..1bca720 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -234,6 +234,7 @@ pub enum ExtensionSet { /// Extensions used for audio file formats, such as `mp3`, `ogg`, `flac`, etc. Audio, /// Extensions used for video file formats, such as `mkv`, `mp4`, `mov`, etc. + #[clap(alias = "videos")] Video, /// Extensions used for media file formats. This acts as a combination of the [Images](ExtensionSet::Images), /// [Audio](ExtensionSet::Audio) and [Videos](ExtensionSet::Videos) variants. diff --git a/src/tests/mod.rs b/src/tests/mod.rs index dbd3300..989398f 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -67,14 +67,14 @@ fn detect_type() { /// Ensure that `mime_extension_lookup` works as expected, and that the set of extensions for JPEG, PNG, PDF, and ZIP /// contain "jpg", "png", "pdf", and "zip", respectively. fn recommend_ext() { - assert!(mime_extension_lookup(IMAGE_JPEG) + assert!(mime_extension_lookup(IMAGE_JPEG.essence_str().into()) .unwrap() .contains(&String::from("jpg"))); - assert!(mime_extension_lookup(IMAGE_PNG).unwrap().contains(&String::from("png"))); - assert!(mime_extension_lookup(APPLICATION_PDF) + assert!(mime_extension_lookup(IMAGE_PNG.essence_str().into()).unwrap().contains(&String::from("png"))); + assert!(mime_extension_lookup(APPLICATION_PDF.essence_str().into()) .unwrap() .contains(&String::from("pdf"))); - assert!(mime_extension_lookup(application_zip()) + assert!(mime_extension_lookup(application_zip().essence_str().into()) .unwrap() .contains(&String::from("zip"))); } @@ -142,7 +142,7 @@ fn simple_directory() { // check if the recommended extension for this file is in the list of known extensions for its mimetype - for // example, if the file is determined to be an IMAGE_PNG, its recommended extension should be one of the extensions // returned by `mime_extension_lookup(IMAGE_PNG)`. - assert!(mime_extension_lookup(result.mime.clone()) + assert!(mime_extension_lookup(result.mime.essence_str().into()) .unwrap() .contains(&result.recommended_extension().unwrap()));