Repository: sharkdp/bat
File: src/bin/bat/assets.rs (Rust)

Code before:
use std::fs;
use std::io;
use std::path::Path;
use std::path::PathBuf;

use clap::crate_version;

use crate::directories::PROJECT_DIRS;

use bat::assets::HighlightingAssets;
use bat::assets_metadata::AssetsMetadata;
use bat::error::*;

pub fn config_dir() -> Cow<'static, str> {
    PROJECT_DIRS.config_dir().to_string_lossy()
}

pub fn cache_dir() -> Cow<'static, str> {
    PROJECT_DIRS.cache_dir().to_string_lossy()
}

pub fn clear_assets(matches: &clap::ArgMatches) {
    let target_dir = matches
        .get_one::<String>("target")
        .map(Path::new)
        .unwrap_or_else(|| PROJECT_DIRS.cache_dir());

    clear_asset(target_dir.join("themes.bin"), "theme set cache");
    clear_asset(target_dir.join("syntaxes.bin"), "syntax set cache");
    clear_asset(target_dir.join("metadata.yaml"), "metadata file");
}

pub fn assets_from_cache_or_binary(use_custom_assets: bool) -> Result<HighlightingAssets> {
    let cache_dir = PROJECT_DIRS.cache_dir();
    if let Some(metadata) = AssetsMetadata::load_from_folder(cache_dir)? {
        if !metadata.is_compatible_with(crate_version!()) {
            return Err(format!(
                "The binary caches for the user-customized syntaxes and themes \
                 in '{}' are not compatible with this version of bat ({}). To solve this, \
                 either rebuild the cache (bat cache --build) or remove \
                 the custom syntaxes/themes (bat cache --clear).\n\
                 For more information, see:\n\n  \
                 https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions",
                cache_dir.to_string_lossy(),
                crate_version!()
            )
            .into());
        }
    }

    let custom_assets = if use_custom_assets {

Review comment (performance):
Thanks for working on this 👍 

Would be great if we could take it one step further and
1. Remove all uses of `PROJECT_DIRS.cache_dir()`
2. Calculate its value centrally and pass it down to whoever needs it

That way we don't need to duplicate this code from `fn build_assets()`, and we reduce the use of globals.

And long-term (or in this PR if you wish) we should do the same for for `PROJECT_DIRS.config_dir()`.


Code after:
use std::io;
use std::path::Path;
use std::path::PathBuf;

use clap::crate_version;

use bat::assets::HighlightingAssets;
use bat::assets_metadata::AssetsMetadata;
use bat::error::*;

pub fn clear_assets(cache_dir: &Path) {
    clear_asset(cache_dir.join("themes.bin"), "theme set cache");
    clear_asset(cache_dir.join("syntaxes.bin"), "syntax set cache");
    clear_asset(cache_dir.join("metadata.yaml"), "metadata file");
}

pub fn assets_from_cache_or_binary(
    use_custom_assets: bool,
    cache_dir: &Path,
) -> Result<HighlightingAssets> {
    if let Some(metadata) = AssetsMetadata::load_from_folder(cache_dir)? {
        if !metadata.is_compatible_with(crate_version!()) {
            return Err(format!(
                "The binary caches for the user-customized syntaxes and themes \
                 in '{}' are not compatible with this version of bat ({}). To solve this, \
                 either rebuild the cache (bat cache --build) or remove \
                 the custom syntaxes/themes (bat cache --clear).\n\
                 For more information, see:\n\n  \
                 https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions",
                cache_dir.to_string_lossy(),
                crate_version!()
            )
            .into());
        }
    }

    let custom_assets = if use_custom_assets {
        HighlightingAssets::from_cache(cache_dir).ok()
    } else {
        None
    };
    Ok(custom_assets.unwrap_or_else(HighlightingAssets::from_binary))
}

fn clear_asset(path: PathBuf, description: &str) {
    print!("Clearing {} ... ", description);
    match fs::remove_file(&path) {
        Err(err) if err.kind() == io::ErrorKind::NotFound => {
            println!("skipped (not present)");
        }
        Err(err) => {