1use std::path::{Path, PathBuf};
2
3use serde_repr::{Deserialize_repr, Serialize_repr};
4
5#[derive(Serialize_repr, Deserialize_repr, Clone, Debug)]
11#[repr(u16)]
12pub enum BaseDirectory {
13 Audio = 1,
15 Cache,
17 Config,
19 Data,
21 LocalData,
23 Desktop,
25 Document,
27 Download,
29 Executable,
31 Font,
33 Home,
35 Picture,
37 Public,
39 Runtime,
41 Template,
43 Video,
45 Resource,
47 App,
50}
51
52pub fn resolve_path<P: AsRef<Path>>(path: P, dir: Option<BaseDirectory>) -> crate::Result<PathBuf> {
62 if let Some(base_dir) = dir {
63 let base_dir_path = match base_dir {
64 BaseDirectory::Audio => audio_dir(),
65 BaseDirectory::Cache => cache_dir(),
66 BaseDirectory::Config => config_dir(),
67 BaseDirectory::Data => data_dir(),
68 BaseDirectory::LocalData => local_data_dir(),
69 BaseDirectory::Desktop => desktop_dir(),
70 BaseDirectory::Document => document_dir(),
71 BaseDirectory::Download => download_dir(),
72 BaseDirectory::Executable => executable_dir(),
73 BaseDirectory::Font => font_dir(),
74 BaseDirectory::Home => home_dir(),
75 BaseDirectory::Picture => picture_dir(),
76 BaseDirectory::Public => public_dir(),
77 BaseDirectory::Runtime => runtime_dir(),
78 BaseDirectory::Template => template_dir(),
79 BaseDirectory::Video => video_dir(),
80 BaseDirectory::Resource => resource_dir(),
81 BaseDirectory::App => app_dir(),
82 };
83 if let Some(mut base_dir_path_value) = base_dir_path {
84 base_dir_path_value.push(path);
85 Ok(base_dir_path_value)
86 } else {
87 Err(crate::Error::Path("unable to determine base dir path".to_string()).into())
88 }
89 } else {
90 let mut dir_path = PathBuf::new();
91 dir_path.push(path);
92 Ok(dir_path)
93 }
94}
95
96pub fn audio_dir() -> Option<PathBuf> {
98 dirs_next::audio_dir()
99}
100
101pub fn cache_dir() -> Option<PathBuf> {
103 dirs_next::cache_dir()
104}
105
106pub fn config_dir() -> Option<PathBuf> {
108 dirs_next::config_dir()
109}
110
111pub fn data_dir() -> Option<PathBuf> {
113 dirs_next::data_dir()
114}
115
116pub fn local_data_dir() -> Option<PathBuf> {
118 dirs_next::data_local_dir()
119}
120
121pub fn desktop_dir() -> Option<PathBuf> {
123 dirs_next::desktop_dir()
124}
125
126pub fn document_dir() -> Option<PathBuf> {
128 dirs_next::document_dir()
129}
130
131pub fn download_dir() -> Option<PathBuf> {
133 dirs_next::download_dir()
134}
135
136pub fn executable_dir() -> Option<PathBuf> {
138 dirs_next::executable_dir()
139}
140
141pub fn font_dir() -> Option<PathBuf> {
143 dirs_next::font_dir()
144}
145
146pub fn home_dir() -> Option<PathBuf> {
148 dirs_next::home_dir()
149}
150
151pub fn picture_dir() -> Option<PathBuf> {
153 dirs_next::picture_dir()
154}
155
156pub fn public_dir() -> Option<PathBuf> {
158 dirs_next::public_dir()
159}
160
161pub fn runtime_dir() -> Option<PathBuf> {
163 dirs_next::runtime_dir()
164}
165
166pub fn template_dir() -> Option<PathBuf> {
168 dirs_next::template_dir()
169}
170
171pub fn video_dir() -> Option<PathBuf> {
173 dirs_next::video_dir()
174}
175
176pub fn resource_dir() -> Option<PathBuf> {
178 crate::platform::resource_dir().ok()
179}
180
181fn app_name() -> crate::Result<String> {
182 let exe = std::env::current_exe()?;
183 let app_name = exe
184 .file_name()
185 .expect("failed to get exe filename")
186 .to_string_lossy();
187
188 Ok(app_name.to_string())
189}
190
191pub fn app_dir() -> Option<PathBuf> {
193 dirs_next::config_dir().and_then(|mut dir| {
194 if let Ok(app_name) = app_name() {
195 dir.push(app_name);
196 Some(dir)
197 } else {
198 None
199 }
200 })
201}