use std::fmt::Debug;
use std::io::Write;
use std::path::Path;
use qubit_local_files::{
FileWriteOptions,
LocalTempFile,
};
use crate::{
MimeDetectorCore,
MimeResult,
StreamBasedMimeDetector,
};
pub trait FileBasedMimeDetector: Debug + Send + Sync {
fn core(&self) -> &MimeDetectorCore;
fn max_test_bytes(&self) -> usize;
fn guess_from_filename(&self, filename: &str) -> Vec<String>;
fn guess_from_local_file(&self, file: &Path) -> MimeResult<Vec<String>>;
}
impl<T> StreamBasedMimeDetector for T
where
T: FileBasedMimeDetector,
{
fn core(&self) -> &MimeDetectorCore {
FileBasedMimeDetector::core(self)
}
fn max_test_bytes(&self) -> usize {
FileBasedMimeDetector::max_test_bytes(self)
}
fn guess_from_filename(&self, filename: &str) -> Vec<String> {
FileBasedMimeDetector::guess_from_filename(self, filename)
}
fn guess_from_content_bytes(
&self,
content: &[u8],
) -> MimeResult<Vec<String>> {
with_temp_file(content, |path| {
FileBasedMimeDetector::guess_from_local_file(self, path)
})
}
fn guess_from_file_stream(
&self,
file: &Path,
) -> MimeResult<(Vec<String>, Vec<u8>)> {
Ok((
FileBasedMimeDetector::guess_from_local_file(self, file)?,
Vec::new(),
))
}
}
pub(crate) fn with_temp_file<T>(
content: &[u8],
detect: impl FnOnce(&Path) -> MimeResult<T>,
) -> MimeResult<T> {
let mut file =
LocalTempFile::with_name(Some("MimeDetectorTemp-"), Some(".tmp"))?;
{
let handle = file.writer(FileWriteOptions::default().buffered())?;
handle.write_all(content)?;
}
file.close()?;
detect(file.path())
}