use clap::{Parser, Subcommand};
use derive_getters::Getters;
use std::path::PathBuf;
#[derive(Debug, Clone, Parser, Getters)]
#[command(name = "elicitation")]
#[command(about = "Type-safe LLM elicitation with formal verification")]
pub struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Debug, Clone, Subcommand)]
pub enum Commands {
Verify {
#[command(subcommand)]
action: VerifyAction,
},
Prusti {
#[command(subcommand)]
action: PrustiAction,
},
}
#[derive(Debug, Clone, Subcommand)]
pub enum VerifyAction {
List,
Run {
#[arg(short, long, default_value = "kani_verification_results.csv")]
output: PathBuf,
#[arg(short, long, default_value_t = 300)]
timeout: u64,
#[arg(short, long)]
resume: bool,
},
Summary {
#[arg(default_value = "kani_verification_results.csv")]
file: PathBuf,
},
Failed {
#[arg(default_value = "kani_verification_results.csv")]
file: PathBuf,
},
}
#[derive(Debug, Clone, Subcommand)]
pub enum PrustiAction {
List,
Run {
#[arg(short, long, default_value = "prusti_verification_results.csv")]
output: PathBuf,
#[arg(short, long, default_value_t = 600)]
timeout: u64,
},
Summary {
#[arg(short, long, default_value = "prusti_verification_results.csv")]
file: PathBuf,
},
Failed {
#[arg(short, long, default_value = "prusti_verification_results.csv")]
file: PathBuf,
},
}
#[tracing::instrument(skip(cli))]
pub fn execute(cli: Cli) -> anyhow::Result<()> {
tracing::debug!("Executing CLI command");
match cli.command() {
Commands::Verify { action } => crate::verification::runner::handle(action),
Commands::Prusti { action } => handle_prusti(action),
}
}
#[tracing::instrument(skip(action))]
fn handle_prusti(action: &PrustiAction) -> anyhow::Result<()> {
tracing::debug!(action = ?action, "Handling Prusti command");
match action {
PrustiAction::List => crate::verification::prusti_runner::list_modules(),
PrustiAction::Run { output, timeout } => {
crate::verification::prusti_runner::run_all(output, *timeout)
}
PrustiAction::Summary { file } => crate::verification::prusti_runner::show_summary(file),
PrustiAction::Failed { file } => crate::verification::prusti_runner::show_failed(file),
}
}