diff --git a/src/common/mime_types.rs b/src/common/mime_types.rs index 991ea1a..d4b6427 100644 --- a/src/common/mime_types.rs +++ b/src/common/mime_types.rs @@ -32,7 +32,7 @@ impl TryFrom<&Path> for MimeType { fn try_from(path: &Path) -> Result { match MimeDetective::new()?.detect_filepath(path)? { guess if guess == mime::APPLICATION_OCTET_STREAM => { - Err(Error::Ambiguous(path.to_string_lossy().into())) + Err(Error::Ambiguous(path.to_owned())) } guess => Ok(Self(guess)), } @@ -42,14 +42,20 @@ impl TryFrom<&Path> for MimeType { // Mime derived from user input: extension(.pdf) or type like image/jpg #[derive(Debug)] pub struct MimeOrExtension(pub Mime); + impl FromStr for MimeOrExtension { type Err = Error; fn from_str(s: &str) -> Result { - if s.starts_with(".") { - Ok(Self(MimeType::try_from(s)?.0)) + let mime = if s.starts_with(".") { + mime_db::lookup(&s[1..]) + .ok_or(Error::Ambiguous(s.into()))? + .parse::() + .unwrap() } else { - Ok(Self(Mime::from_str(s)?)) - } + Mime::from_str(s)? + }; + + Ok(Self(mime)) } } @@ -58,22 +64,25 @@ mod tests { use super::*; #[test] - fn user_input() { - "image/jpg".parse::().unwrap(); - ".jpg".parse::().unwrap(); + fn user_input() -> Result<()> { + assert_eq!(MimeOrExtension::from_str(".pdf")?.0, mime::APPLICATION_PDF); + assert_eq!( + MimeOrExtension::from_str("image/jpeg")?.0, + mime::IMAGE_JPEG + ); + "image//jpg".parse::().unwrap_err(); "image".parse::().unwrap_err(); + + Ok(()) } #[test] - fn from_path_with_extension() { - assert_eq!( - MimeType::try_from(".pdf").unwrap().0, - mime::APPLICATION_PDF - ); - assert_eq!( - MimeType::try_from(".").unwrap().0.essence_str(), - "inode/directory" - ); + fn from_path() -> Result<()> { + assert_eq!(MimeType::try_from(".")?.0.essence_str(), "inode/directory"); + assert_eq!(MimeType::try_from("./tests/cat")?.0.type_(), "text"); + assert_eq!(MimeType::try_from("./tests/rust.vim")?.0.type_(), "text"); + + Ok(()) } } diff --git a/src/error.rs b/src/error.rs index 1f8b14b..8d37679 100644 --- a/src/error.rs +++ b/src/error.rs @@ -10,10 +10,10 @@ pub enum Error { Xdg(#[from] xdg::BaseDirectoriesError), #[error(transparent)] Config(#[from] confy::ConfyError), - #[error("no handler defined for {0}")] + #[error("no handlers found for '{0}'")] NotFound(String), - #[error("could not figure out the mime type {0}")] - Ambiguous(String), + #[error("could not figure out the mime type of '{0}'")] + Ambiguous(std::path::PathBuf), #[error(transparent)] BadMimeType(#[from] mime::FromStrError), #[error("malformed desktop entry at {0}")] diff --git a/tests/cat b/tests/cat new file mode 100755 index 0000000..16586b7 --- /dev/null +++ b/tests/cat @@ -0,0 +1,2 @@ +#!/bin/sh +bat "$@" diff --git a/tests/rust.vim b/tests/rust.vim new file mode 100644 index 0000000..16586b7 --- /dev/null +++ b/tests/rust.vim @@ -0,0 +1,2 @@ +#!/bin/sh +bat "$@"