Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support state directory #1

Merged
merged 2 commits into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/app_strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ pub trait AppStrategy: Sized {
/// Gets the cache directory for your application.
fn cache_dir(&self) -> PathBuf;

/// Gets the state directory for your application.
/// State directory may not to exist for all platforms.
fn state_dir(&self) -> Option<PathBuf>;

/// Constructs a path inside your application’s configuration directory to which a path of your choice has been appended.
fn in_config_dir<P: AsRef<OsStr>>(&self, path: P) -> PathBuf {
in_dir_method!(self, path, config_dir)
Expand Down
8 changes: 8 additions & 0 deletions src/app_strategy/apple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ use std::path::PathBuf;
/// app_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new("Library/Caches/com.apple.Safari/")
/// ));
/// assert_eq!(
/// app_strategy.state_dir(),
/// None
/// );
/// ```
#[derive(Debug)]
pub struct Apple {
Expand Down Expand Up @@ -58,4 +62,8 @@ impl super::AppStrategy for Apple {
fn cache_dir(&self) -> PathBuf {
self.base_strategy.cache_dir().join(&self.bundle_id)
}

fn state_dir(&self) -> Option<PathBuf> {
None
}
}
8 changes: 8 additions & 0 deletions src/app_strategy/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ use std::path::PathBuf;
/// app_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new(".vim/cache/")
/// ));
/// assert_eq!(
/// app_strategy.state_dir().unwrap().strip_prefix(&home_dir),
/// Ok(Path::new(".vim/state/")
/// ));
/// ```
#[derive(Debug)]
pub struct Unix {
Expand Down Expand Up @@ -56,4 +60,8 @@ impl super::AppStrategy for Unix {
fn cache_dir(&self) -> PathBuf {
self.root_dir.join("cache/")
}

fn state_dir(&self) -> Option<PathBuf> {
Some(self.root_dir.join("state/"))
}
}
8 changes: 8 additions & 0 deletions src/app_strategy/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ use std::path::PathBuf;
/// app_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new("AppData/Local/Microsoft/File Explorer/cache"))
/// );
/// assert_eq!(
/// app_strategy.state_dir(),
/// None
/// );
/// ```
#[derive(Debug)]
pub struct Windows {
Expand Down Expand Up @@ -68,4 +72,8 @@ impl super::AppStrategy for Windows {
fn cache_dir(&self) -> PathBuf {
dir_method!(self, cache_dir, "cache/")
}

fn state_dir(&self) -> Option<PathBuf> {
None
}
}
26 changes: 26 additions & 0 deletions src/app_strategy/xdg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::path::PathBuf;
/// std::env::remove_var("XDG_CONFIG_HOME");
/// std::env::remove_var("XDG_DATA_HOME");
/// std::env::remove_var("XDG_CACHE_HOME");
/// std::env::remove_var("XDG_STATE_HOME");
///
/// let app_strategy = Xdg::new(AppStrategyArgs {
/// top_level_domain: "hm".to_string(),
Expand All @@ -37,6 +38,10 @@ use std::path::PathBuf;
/// app_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new(".cache/htop/")
/// ));
/// assert_eq!(
/// app_strategy.state_dir().unwrap().strip_prefix(&home_dir),
/// Ok(Path::new(".local/state/htop/")
/// ));
/// ```
///
/// This next example gives the environment variables values:
Expand All @@ -63,10 +68,16 @@ use std::path::PathBuf;
/// } else {
/// "/my_cache_location/"
/// };
/// let state_path = if cfg!(windows) {
/// "C:\\my_state_location\\"
/// } else {
/// "/my_state_location/"
/// };
///
/// std::env::set_var("XDG_CONFIG_HOME", config_path);
/// std::env::set_var("XDG_DATA_HOME", data_path);
/// std::env::set_var("XDG_CACHE_HOME", cache_path);
/// std::env::set_var("XDG_STATE_HOME", state_path);
///
/// let app_strategy = Xdg::new(AppStrategyArgs {
/// top_level_domain: "hm".to_string(),
Expand All @@ -77,6 +88,7 @@ use std::path::PathBuf;
/// assert_eq!(app_strategy.config_dir(), Path::new(&format!("{}/htop/", config_path)));
/// assert_eq!(app_strategy.data_dir(), Path::new(&format!("{}/htop/", data_path)));
/// assert_eq!(app_strategy.cache_dir(), Path::new(&format!("{}/htop/", cache_path)));
/// assert_eq!(app_strategy.state_dir().unwrap(), Path::new(&format!("{}/htop/", state_path)));
/// ```
///
/// The XDG spec requires that when the environment variables’ values are not absolute paths, their values should be ignored. This example exemplifies this behaviour:
Expand All @@ -91,6 +103,7 @@ use std::path::PathBuf;
/// std::env::set_var("XDG_CONFIG_HOME", "relative_path/");
/// std::env::set_var("XDG_DATA_HOME", "./another_one/");
/// std::env::set_var("XDG_CACHE_HOME", "yet_another/");
/// std::env::set_var("XDG_STATE_HOME", "./and_another");
///
/// let app_strategy = Xdg::new(AppStrategyArgs {
/// top_level_domain: "hm".to_string(),
Expand All @@ -113,6 +126,10 @@ use std::path::PathBuf;
/// app_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new(".cache/htop/")
/// ));
/// assert_eq!(
/// app_strategy.state_dir().unwrap().strip_prefix(&home_dir),
/// Ok(Path::new(".local/state/htop/")
/// ));
/// ```
#[derive(Debug)]
pub struct Xdg {
Expand Down Expand Up @@ -141,4 +158,13 @@ impl super::AppStrategy for Xdg {
fn cache_dir(&self) -> PathBuf {
self.base_strategy.cache_dir().join(&self.unixy_name)
}

fn state_dir(&self) -> Option<PathBuf> {
Some(
self.base_strategy
.state_dir()
.unwrap()
.join(&self.unixy_name),
)
}
}
4 changes: 4 additions & 0 deletions src/base_strategy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ pub trait BaseStrategy: Sized {

/// Gets the user’s cache directory.
fn cache_dir(&self) -> PathBuf;

/// Gets the user’s state directory.
/// State directory may not exist for all platforms.
fn state_dir(&self) -> Option<PathBuf>;
}

macro_rules! create_choose_base_strategy {
Expand Down
8 changes: 8 additions & 0 deletions src/base_strategy/apple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ use std::path::PathBuf;
/// base_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new("Library/Caches/")
/// ));
/// assert_eq!(
/// base_strategy.state_dir(),
/// None
/// );
/// ```
#[derive(Debug)]
pub struct Apple {
Expand Down Expand Up @@ -50,4 +54,8 @@ impl super::BaseStrategy for Apple {
fn cache_dir(&self) -> PathBuf {
self.library_path.join("Caches/")
}

fn state_dir(&self) -> Option<PathBuf> {
None
}
}
8 changes: 8 additions & 0 deletions src/base_strategy/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ use std::path::PathBuf;
/// base_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new("AppData/Local/"))
/// );
/// assert_eq!(
/// base_strategy.state_dir(),
/// None
/// );
/// ```
#[derive(Debug)]
pub struct Windows {
Expand All @@ -49,4 +53,8 @@ impl super::BaseStrategy for Windows {
fn cache_dir(&self) -> PathBuf {
self.appdata.join("Local/")
}

fn state_dir(&self) -> Option<PathBuf> {
None
}
}
21 changes: 21 additions & 0 deletions src/base_strategy/xdg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::path::PathBuf;
/// std::env::remove_var("XDG_CONFIG_HOME");
/// std::env::remove_var("XDG_DATA_HOME");
/// std::env::remove_var("XDG_CACHE_HOME");
/// std::env::remove_var("XDG_STATE_HOME");
///
/// let base_strategy = Xdg::new().unwrap();
///
Expand All @@ -30,6 +31,10 @@ use std::path::PathBuf;
/// base_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new(".cache/")
/// ));
/// assert_eq!(
/// base_strategy.state_dir().unwrap().strip_prefix(&home_dir),
/// Ok(Path::new(".local/state")
/// ));
/// ```
///
/// And here is another example with the environment variables set to demonstrate that the strategy really does read them:
Expand All @@ -55,16 +60,23 @@ use std::path::PathBuf;
/// } else {
/// "/baz/"
/// };
/// let state_path = if cfg!(windows) {
/// "C:\\foobar\\"
/// } else {
/// "/foobar/"
/// };
///
/// std::env::set_var("XDG_CONFIG_HOME", config_path);
/// std::env::set_var("XDG_DATA_HOME", data_path);
/// std::env::set_var("XDG_CACHE_HOME", cache_path);
/// std::env::set_var("XDG_STATE_HOME", state_path);
///
/// let base_strategy = Xdg::new().unwrap();
///
/// assert_eq!(base_strategy.config_dir(), Path::new(config_path));
/// assert_eq!(base_strategy.data_dir(), Path::new(data_path));
/// assert_eq!(base_strategy.cache_dir(), Path::new(cache_path));
/// assert_eq!(base_strategy.state_dir().unwrap(), Path::new(state_path));
/// ```
///
/// The specification states that:
Expand All @@ -81,6 +93,7 @@ use std::path::PathBuf;
/// std::env::set_var("XDG_CONFIG_HOME", "foo/");
/// std::env::set_var("XDG_DATA_HOME", "bar/");
/// std::env::set_var("XDG_CACHE_HOME", "baz/");
/// std::env::set_var("XDG_STATE_HOME", "foobar/");
///
/// let base_strategy = Xdg::new().unwrap();
///
Expand All @@ -98,6 +111,10 @@ use std::path::PathBuf;
/// base_strategy.cache_dir().strip_prefix(&home_dir),
/// Ok(Path::new(".cache/")
/// ));
/// assert_eq!(
/// base_strategy.state_dir().unwrap().strip_prefix(&home_dir),
/// Ok(Path::new(".local/state/")
/// ));
/// ```
#[derive(Debug)]
pub struct Xdg {
Expand Down Expand Up @@ -142,4 +159,8 @@ impl super::BaseStrategy for Xdg {
fn cache_dir(&self) -> PathBuf {
self.env_var_or_default("XDG_CACHE_HOME", ".cache/")
}

fn state_dir(&self) -> Option<PathBuf> {
Some(self.env_var_or_default("XDG_STATE_HOME", ".local/state/"))
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//! let config_dir = strategy.config_dir();
//! let data_dir = strategy.data_dir();
//! let cache_dir = strategy.cache_dir();
//! let state_dir = strategy.state_dir();
//! ```
//!
//! Here is an example where you provide Etcetera with some basic information about your application, and Etcetera will in turn give you a path that includes this information (this is called an ‘app strategy’).
Expand All @@ -33,6 +34,7 @@
//! let config_dir = strategy.config_dir();
//! let data_dir = strategy.data_dir();
//! let cache_dir = strategy.cache_dir();
//! let state_dir = strategy.state_dir();
//! ```
//!
//! Say you were a hardened Unix veteran, and didn’t want to have any of this XDG nonsense, clutter in the home directory be damned! Instead of using `choose_app_strategy` or `choose_base_strategy`, you can pick a strategy yourself. Here’s an example using the [`Unix`](app_strategy/struct.Unix.html) strategy – see its documentation to see what kind of folder structures it produces:
Expand Down