Skip to content

Commit

Permalink
Add support for XDG_STATE_HOME
Browse files Browse the repository at this point in the history
  • Loading branch information
soc committed Sep 15, 2021
1 parent 7614f41 commit cb6a274
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 5 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ If you want to compute the location of cache, config or data directories for you
| `executable_dir` | `Some($XDG_BIN_HOME`/../bin`)` or `Some($XDG_DATA_HOME`/../bin`)` or `Some($HOME`/.local/bin`)` | `None` | `None` |
| `preference_dir` | `$XDG_CONFIG_HOME` or `$HOME`/.config | `{FOLDERID_RoamingAppData}` | `$HOME`/Library/Preferences |
| `runtime_dir` | `Some($XDG_RUNTIME_DIR)` or `None` | `None` | `None` |
| `state_dir` | `Some($XDG_STATE_HOME)` or `Some($HOME`/.local/state`)` | `None` | `None` |

### `UserDirs`

Expand Down Expand Up @@ -147,7 +148,8 @@ which are derived from the standard directories.
| `data_dir` | `$XDG_DATA_HOME`/`<project_path>` or `$HOME`/.local/share/`<project_path>` | `{FOLDERID_RoamingAppData}`/`<project_path>`/data | `$HOME`/Library/Application Support/`<project_path>` |
| `data_local_dir` | `$XDG_DATA_HOME`/`<project_path>` or `$HOME`/.local/share/`<project_path>` | `{FOLDERID_LocalAppData}`/`<project_path>`/data | `$HOME`/Library/Application Support/`<project_path>` |
| `preference_dir` | `$XDG_CONFIG_HOME`/`<project_path>` or `$HOME`/.config/`<project_path>` | `{FOLDERID_RoamingAppData}`/`<project_path>`/config | `$HOME`/Library/Preferences/`<project_path>` |
| `runtime_dir` | `Some($XDG_RUNTIME_DIR`/`_project_path_)` | `None` | `None` |
| `runtime_dir` | `Some($XDG_RUNTIME_DIR`/`<project_path>)` | `None` | `None` |
| `state_dir` | `Some($XDG_STATE_HOME`/`<project_path>)` or `$HOME`/.local/state/`<project_path>` | `None` | `None` |

The specific value of `<project_path>` is computed by the

Expand Down Expand Up @@ -216,6 +218,10 @@ cargo build --target=x86_64-unknown-redox

## Changelog

### 4

- Add support for `XDG_STATE_HOME`.

### 3

- **BREAKING CHANGE** The behavior of the `BaseDirs::config_dir` and `ProjectDirs::config_dir`
Expand Down
36 changes: 35 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct BaseDirs {
executable_dir: Option<PathBuf>,
preference_dir: PathBuf,
runtime_dir: Option<PathBuf>,
state_dir: Option<PathBuf>
}

/// `UserDirs` provides paths of user-facing standard directories, following the conventions of the operating system the library is running on.
Expand Down Expand Up @@ -134,7 +135,8 @@ pub struct ProjectDirs {
data_dir: PathBuf,
data_local_dir: PathBuf,
preference_dir: PathBuf,
runtime_dir: Option<PathBuf>
runtime_dir: Option<PathBuf>,
state_dir: Option<PathBuf>
}

