use crate::plugin::Plugin; use std::time::Instant; pub fn run_conversion( path: &[(&dyn Plugin, &str, &str)], input: &[u8], verbosity: u8, ) -> Result, String> { if verbosity >= 1 { let path_str: Vec<_> = path.iter().map(|(p, _, _)| p.name()).collect(); eprintln!("Path taken: {}", path_str.join(" -> ")); } let mut current_data = input.to_vec(); for (plugin, from_format, to_format) in path { if verbosity >= 2 { eprintln!("Converting {} to {} using plugin {}...", from_format, to_format, plugin.name()); } if verbosity >= 4 { eprintln!("[Plugin Log] Running plugin: {}", plugin.name()); eprintln!("[Plugin Log] Source format: {}", from_format); eprintln!("[Plugin Log] Target format: {}", to_format); eprintln!("[Plugin Log] Metrics - Familiarity: {}, Quality: {}, Speed: {}", plugin.familiarity(), plugin.quality(), plugin.speed()); } let start_time = Instant::now(); current_data = plugin.convert(¤t_data, from_format, to_format)?; let elapsed = start_time.elapsed(); if verbosity >= 3 { eprintln!("Step '{} -> {}' completed in {:.2?}", from_format, to_format, elapsed); } } Ok(current_data) } #[cfg(test)] mod tests { use super::*; struct MockPlugin { name: &'static str, f: u8, q: u8, s: u8, fail: bool, } impl Plugin for MockPlugin { fn name(&self) -> &'static str { self.name } fn from_formats(&self) -> Vec<&'static str> { vec!["a"] } fn to_formats(&self) -> Vec<&'static str> { vec!["b"] } fn familiarity(&self) -> u8 { self.f } fn quality(&self) -> u8 { self.q } fn speed(&self) -> u8 { self.s } fn convert(&self, input: &[u8], _from: &str, _to: &str) -> Result, String> { if self.fail { return Err("Failed".to_string()); } let mut out = input.to_vec(); out.push(1); Ok(out) } } macro_rules! test_runner { ($name:ident, $verbosity:expr, $fail:expr, $expected_res:expr, $expected_len:expr) => { #[test] fn $name() { let plugin = MockPlugin { name: "mock", f: 10, q: 10, s: 10, fail: $fail }; let path: Vec<(&dyn Plugin, &str, &str)> = vec![(&plugin, "a", "b")]; let input = vec![0]; let result = run_conversion(&path, &input, $verbosity); assert_eq!(result.is_ok(), $expected_res); if let Ok(res) = result { assert_eq!(res.len(), $expected_len); } } }; } test_runner!(test_runner_verb_0, 0, false, true, 2); test_runner!(test_runner_verb_1, 1, false, true, 2); test_runner!(test_runner_verb_2, 2, false, true, 2); test_runner!(test_runner_verb_3, 3, false, true, 2); test_runner!(test_runner_verb_4, 4, false, true, 2); test_runner!(test_runner_verb_5, 5, false, true, 2); test_runner!(test_runner_verb_0_fail, 0, true, false, 0); test_runner!(test_runner_verb_1_fail, 1, true, false, 0); test_runner!(test_runner_verb_4_fail, 4, true, false, 0); test_runner!(test_runner_verb_255, 255, false, true, 2); }