use clap::Parser;
use std::collections::HashMap;
use std::error::Error;
use tx3_bindgen::{rust, typescript, Job};
fn parse_key_val<T, U>(s: &str) -> Result<(T, U), Box<dyn Error + Send + Sync + 'static>>
where
T: std::str::FromStr,
T::Err: Error + Send + Sync + 'static,
U: std::str::FromStr,
U::Err: Error + Send + Sync + 'static,
{
let pos = s
.find('=')
.ok_or_else(|| format!("invalid KEY=value: no `=` found in `{s}`"))?;
Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
}
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[arg(short, long)]
output: String,
#[arg(short, long, required = true, num_args = 1..)]
input: Vec<String>,
#[arg(short, long, value_parser = ["typescript", "python", "rust", "balius"])]
template: String,
#[arg(short = 'R', long)]
trp_endpoint: Option<String>,
#[arg(short = 'H', long, value_parser = parse_key_val::<String, String>)]
trp_header: Vec<(String, String)>,
#[arg(short = 'E', long, value_parser = parse_key_val::<String, String>)]
env_arg: Vec<(String, String)>,
}
fn main() {
let cli = Cli::parse();
for input_file in cli.input {
let protocol = tx3_lang::Protocol::from_file(&input_file)
.load()
.unwrap_or_else(|e| {
eprintln!("Failed to load protocol file {}: {}", input_file, e);
std::process::exit(1);
});
let input_file = std::path::Path::new(&input_file);
let job = Job {
name: input_file
.file_stem()
.unwrap()
.to_str()
.unwrap()
.to_string(),
protocol,
dest_path: cli.output.clone().into(),
trp_endpoint: cli
.trp_endpoint
.clone()
.unwrap_or("http://localhost:3000".to_string()),
trp_headers: HashMap::from_iter(cli.trp_header.clone()),
env_args: HashMap::from_iter(cli.env_arg.clone()),
};
match cli.template.as_str() {
"typescript" => typescript::generate(&job),
"rust" => rust::generate(&job),
"python" => todo!(),
"balius" => todo!(),
_ => unreachable!(), }
}
}