platform_path/platform/path/
base.rs

1use crate::{Error, Result};
2use camino::Utf8PathBuf;
3use directories::BaseDirs;
4use std::path::PathBuf;
5use structopt::StructOpt;
6use strum::{Display, EnumIter, EnumProperty, EnumString};
7
8#[derive(Debug, PartialEq, Eq, Hash, Display, StructOpt, EnumString, EnumIter, EnumProperty)]
9#[cfg_attr(
10  feature = "serde1",
11  derive(serde::Serialize, serde::Deserialize),
12  serde(rename_all = "kebab-case")
13)]
14#[strum(serialize_all = "kebab-case")]
15#[structopt(
16  rename_all = "kebab-case",
17  about = "user-invisible standard directories"
18)]
19pub enum Base {
20  #[structopt(about = "the user's cache directory")]
21  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
22  Cache,
23  #[structopt(about = "the user's config directory")]
24  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
25  Config,
26  #[structopt(about = "the user's data directory")]
27  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
28  Data,
29  #[structopt(about = "the user's local data directory")]
30  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
31  DataLocal,
32  #[structopt(about = "the user's executable directory")]
33  #[strum(props(linux = "supported", macos = "unsupported", windows = "unsupported"))]
34  Executable,
35  #[structopt(about = "the user's home directory")]
36  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
37  Home,
38  #[structopt(about = "the user's preference directory")]
39  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
40  Preference,
41  #[structopt(about = "the user's runtime directory")]
42  #[strum(props(linux = "supported", macos = "unsupported", windows = "unsupported"))]
43  Runtime,
44  #[structopt(about = "the user's state directory")]
45  #[strum(props(linux = "supported", macos = "unsupported", windows = "unsupported"))]
46  State,
47}
48
49impl Base {
50  pub fn dirs() -> Result<BaseDirs> {
51    BaseDirs::new().ok_or(Error::InvalidHomeDirectory)
52  }
53
54  pub(crate) fn path_buf(&self) -> Result<PathBuf> {
55    Self::dirs().and_then(|base| {
56      match self {
57        Self::Cache => Some(base.cache_dir()),
58        Self::Config => Some(base.config_dir()),
59        Self::Data => Some(base.data_dir()),
60        Self::DataLocal => Some(base.data_local_dir()),
61        Self::Executable => base.executable_dir(),
62        Self::Home => Some(base.home_dir()),
63        Self::Preference => Some(base.preference_dir()),
64        Self::Runtime => base.runtime_dir(),
65        Self::State => base.state_dir(),
66      }
67      .ok_or(Error::NotDefinedByPlatformStandard)
68      .map(|path| path.to_path_buf())
69    })
70  }
71
72  pub fn utf8_path_buf(&self) -> Result<Utf8PathBuf> {
73    self
74      .path_buf()
75      .and_then(|path| Ok(Utf8PathBuf::try_from(path)?))
76  }
77}