use clap::Parser;
use crate::commands::*;
use crate::config::Config;
#[derive(Parser)]
#[command(version, about, long_about = None)]
pub struct Cli {
#[arg(short = 'T', long, default_value = "false", action = clap::ArgAction::SetTrue)]
pub(crate) time: bool,
#[arg(short = 'C', long = "config")]
config_path: Option<std::path::PathBuf>,
#[arg(short, action = clap::ArgAction::Count)]
pub(crate) verbose: u8,
#[command(subcommand)]
command: Commands,
#[clap(skip)]
pub config: Config,
}
impl Default for Cli {
fn default() -> Self {
Self::parse()
}
}
impl Cli {
pub fn new() -> anyhow::Result<Self> {
let mut cli = Self::parse();
if let Some(config_path) = &cli.config_path {
cli.config = Config::load(config_path)?
}
Ok(cli)
}
pub fn path_with_default_ext(&self, path: impl AsRef<std::path::Path>) -> std::path::PathBuf {
let mut path = path.as_ref().to_path_buf();
if path.extension().is_none() {
path.set_extension(self.config.default_extension.clone());
}
path
}
pub fn run(&self) -> anyhow::Result<()> {
let start = std::time::Instant::now();
match &self.command {
Commands::Parse(parse) => {
parse.run(self)?;
}
Commands::Resolve(resolve) => {
resolve.run(self)?;
}
Commands::Eval(eval) => {
eval.run(self)?;
}
Commands::Export(export) => {
export.run(self)?;
}
Commands::Create(create) => {
create.run(self)?;
}
Commands::Watch(watch) => {
watch.run(self)?;
}
Commands::Install(install) => {
install.run(self)?;
}
}
if self.time {
eprintln!(
"Overall Time : {}",
Self::time_to_string(&start.elapsed())
);
}
Ok(())
}
pub(super) fn is_parse(&self) -> bool {
matches!(self.command, Commands::Parse(..))
}
pub(super) fn is_resolve(&self) -> bool {
matches!(self.command, Commands::Resolve(..))
}
pub(super) fn is_eval(&self) -> bool {
matches!(self.command, Commands::Eval(..))
}
pub(super) fn is_export(&self) -> bool {
matches!(self.command, Commands::Export(..))
}
pub(super) fn time_to_string(duration: &std::time::Duration) -> String {
use num_format::{Locale, ToFormattedString};
format!(
"{:>8}µs",
duration.as_micros().to_formatted_string(&Locale::en)
)
}
}