2022-10-07 13:51:38 +00:00
|
|
|
use std::{
|
|
|
|
collections::{HashMap, VecDeque},
|
|
|
|
str::FromStr,
|
|
|
|
};
|
2022-10-07 10:18:23 +00:00
|
|
|
|
|
|
|
use lazy_static::lazy_static;
|
|
|
|
use mime::Mime;
|
|
|
|
|
|
|
|
lazy_static! {
|
2022-10-07 13:51:38 +00:00
|
|
|
static ref ALIASES: HashMap<Mime, Mime> = load_mime_aliases();
|
|
|
|
static ref PARENTS: Vec<(Mime, Mime)> = load_mime_parent_relations();
|
|
|
|
static ref EXTENSIONS: HashMap<Mime, &'static str> = load_mime_extensions();
|
2022-10-07 10:18:23 +00:00
|
|
|
}
|
|
|
|
|
2022-10-07 13:51:38 +00:00
|
|
|
fn load_mime_aliases() -> HashMap<Mime, Mime> {
|
2022-10-07 10:18:23 +00:00
|
|
|
tree_magic_db::aliases()
|
|
|
|
.lines()
|
2022-11-04 10:37:10 +00:00
|
|
|
.filter_map(|line| line.split_once(' '))
|
|
|
|
.filter_map(|(alias, mime)| Some((Mime::from_str(alias).ok()?, Mime::from_str(mime).ok()?)))
|
2022-10-07 10:18:23 +00:00
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
2022-10-07 13:51:38 +00:00
|
|
|
fn load_mime_parent_relations() -> Vec<(Mime, Mime)> {
|
2022-10-07 10:18:23 +00:00
|
|
|
tree_magic_db::subclasses()
|
|
|
|
.lines()
|
2022-11-04 10:37:10 +00:00
|
|
|
.filter_map(|line| line.split_once(' '))
|
|
|
|
.filter_map(|(child, parent)| {
|
2022-10-07 10:18:23 +00:00
|
|
|
Some((Mime::from_str(child).ok()?, Mime::from_str(parent).ok()?))
|
|
|
|
})
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
2022-10-07 13:51:38 +00:00
|
|
|
fn load_mime_extensions() -> HashMap<Mime, &'static str> {
|
|
|
|
include_str!("../mime.types")
|
|
|
|
.lines()
|
|
|
|
.filter(|line| !line.is_empty() && !line.starts_with('#'))
|
2022-11-04 10:37:10 +00:00
|
|
|
.map(str::split_whitespace)
|
|
|
|
.filter_map(|mut elements| Some((Mime::from_str(elements.next()?).ok()?, elements.next()?)))
|
|
|
|
.map(|(mime, extension)| (ALIASES.get(&mime).cloned().unwrap_or(mime), extension))
|
2022-10-07 13:51:38 +00:00
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn get_alias(mimetype: Mime) -> Mime {
|
|
|
|
ALIASES.get(&mimetype).cloned().unwrap_or(mimetype)
|
|
|
|
}
|
|
|
|
|
2022-10-07 10:18:23 +00:00
|
|
|
fn get_mime_parents(mimetype: &Mime) -> Vec<&Mime> {
|
|
|
|
PARENTS
|
|
|
|
.iter()
|
|
|
|
.filter_map(|(child, parent)| (child == mimetype).then_some(parent))
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn matches_text(mime: &Mime) -> bool {
|
|
|
|
if mime.type_() == mime::TEXT {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return get_mime_parents(mime).into_iter().any(matches_text);
|
|
|
|
}
|
2022-10-07 13:51:38 +00:00
|
|
|
|
|
|
|
pub(crate) fn get_extension(mimetype: &Mime) -> Option<&'static str> {
|
|
|
|
let mut queue = VecDeque::new();
|
|
|
|
queue.push_back(mimetype);
|
|
|
|
while let Some(mime) = queue.pop_front() {
|
|
|
|
match EXTENSIONS.get(mimetype).copied() {
|
|
|
|
Some(ext) => return Some(ext),
|
|
|
|
None => queue.extend(get_mime_parents(mime)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|