use clap::{Parser, Subcommand};
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(name = "amaters-server")]
#[command(version = env!("CARGO_PKG_VERSION"))]
#[command(about = "AmateRS Fully Homomorphic Encrypted Database Server", long_about = None)]
#[command(author = "COOLJAPAN OU (Team KitaSan)")]
pub struct Cli {
#[arg(short, long, default_value = "./config.toml", global = true)]
pub config: PathBuf,
#[arg(short, long, global = true)]
pub bind: Option<String>,
#[arg(short, long, global = true)]
pub data_dir: Option<PathBuf>,
#[arg(long, global = true)]
pub log_level: Option<String>,
#[command(subcommand)]
pub command: Command,
}
#[derive(Subcommand, Debug, Clone)]
pub enum Command {
Start {
#[arg(short, long)]
foreground: bool,
#[arg(long)]
generate_config: bool,
},
Stop {
#[arg(short, long)]
force: bool,
#[arg(short, long, default_value = "30")]
timeout: u64,
},
Status {
#[arg(short, long, default_value = "human")]
format: String,
},
Version {
#[arg(short, long)]
verbose: bool,
},
ValidateConfig {
#[arg(short, long)]
show: bool,
},
}
impl Cli {
pub fn parse_args() -> Self {
Self::parse()
}
pub fn config_path(&self) -> &PathBuf {
&self.config
}
pub fn has_config_override(&self) -> bool {
self.config.to_str() != Some("./config.toml")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StatusFormat {
Human,
Json,
}
impl StatusFormat {
pub fn from_str(s: &str) -> Result<Self, String> {
match s.to_lowercase().as_str() {
"human" => Ok(Self::Human),
"json" => Ok(Self::Json),
_ => Err(format!("Invalid format: {}. Must be 'human' or 'json'", s)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_status_format_parsing() {
assert_eq!(
StatusFormat::from_str("human").ok(),
Some(StatusFormat::Human)
);
assert_eq!(
StatusFormat::from_str("json").ok(),
Some(StatusFormat::Json)
);
assert_eq!(
StatusFormat::from_str("Human").ok(),
Some(StatusFormat::Human)
);
assert!(StatusFormat::from_str("invalid").is_err());
}
}