1mod proj_dirs;
2mod project_triplet;
3
4pub mod dir_utils;
6
7pub mod strategy;
9
10pub use proj_dirs::{FullProjectDirs, MissingError, ProjectDirs};
11
12pub struct Project {
14 _orig_qualifier: String,
16 _orig_organization: String,
18 _orig_application: String,
20
21 qualifier_value: String,
22 organization_name: String,
23 application_name: String,
24}
25
26#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord)]
28#[cfg_attr(feature = "strum", derive(strum::Display, strum::EnumString))]
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
30#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))]
31#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
32pub enum Directory {
33 Bin,
35 Cache,
37 Config,
39 Data,
41 Include,
43 Lib,
45 Log,
47 ProjectRoot,
49 Runtime,
51 State,
53}
54
55#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
57#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
58pub struct Scoped {
59 pub user: ProjectDirs,
60 pub system: ProjectDirs,
61 pub local: ProjectDirs,
62}
63
64impl Project {
65 pub fn new(qualifier: &str, organization: &str, application: &str) -> Self {
66 Self {
67 _orig_qualifier: qualifier.to_string(),
68 _orig_organization: organization.to_string(),
69 _orig_application: application.to_string(),
70 qualifier_value: project_triplet::qualifier_cleanup(qualifier),
71 organization_name: project_triplet::name_cleanup(organization),
72 application_name: project_triplet::name_cleanup(application),
73 }
74 }
75
76 pub fn application_name_unix(&self) -> String {
78 project_triplet::unix_name_cleanup(&self._orig_application)
79 }
80
81 pub fn application_name_windows(&self) -> String {
83 project_triplet::windows_name_cleanup(&self._orig_application)
84 }
85
86 pub fn application_name_macos(&self) -> String {
88 project_triplet::unix_name_cleanup(&self._orig_application)
89 }
90
91 pub fn organization_name_windows(&self) -> String {
93 project_triplet::windows_name_cleanup(&self._orig_organization)
94 }
95
96 pub fn organization_name(&self) -> &str {
98 &self.organization_name
99 }
100
101 pub fn application_name(&self) -> &str {
103 &self.application_name
104 }
105
106 pub fn qualifier(&self) -> &str {
108 &self.qualifier_value
109 }
110
111 #[cfg(all(target_family = "unix", not(target_os = "macos")))]
112 fn unix_project_dirs(&self) -> Scoped {
113 use crate::strategy::fhs::Fhs;
114 use crate::strategy::unix::Unix;
115 use crate::strategy::xdg::{Xdg, XdgEnv};
116
117 Scoped {
118 user: self
119 .xdg_with_env(XdgEnv::new_system())
120 .map(|x| x.into())
121 .unwrap_or(ProjectDirs::empty()),
122 system: self.fhs().into(),
123 local: self
124 .unix_pwd()
125 .map(Into::into)
126 .unwrap_or(ProjectDirs::empty()),
127 }
128 }
129
130 #[cfg(target_os = "windows")]
131 fn windows_project_dirs(&self) -> Scoped {
132 use crate::strategy::unix::Unix;
133
134 use crate::strategy::windows::{Windows, WindowsEnv};
135 let windows_env = WindowsEnv::new_system();
136 Scoped {
137 user: self.windows_user_with_env(windows_env.clone()),
138 system: self.windows_system_with_env(windows_env),
139 local: self
140 .unix_pwd()
141 .map(Into::into)
142 .unwrap_or(ProjectDirs::empty()),
143 }
144 }
145
146 pub fn project_dirs(&self) -> Scoped {
147 #[cfg(all(target_family = "unix", not(target_os = "macos")))]
148 {
149 self.unix_project_dirs()
150 }
151 #[cfg(all(target_family = "unix", target_os = "macos"))]
152 {
153 todo!()
154 }
155 #[cfg(target_family = "windows")]
156 {
157 self.windows_project_dirs()
158 }
159 }
160}