use std::ffi::OsStr; use std::path::Path; use anyhow::Result; use crate::model::Document; pub mod cbz; pub mod pdf; use cbz::{CbzReader, CbzWriter}; use pdf::{PdfReader, PdfWriter}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum FormatId { Cbz, Pdf, } impl FormatId { #[allow(dead_code)] pub fn can_read(self) -> bool { get_reader(self).is_some() } #[allow(dead_code)] pub fn can_write(self) -> bool { get_writer(self).is_some() } pub fn detect_from_path(path: &Path) -> Option { match path.extension().and_then(OsStr::to_str) { Some("cbz") => Some(FormatId::Cbz), Some("pdf") => Some(FormatId::Pdf), _ => None, } } } pub trait FormatReader: Send + Sync { fn read(&self, input: &Path) -> Result; } pub trait FormatWriter: Send + Sync { fn write(&self, doc: &Document, output: &Path) -> Result<()>; } pub fn get_reader(format: FormatId) -> Option> { match format { FormatId::Cbz => Some(Box::new(CbzReader)), FormatId::Pdf => Some(Box::new(PdfReader)), } } pub fn get_writer(format: FormatId) -> Option> { match format { FormatId::Pdf => Some(Box::new(PdfWriter)), FormatId::Cbz => Some(Box::new(CbzWriter)), } }