use std::io::Read;
use std::process::ExitCode;
use camino::Utf8PathBuf;
use clap::Parser;
use rpc_gen_cpp::{GenerateOptions, generate_to_dir};
#[derive(Debug, Parser)]
#[command(name = "rpc-gen-cpp")]
struct Cli {
#[arg(long)]
describe: bool,
#[arg(long = "plugin-name", default_value = "cpp")]
plugin_name: String,
#[arg(long = "out-dir")]
out_dir: Option<Utf8PathBuf>,
#[arg(long = "opt")]
opts: Vec<String>,
}
fn main() -> ExitCode {
match run(Cli::parse()) {
Ok(()) => ExitCode::SUCCESS,
Err(error) => {
eprintln!("{error}");
ExitCode::FAILURE
}
}
}
fn run(cli: Cli) -> Result<(), String> {
if cli.describe {
println!(
"{}",
serde_json::json!({
"name": "rpc-gen-cpp",
"plugin_name": cli.plugin_name,
"version": env!("CARGO_PKG_VERSION"),
"output_mode": "direct_file_writing",
"capabilities": [
"cpp.dto",
"cpp.codec",
"cpp.client",
"cpp.server",
"cpp.activation",
"cpp.notifications",
"cpp.boost-asio",
"cpp.vcpkg"
],
"transports": [
"tcp"
]
})
);
return Ok(());
}
let out_dir = cli
.out_dir
.ok_or_else(|| "--out-dir is required unless --describe is used".to_string())?;
let mut input = String::new();
std::io::stdin()
.read_to_string(&mut input)
.map_err(|error| format!("failed to read IR from stdin: {error}"))?;
let ir = serde_json::from_str(&input)
.map_err(|error| format!("failed to parse canonical IR from stdin: {error}"))?;
let options = GenerateOptions::from_cli_opts(&cli.opts).map_err(|error| error.to_string())?;
generate_to_dir(&ir, &out_dir, options).map_err(|error| error.to_string())
}