Initial commit

This commit is contained in:
Elias Wendland
2026-07-01 15:50:24 +02:00
commit e030513d57
14 changed files with 928 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
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);
}
}
}