tripley-rpc-gen-cpp 0.1.1

C++ client and server generator for Tripley RPC IDL.
Documentation
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())
}