use clap::{Parser, Subcommand};
use std::fs;
use std::path::PathBuf;
use brine_kiwi_compiler::{compile_schema, compile_schema_to_rust, decode_binary_schema};
use brine_kiwi_compiler::error::KiwiError;
use brine_kiwi::decode_to_json;
#[derive(Parser)]
#[command(name = "brine-kiwi-cli")]
#[command(about = "Compile, decode, or generate Rust from Kiwi schemas", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Compile {
#[arg(short, long)]
input: PathBuf,
#[arg(short, long)]
output: Option<PathBuf>,
},
Decode {
#[arg(short, long)]
input: PathBuf,
},
GenRust {
#[arg(short, long)]
input: PathBuf,
#[arg(short, long)]
output: Option<PathBuf>,
},
}
fn main() -> Result<(), KiwiError> {
let cli = Cli::parse();
match &cli.command {
Commands::Compile { input, output } => {
let text = fs::read_to_string(input).map_err(KiwiError::Io)?;
let (_schema, bin) = compile_schema(&text)?;
let out_path = if let Some(o) = output {
o.clone()
} else {
let mut p = input.clone();
p.set_extension("kiwi.bin");
p
};
fs::write(&out_path, &bin).map_err(KiwiError::Io)?;
println!("Compiled {} → {}", input.display(), out_path.display());
Ok(())
}
Commands::Decode { input } => {
let data = fs::read(input).map_err(KiwiError::Io)?;
let _schema = decode_binary_schema(&data)?;
let json = decode_to_json(&data)?;
println!("{}", json);
Ok(())
}
Commands::GenRust { input, output } => {
let text = fs::read_to_string(input).map_err(KiwiError::Io)?;
let (schema, _bin) = compile_schema(&text)?;
let rust_code = compile_schema_to_rust(&schema);
if let Some(out_path) = output {
fs::write(out_path, &rust_code).map_err(KiwiError::Io)?;
println!("Generated Rust code written to {}", out_path.display());
} else {
println!("Generated Rust code:\n\n{}", rust_code);
}
Ok(())
}
}
}