platform_path/platform/path/
user.rs

1use crate::{Error, Result};
2use camino::Utf8PathBuf;
3use directories::UserDirs;
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(rename_all = "kebab-case", about = "user-facing standard directories")]
16pub enum User {
17  #[structopt(about = "the user's audio directory")]
18  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
19  Audio,
20  #[structopt(about = "the user's desktop directory")]
21  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
22  Desktop,
23  #[structopt(about = "the user's document directory")]
24  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
25  Document,
26  #[structopt(about = "the user's download directory")]
27  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
28  Download,
29  #[structopt(about = "the user's font directory")]
30  #[strum(props(linux = "supported", macos = "supported", windows = "unsupported"))]
31  Font,
32  #[structopt(about = "the user's home directory")]
33  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
34  Home,
35  #[structopt(about = "the user's picture directory")]
36  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
37  Picture,
38  #[structopt(about = "the user's public directory")]
39  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
40  Public,
41  #[structopt(about = "the user's template directory")]
42  #[strum(props(linux = "supported", macos = "unsupported", windows = "supported"))]
43  Template,
44  #[structopt(about = "the user's video directory")]
45  #[strum(props(linux = "supported", macos = "supported", windows = "supported"))]
46  Video,
47}
48
49impl User {
50  pub fn dirs() -> Result<UserDirs> {
51    UserDirs::new().ok_or(Error::InvalidHomeDirectory)
52  }
53
54  pub(crate) fn path_buf(&self) -> Result<PathBuf> {
55    Self::dirs().and_then(|user| {
56      match self {
57        Self::Audio => user.audio_dir(),
58        Self::Desktop => user.desktop_dir(),
59        Self::Document => user.document_dir(),
60        Self::Download => user.download_dir(),
61        Self::Font => user.font_dir(),
62        Self::Home => Some(user.home_dir()),
63        Self::Picture => user.picture_dir(),
64        Self::Public => user.public_dir(),
65        Self::Template => user.template_dir(),
66        Self::Video => user.video_dir(),
67      }
68      .ok_or(Error::NotDefinedByPlatformStandard)
69      .map(|path| path.to_path_buf())
70    })
71  }
72
73  pub fn utf8_path_buf(&self) -> Result<Utf8PathBuf> {
74    self
75      .path_buf()
76      .and_then(|path| Ok(Utf8PathBuf::try_from(path)?))
77  }
78}