pub mod args; pub mod identifier; pub mod pathfinder; pub mod plugin; pub mod runner; include!(concat!(env!("OUT_DIR"), "/plugins_gen.rs")); use args::Args; use clap::Parser; use std::fs; use std::io::{self, IsTerminal, Write}; use std::process; fn main() { let args = Args::parse(); // Read input file let input_bytes = match fs::read(&args.input_path) { Ok(b) => b, Err(e) => { if !args.quiet { eprintln!("Error reading input file: {}", e); } process::exit(1); } }; let from_format = match identifier::identify_format(&args.input_path) { Some(f) => f, None => { if !args.quiet { eprintln!("Error: Unknown input format."); } process::exit(1); } }; let plugins = get_plugins(); let to_format = match &args.output_path { Some(out) => match identifier::identify_format(out) { Some(f) => f, None => { if !args.quiet { eprintln!("Error: Unknown output format."); } process::exit(1); } }, None => { // Pick a default target format based on the first available conversion let default_target = plugins.iter().find_map(|p| { if p.from_formats().contains(&from_format) { p.to_formats().first().copied() } else { None } }); match default_target { Some(t) => t, None => { if !args.quiet { eprintln!("Error: No output path provided, and no available conversions found."); } process::exit(1); } } } }; let path = match pathfinder::find_best_path(&plugins, from_format, to_format, &args.priority) { Some(p) => p, None => { if !args.quiet { eprintln!("Error: No conversion path found from {} to {}.", from_format, to_format); } process::exit(1); } }; if args.test { if !args.quiet { let path_str: Vec<_> = path.iter().map(|(p, _, _)| p.name()).collect(); println!("Test successful. Path: {}", path_str.join(" -> ")); } return; } let verbosity = args.verbosity_level(); let result = runner::run_conversion(&path, &input_bytes, verbosity); let output_bytes = match result { Ok(b) => b, Err(e) => { if !args.quiet { eprintln!("Conversion error: {}", e); } process::exit(1); } }; if let Some(out_path) = &args.output_path { if let Err(e) = fs::write(out_path, &output_bytes) { if !args.quiet { eprintln!("Error writing output file: {}", e); } process::exit(1); } } else { let is_piped = !io::stdout().is_terminal(); if !is_piped && !args.write_to_console { if !args.quiet { eprintln!("Warning: Outputting directly to console. Use -c to suppress this warning, or redirect to a file."); } } let mut stdout = io::stdout(); if let Err(e) = stdout.write_all(&output_bytes) { if !args.quiet { eprintln!("Error writing to console: {}", e); } process::exit(1); } } }