impl BaseDirs {
Expand Down Expand Up @@ -246,6 +248,22 @@ impl BaseDirs {
pub fn runtime_dir(&self) -> Option<&Path> {
self.runtime_dir.as_ref().map(|p| p.as_path())
}
/// Returns the path to the user's state directory.
///
/// The state directory contains data that should be retained between sessions (unlike the runtime
/// directory), but may not be important/portable enough to be synchronized across machines (unlike
/// the config/preferences/data directories).
///
/// The returned value depends on the operating system and is either a `Some`, containing a value from the following table, or a `None`.
///
/// |Platform | Value | Example |
/// | ------- | ----------------------------------------- | ------------------------ |
/// | Linux | `$XDG_STATE_HOME` or `$HOME`/.local/state | /home/alice/.local/state |
/// | macOS | – | – |
/// | Windows | – | – |
pub fn state_dir(&self) -> Option<&Path> {
self.state_dir.as_ref().map(|p| p.as_path())
}
}

impl UserDirs {
Expand Down Expand Up @@ -463,6 +481,22 @@ impl ProjectDirs {
pub fn runtime_dir(&self) -> Option<&Path> {
self.runtime_dir.as_ref().map(|p| p.as_path())
}
/// Returns the path to the project's state directory.
///
/// The state directory contains data that should be retained between sessions (unlike the runtime
/// directory), but may not be important/portable enough to be synchronized across machines (unlike
/// the config/preferences/data directories).
///
/// The returned value depends on the operating system and is either a `Some`, containing a value from the following table, or a `None`.
///
/// |Platform | Value | Example |
/// | ------- | --------------------------------------------------------------------------- | ------------------------------- |
/// | Linux | `$XDG_STATE_HOME`/`_project_path_` or `$HOME`/.local/state/`_project_path_` | /home/alice/.local/state/barapp |
/// | macOS | – | – |
/// | Windows | – | – |
pub fn state_dir(&self) -> Option<&Path> {
self.state_dir.as_ref().map(|p| p.as_path())
}
}

#[cfg(test)]
Expand Down
8 changes: 6 additions & 2 deletions src/lin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub fn base_dirs() -> Option<BaseDirs> {
let data_local_dir = data_dir.clone();
let preference_dir = config_dir.clone();
let runtime_dir = env::var_os("XDG_RUNTIME_DIR").and_then(dirs_sys::is_absolute_path);
let state_dir = env::var_os("XDG_STATE_HOME") .and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/state"));
let executable_dir =
env::var_os("XDG_BIN_HOME").and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| {
let mut new_dir = data_dir.clone(); new_dir.pop(); new_dir.push("bin"); new_dir });
Expand All @@ -27,7 +28,8 @@ pub fn base_dirs() -> Option<BaseDirs> {
data_local_dir: data_local_dir,
executable_dir: Some(executable_dir),
preference_dir: preference_dir,
runtime_dir: runtime_dir
runtime_dir: runtime_dir,
state_dir: Some(state_dir)
};
Some(base_dirs)
} else {
Expand Down Expand Up @@ -67,6 +69,7 @@ pub fn project_dirs_from_path(project_path: PathBuf) -> Option<ProjectDirs> {
let data_local_dir = data_dir.clone();
let preference_dir = config_dir.clone();
let runtime_dir = env::var_os("XDG_RUNTIME_DIR").and_then(dirs_sys::is_absolute_path).map(|o| o.join(&project_path));
let state_dir = env::var_os("XDG_STATE_HOME") .and_then(dirs_sys::is_absolute_path).unwrap_or_else(|| home_dir.join(".local/state")).join(&project_path);

let project_dirs = ProjectDirs {
project_path: project_path,
Expand All @@ -75,7 +78,8 @@ pub fn project_dirs_from_path(project_path: PathBuf) -> Option<ProjectDirs> {
data_dir: data_dir,
data_local_dir: data_local_dir,
preference_dir: preference_dir,
runtime_dir: runtime_dir
runtime_dir: runtime_dir,
state_dir: Some(state_dir)
};
Some(project_dirs)
} else {
Expand Down
1 change: 1 addition & 0 deletions src/mac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub fn project_dirs_from_path(project_path: PathBuf) -> Option<ProjectDirs> {
data_local_dir: data_local_dir,
preference_dir: preference_dir,
runtime_dir: None,
state_dir: None
};
Some(project_dirs)
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/win.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ pub fn project_dirs_from_path(project_path: PathBuf) -> Option<ProjectDirs> {
data_dir: data_dir,
data_local_dir: data_local_dir,
preference_dir: preference_dir,
runtime_dir: None
runtime_dir: None,
state_dir: None
};
Some(project_dirs)
} else {
Expand Down

0 comments on commit cb6a274

Please sign in to comment.