Simplify interface to obtaining cache_dir

This commit is contained in:
David Tolnay 2025-03-02 22:27:38 -08:00
parent 69f8fad695
commit a58bd1a6ca
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82
4 changed files with 87 additions and 147 deletions

1
Cargo.lock generated
View file

@ -197,7 +197,6 @@ version = "1.0.100"
dependencies = [
"bat",
"cargo-subcommand-metadata",
"cfg-if",
"clap",
"clap-cargo",
"console",

View file

@ -19,7 +19,6 @@ prettyplease = []
[dependencies]
bat = { version = "0.25", default-features = false, features = ["paging", "regex-fancy"] }
cargo-subcommand-metadata = "0.1"
cfg-if = "1"
clap = { version = "4", features = ["deprecated", "derive"] }
clap-cargo = "0.15"
console = "0.15"

View file

@ -1,5 +1,5 @@
use crate::error::Result;
use crate::etcetera::{self, BaseStrategy as _};
use crate::etcetera;
use std::env;
use std::path::PathBuf;
use std::str;
@ -21,6 +21,6 @@ pub fn cache_dir() -> Result<PathBuf> {
return Ok(PathBuf::from(cache_dir));
}
let basedirs = etcetera::choose_base_strategy()?;
Ok(basedirs.cache_dir().join("bat"))
let cache_dir = etcetera::cache_dir()?;
Ok(cache_dir.join("bat"))
}

View file

@ -1,51 +1,23 @@
use crate::error::{Error, Result};
pub mod base_strategy {
use crate::error::Result;
use std::path::PathBuf;
pub trait BaseStrategy {
fn cache_dir(&self) -> PathBuf;
}
macro_rules! create_strategies {
($base: ty) => {
pub fn choose_base_strategy() -> Result<$base> {
<$base>::new()
}
};
}
cfg_if::cfg_if! {
if #[cfg(target_os = "windows")] {
create_strategies!(Windows);
} else if #[cfg(any(target_os = "macos", target_os = "ios"))] {
create_strategies!(Xdg);
pub fn cache_dir() -> Result<PathBuf> {
let home_dir = home::home_dir().ok_or(Error::HomeDir)?;
if cfg!(windows) {
Ok(windows::cache_dir(&home_dir))
} else {
create_strategies!(Xdg);
Ok(xdg::cache_dir(&home_dir))
}
}
mod windows {
use crate::error::Result;
use std::path::PathBuf;
pub struct Windows {
home_dir: PathBuf,
}
impl Windows {
pub fn new() -> Result<Self> {
Ok(Self {
home_dir: crate::etcetera::home_dir()?,
})
}
use std::path::{Path, PathBuf};
fn dir_inner(env: &'static str) -> Option<PathBuf> {
std::env::var_os(env)
.filter(|s| !s.is_empty())
.map(PathBuf::from)
.or_else(|| Self::dir_crt(env))
.or_else(|| dir_crt(env))
}
// Ref: https://github.com/rust-lang/cargo/blob/home-0.5.11/crates/home/src/windows.rs
@ -101,31 +73,14 @@ pub mod base_strategy {
fn dir_crt(_env: &'static str) -> Option<PathBuf> {
None
}
}
impl super::BaseStrategy for Windows {
fn cache_dir(&self) -> PathBuf {
Self::dir_inner("LOCALAPPDATA")
.unwrap_or_else(|| self.home_dir.join("AppData").join("Local"))
}
pub fn cache_dir(home_dir: &Path) -> PathBuf {
dir_inner("LOCALAPPDATA").unwrap_or_else(|| home_dir.join("AppData").join("Local"))
}
}
mod xdg {
use crate::error::Result;
use std::path::Path;
use std::path::PathBuf;
pub struct Xdg {
home_dir: PathBuf,
}
impl Xdg {
pub fn new() -> Result<Self> {
Ok(Self {
home_dir: crate::etcetera::home_dir()?,
})
}
use std::path::{Path, PathBuf};
fn env_var_or_none(env_var: &str) -> Option<PathBuf> {
std::env::var(env_var).ok().and_then(|path| {
@ -140,24 +95,11 @@ pub mod base_strategy {
})
}
fn env_var_or_default(&self, env_var: &str, default: impl AsRef<Path>) -> PathBuf {
Self::env_var_or_none(env_var).unwrap_or_else(|| self.home_dir.join(default))
}
fn env_var_or_default(home_dir: &Path, env_var: &str, default: impl AsRef<Path>) -> PathBuf {
env_var_or_none(env_var).unwrap_or_else(|| home_dir.join(default))
}
impl super::BaseStrategy for Xdg {
fn cache_dir(&self) -> PathBuf {
self.env_var_or_default("XDG_CACHE_HOME", ".cache/")
pub fn cache_dir(home_dir: &Path) -> PathBuf {
env_var_or_default(home_dir, "XDG_CACHE_HOME", ".cache/")
}
}
}
pub use windows::Windows;
pub use xdg::Xdg;
}
pub use base_strategy::{choose_base_strategy, BaseStrategy};
pub fn home_dir() -> Result<std::path::PathBuf> {
home::home_dir().ok_or(Error::HomeDir)
}