use std::fmt::Debug;
use std::fs::File;
use std::io::SeekFrom;
use std::path::Path;
use qubit_io::ReadSeek;
use crate::{
MimeDetectorCore,
MimeResult,
};
pub trait StreamBasedMimeDetector: 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_content_bytes(&self, content: &[u8]) -> MimeResult<Vec<String>>;
fn guess_from_reader_stream(
&self,
reader: &mut dyn ReadSeek,
) -> MimeResult<(Vec<String>, Vec<u8>)> {
let content = read_prefix(reader, self.max_test_bytes())?;
let candidates = self.guess_from_content_bytes(&content)?;
Ok((candidates, content))
}
fn guess_from_file_stream(&self, file: &Path) -> MimeResult<(Vec<String>, Vec<u8>)> {
let mut reader = File::open(file)?;
self.guess_from_reader_stream(&mut reader)
}
}
pub(crate) fn read_prefix(reader: &mut dyn ReadSeek, max_bytes: usize) -> MimeResult<Vec<u8>> {
let position = reader.stream_position()?;
let mut buffer = vec![0; max_bytes];
let bytes_read = reader.read(&mut buffer)?;
buffer.truncate(bytes_read);
reader.seek(SeekFrom::Start(position))?;
Ok(buffer)
}