use std::path::PathBuf; use std::time::Duration; use anyhow::Result; use indicatif::{ProgressBar, ProgressStyle}; use rayon::prelude::*; use crate::formats::{get_reader, get_writer, FormatId}; #[derive(Debug, Clone)] pub struct Job { pub from: FormatId, pub to: FormatId, pub input_path: PathBuf, pub output_path: PathBuf, } impl Job { pub fn new(input_path: PathBuf, output_dir: PathBuf, from: FormatId, to: FormatId) -> Self { let mut output_path = output_dir.join(input_path.file_name().unwrap()); match to { FormatId::Pdf => output_path.set_extension("pdf"), FormatId::Cbz => output_path.set_extension("cbz"), FormatId::Cbr => output_path.set_extension("cbr"), }; Self { from, to, input_path, output_path, } } } pub fn process_jobs(jobs: Vec) -> Result<()> { let pb = ProgressBar::new(jobs.len() as u64); pb.enable_steady_tick(Duration::from_millis(300)); pb.set_style(ProgressStyle::with_template( "[{elapsed_precise}] {wide_bar} {pos:>7}/{len:7} {msg}", )?); jobs.par_iter().for_each(|job| { // Build the pipeline for each job let reader = get_reader(job.from).expect("No reader registered for selected input format"); let writer = get_writer(job.to).expect("No writer registered for selected output format"); let doc = reader.read(&job.input_path).expect("Failed to read input"); writer .write(&doc, &job.output_path) .expect("Failed to write output"); pb.inc(1); }); pb.finish(); Ok(()) }