nedots 0.1.3

A tool to manage configuration files/(ne)dots.
use crate::paths::MakeDirs;
use std::path::Path;

#[derive(Debug, clap::Args)]
/// Clean up `dots` & `backups`. Example: `nedots clean -db` to clean both.
pub(crate) struct CleanCmd {
    #[arg(short, long)]
    /// Clean up `dots`.
    dots: bool,

    #[arg(short, long)]
    /// Clean up `backups`.
    backups: bool,

    #[arg(short = 'y', long)]
    /// Won't prompt you to confirm the operation when cleaning.
    assumeyes: bool,
}

impl super::Command for CleanCmd {
    fn run(
        &self,
        _: &super::nedots::RootCmd,
        config: &crate::config::Config,
    ) -> anyhow::Result<()> {
        if self.dots {
            confirm_clean(
                &format!(
                    " ~ {}. Continue?",
                    console::style("Cleaning dots").yellow().bold()
                ),
                &config.root.join(&config.dots_dir),
                self.assumeyes,
            )?
        }

        if self.backups {
            confirm_clean(
                &format!(
                    " ~ {}. Continue?",
                    console::style("Cleaning backups").yellow().bold()
                ),
                &config.root.join(&config.backup_dir),
                self.assumeyes,
            )?
        }

        Ok(())
    }
}

fn confirm_clean(prompt: &str, path: &Path, assumeyes: bool) -> anyhow::Result<()> {
    match assumeyes {
        true => clean(path),
        false => confirm(prompt, path, clean),
    }
}

fn confirm(
    prompt: &str,
    path: &Path,
    func: impl Fn(&Path) -> anyhow::Result<()>,
) -> anyhow::Result<()> {
    match dialoguer::Confirm::new().with_prompt(prompt).interact()? {
        true => func(path),
        false => Ok(()),
    }
}

fn clean(dir: &Path) -> anyhow::Result<()> {
    trash::delete(dir)?;
    log::trace!("Trashed {}!", dir.display());

    dir.make_all_dirs()?;
    log::trace!("Recreated {}", dir.display());

    log::info!("🗑️ Removed {}", console::style(dir.display()).bold().red());
    Ok(())
}