use clap::{CommandFactory, Subcommand};
use clap_complete::{
generate_to,
shells::{Bash, Elvish, Fish, PowerShell, Zsh},
};
use home::home_dir;
use std::fs::create_dir_all;
use crate::{cli::CliArgs, commands::list_crates::ListCrates};
use crate::{
commands::{gh::lib::GhSubCommand, movies::MoviesSubCommand, shortcuts::ShortcutsSubcommand},
config::Config,
errors::GeneralError,
};
use crate::commands::config::ConfigSubcommand;
pub(crate) mod config;
pub(crate) mod gh;
pub(crate) mod list_crates;
pub(crate) mod man;
pub(crate) mod movies;
pub(crate) mod music;
pub(crate) mod share;
pub(crate) mod shortcuts;
pub(crate) mod watching;
#[derive(Subcommand, Debug)]
pub(crate) enum Commands {
Config {
#[command(subcommand)]
subcommand: ConfigSubcommand,
},
Gh {
#[command(subcommand)]
subcommand: GhSubCommand,
},
Movies {
#[command(subcommand)]
subcommand: MoviesSubCommand,
},
Completions,
#[command(alias = "s")]
Shortcuts {
#[command(subcommand)]
subcommand: ShortcutsSubcommand,
},
Man,
#[command(name = "list_crates")]
ListCrates(ListCrates),
#[cfg(feature = "pngtools")]
#[command(name = "pngtools")]
PngTools,
#[cfg(feature = "git-mover")]
#[command(name = "git-mover")]
GitMover(git_mover::GitMoverCli),
#[cfg(feature = "galion")]
#[command(name = "galion")]
Galion(galion::GalionArgs),
Music {
#[command(subcommand)]
subcommand: crate::commands::music::MusicSubcommand,
},
Share,
Watching,
}
impl Commands {
pub fn gen_completions(_config: &mut Config) -> Result<(), GeneralError> {
let mut cmd = CliArgs::command();
let app_name = env!("CARGO_CRATE_NAME");
let outdir = home_dir().ok_or(GeneralError::new("Cannot get home dir"))?;
let outdir = outdir.join(".config").join(".n4n5").join("completions");
create_dir_all(&outdir)?;
generate_to(Bash, &mut cmd, app_name, &outdir)?;
generate_to(Zsh, &mut cmd, app_name, &outdir)?;
generate_to(Fish, &mut cmd, app_name, &outdir)?;
generate_to(PowerShell, &mut cmd, app_name, &outdir)?;
generate_to(Elvish, &mut cmd, app_name, &outdir)?;
Ok(())
}
pub(crate) fn invoke(self, config: &mut Config) -> Result<(), GeneralError> {
match self {
Commands::Config { subcommand } => subcommand.invoke(config),
Commands::Gh { subcommand } => subcommand.invoke(config),
Commands::Movies { subcommand } => subcommand.invoke(config),
Commands::Completions => Commands::gen_completions(config),
Commands::Man => Commands::gen_man(config),
Commands::Shortcuts { subcommand } => subcommand.run(config),
Commands::ListCrates(subcommand) => subcommand.list_crates(config),
#[cfg(feature = "pngtools")]
Commands::PngTools => Self::pngtools(),
#[cfg(feature = "git-mover")]
Commands::GitMover(git_mover) => Self::git_mover(git_mover),
#[cfg(feature = "galion")]
Commands::Galion(galion_args) => Self::galion(galion_args),
Commands::Music { subcommand } => subcommand.invoke(config),
Commands::Share => Self::share(),
Commands::Watching => Self::watching(),
}
}
#[cfg(feature = "pngtools")]
pub fn pngtools() -> Result<(), GeneralError> {
pngtools::run_cli().map_err(|e| ("Error with pngtools", e))?;
Ok(())
}
pub(crate) fn share() -> Result<(), GeneralError> {
use crate::commands::share::main;
use tokio::runtime::Runtime;
let rt = Runtime::new()?;
rt.block_on(async {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.init();
main()
.await
.map_err(|e| GeneralError::new_with_source("Error from sharing", e))
})?;
Ok(())
}
#[cfg(feature = "git-mover")]
pub fn git_mover(git_mover_inst: git_mover::GitMoverCli) -> Result<(), GeneralError> {
use tokio::runtime::Runtime;
let rt = Runtime::new()?;
rt.block_on(async {
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.format_target(false)
.format_timestamp(None)
.init();
git_mover_inst
.main()
.await
.map_err(|e| GeneralError::new_with_source("Error with git-mover", e))
})?;
Ok(())
}
#[cfg(feature = "galion")]
pub fn galion(galion_args: galion::GalionArgs) -> Result<(), GeneralError> {
use galion::GalionApp;
let app = GalionApp::try_from_galion_args(galion_args)
.map_err(|e| GeneralError::new_with_source("Error with galion", e))?;
app.run_tui()
.map_err(|e| GeneralError::new_with_source("Error with galion", e))?;
Ok(())
}
}