cargo-trim 0.7.0

Binary application to cleanup $CARGO_HOME cache
use colored::Colorize;
use std::{env, fs, path::Path};

// list all a env variables list in vector form
pub(crate) fn env_list(variable: &str) -> Vec<String> {
    let list = env::var(variable);
    let mut vec_list = Vec::new();
    if let Ok(name_list) = list {
        name_list
            .split_whitespace()
            .for_each(|name| vec_list.push(name.to_string()));
    }
    vec_list
}

// remove semver version part from crates full name
pub(crate) fn clear_version_value(full_name: &str) -> (String, String) {
    let version_split: Vec<&str> = full_name.split('-').collect();
    let mut version_start_position = version_split.len();
    // check a split part to check from where a semver start
    for (pos, split_part) in version_split.iter().enumerate() {
        if semver::Version::parse(split_part).is_ok() {
            version_start_position = pos;
            break;
        }
    }
    let (clear_name_vec, version_vec) = version_split.split_at(version_start_position);
    let clear_name = clear_name_vec.join("-");
    let version = version_vec.join("-");
    (clear_name, version)
}

// delete folder with folder path provided
pub(crate) fn delete_folder(path: &Path, dry_run: bool) -> std::io::Result<()> {
    if path.exists() {
        if path.is_file() {
            if dry_run {
                println!(
                    "{} {} {:?}",
                    "Dry run:".color("yellow"),
                    "Removed".color("red"),
                    path
                );
            } else {
                fs::remove_file(&path)?;
            }
        } else if path.is_dir() {
            if dry_run {
                println!(
                    "{} {} {:?}",
                    "Dry run:".color("yellow"),
                    "Removed".color("red"),
                    path
                );
            } else {
                fs::remove_dir_all(path)?;
            }
        }
    }
    Ok(())
}

//  get size of directory
pub(crate) fn get_size(path: &Path) -> std::io::Result<u64> {
    let mut total_size = 0;
    if path.is_dir() {
        for entry in fs::read_dir(path)? {
            let entry_path = entry?.path();
            if entry_path.is_dir() {
                total_size += get_size(&entry_path)?;
            } else {
                total_size += entry_path.metadata()?.len();
            }
        }
    } else {
        total_size += path.metadata()?.len();
    }
    Ok(total_size)
}

#[allow(
    clippy::cast_precision_loss,
    clippy::cast_possible_truncation,
    clippy::cast_sign_loss
)]
pub(crate) fn convert_pretty(num: u64) -> String {
    if num == 0 {
        return "0 B".to_string();
    }
    let num = num as f64;
    let units = ["B", "kB", "MB", "GB", "TB"];
    let factor = (num.log10() / 3_f64).floor();
    let power_factor = if factor >= units.len() as f64 {
        (units.len() - 1) as f64
    } else {
        factor
    };
    let pretty_bytes = format!("{:.3}", num / 1000_f64.powf(power_factor))
        .parse::<f64>()
        .unwrap();
    let unit = units[power_factor as usize];
    format!("{} {}", pretty_bytes, unit)
}