use std::io::{self, BufRead, Read, Seek};
use crate::discovery::{BdFileKind, BdmvDir};
pub mod fs;
pub mod udf;
pub trait ReadSeek: Read + Seek {}
impl<T: Read + Seek> ReadSeek for T {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SearchOption {
TopDirectoryOnly,
AllDirectories,
}
pub trait BdFile: Send {
fn name(&self) -> &str;
fn full_name(&self) -> &str;
fn extension(&self) -> &str;
fn length(&self) -> u64;
fn is_dir(&self) -> bool;
fn open_read(&self) -> io::Result<Box<dyn ReadSeek>>;
fn open_text(&self) -> io::Result<Box<dyn BufRead>>;
}
pub trait BdDir {
fn name(&self) -> &str;
fn full_name(&self) -> &str;
fn parent(&self) -> Option<Box<dyn BdDir>>;
fn get_files(&self) -> io::Result<Vec<Box<dyn BdFile>>>;
fn get_files_pattern(&self, pattern: &str) -> io::Result<Vec<Box<dyn BdFile>>>;
fn get_files_pattern_option(
&self,
pattern: &str,
option: SearchOption,
) -> io::Result<Vec<Box<dyn BdFile>>>;
fn get_directories(&self) -> io::Result<Vec<Box<dyn BdDir>>>;
}
pub fn find_directory(dir: &dyn BdDir, which: BdmvDir) -> io::Result<Option<Box<dyn BdDir>>> {
for child in dir.get_directories()? {
if BdmvDir::from_name(child.name()) == Some(which) {
return Ok(Some(child));
}
}
Ok(None)
}
pub fn find_files(dir: &dyn BdDir, kind: BdFileKind) -> io::Result<Vec<Box<dyn BdFile>>> {
let mut out: Vec<Box<dyn BdFile>> = Vec::new();
for file in dir.get_files()? {
if BdFileKind::from_filename(file.name()) == Some(kind) {
out.push(file);
}
}
Ok(out)
}
#[cfg(test)]
mod tests {
use super::SearchOption;
#[test]
fn search_option_is_debug_and_eq() {
assert_eq!(format!("{:?}", SearchOption::AllDirectories), "AllDirectories");
assert_eq!(SearchOption::TopDirectoryOnly, SearchOption::TopDirectoryOnly);
assert_ne!(SearchOption::TopDirectoryOnly, SearchOption::AllDirectories);
}
}