use clap::{Parser, Subcommand, ValueEnum};
use clap_complete::Shell;
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "tensorlogic")]
#[command(author, version, about, long_about = None)]
#[command(propagate_version = true)]
pub struct Cli {
#[arg(value_name = "INPUT")]
pub input: String,
#[arg(short = 'f', long, value_enum, default_value = "expr")]
pub input_format: InputFormat,
#[arg(short, long)]
pub output: Option<PathBuf>,
#[arg(short = 'F', long, value_enum, default_value = "graph")]
pub output_format: OutputFormat,
#[arg(short, long)]
pub strategy: Option<String>,
#[arg(short, long, value_parser = parse_domain)]
pub domains: Vec<(String, usize)>,
#[arg(long)]
pub validate: bool,
#[arg(long)]
pub debug: bool,
#[arg(short, long)]
pub analyze: bool,
#[arg(short, long)]
pub quiet: bool,
#[arg(long)]
pub no_color: bool,
#[arg(long)]
pub no_config: bool,
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Subcommand)]
pub enum Commands {
Repl,
Batch {
#[arg(required = true)]
files: Vec<PathBuf>,
},
Watch {
file: PathBuf,
},
Completion {
#[arg(value_enum)]
shell: Shell,
},
Config {
#[command(subcommand)]
command: ConfigCommand,
},
}
#[derive(Subcommand)]
pub enum ConfigCommand {
Show,
Path,
Init,
Edit,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum InputFormat {
Expr,
Json,
Yaml,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum OutputFormat {
Graph,
Dot,
Json,
Stats,
}
fn parse_domain(s: &str) -> Result<(String, usize), String> {
let parts: Vec<&str> = s.split(':').collect();
if parts.len() != 2 {
return Err(format!("Invalid domain format '{}'. Expected name:size", s));
}
let name = parts[0].to_string();
let size = parts[1]
.parse::<usize>()
.map_err(|e| format!("Invalid domain size: {}", e))?;
Ok((name, size))
}