pub mod install;
use crate::config::ShellType;
use clap::{Parser, Subcommand};
use std::path::PathBuf;
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
pub enum ShellTypeArg {
Bash,
Zsh,
Fish,
}
impl From<ShellTypeArg> for ShellType {
fn from(arg: ShellTypeArg) -> Self {
match arg {
ShellTypeArg::Bash => ShellType::Bash,
ShellTypeArg::Zsh => ShellType::Zsh,
ShellTypeArg::Fish => ShellType::Fish,
}
}
}
#[derive(Parser)]
#[command(name = "par-term")]
#[command(author, version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
pub command: Option<Commands>,
#[arg(long, value_name = "SHADER")]
pub shader: Option<String>,
#[arg(long, value_name = "SECONDS")]
pub exit_after: Option<f64>,
#[arg(long, value_name = "PATH", num_args = 0..=1, default_missing_value = "")]
pub screenshot: Option<PathBuf>,
#[arg(long, value_name = "COMMAND")]
pub command_to_send: Option<String>,
#[arg(long)]
pub log_session: bool,
#[arg(long, value_enum, value_name = "LEVEL")]
pub log_level: Option<LogLevelArg>,
}
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
pub enum LogLevelArg {
Off,
Error,
Warn,
Info,
Debug,
Trace,
}
impl LogLevelArg {
pub fn to_level_filter(self) -> log::LevelFilter {
match self {
LogLevelArg::Off => log::LevelFilter::Off,
LogLevelArg::Error => log::LevelFilter::Error,
LogLevelArg::Warn => log::LevelFilter::Warn,
LogLevelArg::Info => log::LevelFilter::Info,
LogLevelArg::Debug => log::LevelFilter::Debug,
LogLevelArg::Trace => log::LevelFilter::Trace,
}
}
}
#[derive(Subcommand)]
pub enum Commands {
InstallShaders {
#[arg(short = 'y', long)]
yes: bool,
#[arg(short, long)]
force: bool,
},
InstallShellIntegration {
#[arg(long, value_enum)]
shell: Option<ShellTypeArg>,
},
UninstallShellIntegration,
UninstallShaders {
#[arg(short, long)]
force: bool,
},
InstallIntegrations {
#[arg(short = 'y', long)]
yes: bool,
},
SelfUpdate {
#[arg(short = 'y', long)]
yes: bool,
},
McpServer,
}
#[derive(Clone, Debug, Default)]
pub struct RuntimeOptions {
pub shader: Option<String>,
pub exit_after: Option<f64>,
pub screenshot: Option<PathBuf>,
pub command_to_send: Option<String>,
pub log_session: bool,
pub log_level: Option<log::LevelFilter>,
}
pub enum CliResult {
Continue(RuntimeOptions),
Exit(i32),
}
pub fn process_cli() -> CliResult {
use install::{
install_integrations_cli, install_shaders_cli, install_shell_integration_cli,
self_update_cli, uninstall_shaders_cli, uninstall_shell_integration_cli,
};
let cli = Cli::parse();
match cli.command {
Some(Commands::InstallShaders { yes, force }) => {
let result = install_shaders_cli(yes || force);
CliResult::Exit(if result.is_ok() { 0 } else { 1 })
}
Some(Commands::InstallShellIntegration { shell }) => {
let result = install_shell_integration_cli(shell.map(Into::into));
CliResult::Exit(if result.is_ok() { 0 } else { 1 })
}
Some(Commands::UninstallShellIntegration) => {
let result = uninstall_shell_integration_cli();
CliResult::Exit(if result.is_ok() { 0 } else { 1 })
}
Some(Commands::UninstallShaders { force }) => {
let result = uninstall_shaders_cli(force);
CliResult::Exit(if result.is_ok() { 0 } else { 1 })
}
Some(Commands::InstallIntegrations { yes }) => {
let result = install_integrations_cli(yes);
CliResult::Exit(if result.is_ok() { 0 } else { 1 })
}
Some(Commands::SelfUpdate { yes }) => {
let result = self_update_cli(yes);
CliResult::Exit(if result.is_ok() { 0 } else { 1 })
}
Some(Commands::McpServer) => {
crate::mcp_server::set_app_version(crate::VERSION);
crate::mcp_server::run_mcp_server();
CliResult::Exit(0)
}
None => {
let options = RuntimeOptions {
shader: cli.shader,
exit_after: cli.exit_after,
screenshot: cli.screenshot,
command_to_send: cli.command_to_send,
log_session: cli.log_session,
log_level: cli.log_level.map(|l| l.to_level_filter()),
};
CliResult::Continue(options)
}
}
}