Overhaul extension => mime retrieval | #9

This commit is contained in:
Gregory 2020-06-20 21:23:08 -04:00
parent a5185ae2ae
commit 2d1974c5bb
No known key found for this signature in database
GPG key ID: 2E44FAEEDC94B1E2
2 changed files with 31 additions and 5 deletions

View file

@ -10,6 +10,20 @@ use std::{
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct MimeType(pub Mime); pub struct MimeType(pub Mime);
impl MimeType {
fn from_ext(ext: &str) -> Result<Mime> {
match &*xdg_mime::SharedMimeInfo::new()
.get_mime_types_from_file_name(ext)
{
[m] if m == &mime::APPLICATION_OCTET_STREAM => {
Err(Error::Ambiguous(ext.into()))
}
[] => unreachable!(),
[guess, ..] => Ok(guess.clone()),
}
}
}
impl TryFrom<&str> for MimeType { impl TryFrom<&str> for MimeType {
type Error = Error; type Error = Error;
@ -51,12 +65,12 @@ impl FromStr for MimeOrExtension {
type Err = Error; type Err = Error;
fn from_str(s: &str) -> Result<Self> { fn from_str(s: &str) -> Result<Self> {
let mime = if s.starts_with(".") { let mime = if s.starts_with(".") {
mime_db::lookup(&s[1..]) MimeType::from_ext(s)?
.ok_or(Error::Ambiguous(s.into()))?
.parse::<Mime>()
.unwrap()
} else { } else {
Mime::from_str(s)? match Mime::from_str(s)? {
m if m.subtype() == "" => return Err(Error::InvalidMime(m)),
proper_mime => proper_mime,
}
}; };
Ok(Self(mime)) Ok(Self(mime))
@ -92,4 +106,14 @@ mod tests {
Ok(()) Ok(())
} }
#[test]
fn from_ext() -> Result<()> {
assert_eq!(".mp3".parse::<MimeOrExtension>()?.0, "audio/mpeg");
assert_eq!("audio/mpeg".parse::<MimeOrExtension>()?.0, "audio/mpeg");
".".parse::<MimeOrExtension>().unwrap_err();
"audio/".parse::<MimeOrExtension>().unwrap_err();
Ok(())
}
} }

View file

@ -14,6 +14,8 @@ pub enum Error {
Ambiguous(std::path::PathBuf), Ambiguous(std::path::PathBuf),
#[error(transparent)] #[error(transparent)]
BadMimeType(#[from] mime::FromStrError), BadMimeType(#[from] mime::FromStrError),
#[error("bad mime: {0}")]
InvalidMime(mime::Mime),
#[error("malformed desktop entry at {0}")] #[error("malformed desktop entry at {0}")]
BadEntry(std::path::PathBuf), BadEntry(std::path::PathBuf),
#[error("error spawning selector process '{0}'")] #[error("error spawning selector process '{0}'")]