Initial commit
This commit is contained in:
+126
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user