std/fs/dirs.rs
1use crate::path::{Path, PathBuf};
2use crate::sys::fs::{ExtraHomeDirs, ExtraMediaDirs};
3
4/// Common user directory paths used for user-specific application files.
5///
6/// It is not required that the user directories are accessible by the current
7/// user, nor that there is a directory at that path. A robust application
8/// should handle the case where user directories are incorrectly configured.
9///
10/// Even when configured correctly, multiple paths may point to the same location.
11/// You should not assume that a file written relative to one directory will not
12/// conflict with the same relative path in a different home directory.
13///
14/// # Platform-specific behavior
15///
16/// As the filesystem conventions for discovering directories varies between
17/// operating systems, constructors for `HomeDirs` that use the host platform's
18/// conventions are provided as extension traits under the `std::os` module.
19#[unstable(feature = "fs_home_dirs", issue = "162082")]
20#[derive(Debug, Clone)]
21pub struct HomeDirs {
22 pub(crate) cache: Option<PathBuf>,
23 pub(crate) config: Option<PathBuf>,
24 pub(crate) data: Option<PathBuf>,
25 pub(crate) state: Option<PathBuf>,
26 #[cfg_attr(not(unix), expect(dead_code, reason = "no extra home dirs"))]
27 pub(crate) extra: ExtraHomeDirs,
28}
29
30/// Common user directory paths used for user-specific media files.
31///
32/// It is not required that the media directories are accessible by the current
33/// user, nor that there is a directory at that path. A robust application
34/// should handle the case where media directories are incorrectly configured.
35///
36/// Even when configured correctly, multiple paths may point to the same location.
37/// You should not assume that a file written relative to one directory will not
38/// conflict with the same relative path in a different media directory.
39///
40/// # Platform-specific behavior
41///
42/// As the filesystem conventions for discovering directories varies between
43/// operating systems, constructors for `MediaDirs` that use the host platform's
44/// conventions are provided as extension traits under the `std::os` module.
45#[unstable(feature = "fs_media_dirs", issue = "162083")]
46#[derive(Debug, Clone)]
47pub struct MediaDirs {
48 pub(crate) desktop: Option<PathBuf>,
49 pub(crate) documents: Option<PathBuf>,
50 pub(crate) downloads: Option<PathBuf>,
51 pub(crate) music: Option<PathBuf>,
52 pub(crate) pictures: Option<PathBuf>,
53 pub(crate) videos: Option<PathBuf>,
54 #[cfg_attr(not(unix), expect(dead_code, reason = "no extra media dirs"))]
55 pub(crate) extra: ExtraMediaDirs,
56}
57
58// NB: HomeDirs and MediaDirs intentionally do not implement Default. Self::empty()
59// is a logical default, but users may also intuit the default to use default
60// platform conventions. Omitting Default pushes users to explicitly choose.
61
62impl HomeDirs {
63 /// Create a known user directory set with no known directories.
64 ///
65 /// This is useful with the builder `set_*` methods to create a `HomeDirs`
66 /// with exactly the directories you want, without any other defaults.
67 #[unstable(feature = "fs_home_dirs", issue = "162082")]
68 pub fn empty() -> Self {
69 Self { cache: None, config: None, data: None, state: None, extra: Default::default() }
70 }
71
72 /// A base directory relative to which user-specific non-essential cache
73 /// data files should be stored.
74 ///
75 /// "Cache" files are temporary data that can be used to cache redundant
76 /// work of an application, but which can be discarded arbitrarily and
77 /// recreated as necessary. Files in this directory may potentially be
78 /// automatically purged any time they are not currently open, or they
79 /// may not, depending on system configuration. A robust application
80 /// should ensure that its caches do not grow without a reasonable bound.
81 ///
82 /// This is the same directory for all applications. Applications should
83 /// use a subdirectory for application-specific cache files.
84 ///
85 /// # Platform-specific behavior
86 ///
87 /// When constructed using platform-specific conventions, the value is:
88 ///
89 /// | OS | Path |
90 /// | -- | ---- |
91 /// | [XDG] (Linux) | `${XDG_CACHE_HOME:-$HOME/.cache}` |
92 /// | [Darwin] (macOS) | [`NSCachesDirectory`] (`$HOME/Library/Caches`) |
93 /// | [Windows] | [`{FOLDERID_LocalAppData}`] (`%LOCALAPPDATA%`) |
94 ///
95 /// Other paths can be configured via [`set_cache_home`](Self::set_cache_home).
96 ///
97 /// [XDG]: crate::os::unix::fs::HomeDirsExt
98 /// [Darwin]: crate::os::darwin::fs::HomeDirsExt
99 /// [Windows]: crate::os::windows::fs::HomeDirsExt
100 /// [`NSCachesDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/cachesdirectory?language=objc
101 /// [`{FOLDERID_LocalAppData}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_localappdata
102 #[unstable(feature = "fs_home_dirs", issue = "162082")]
103 pub fn cache_home(&self) -> Option<&Path> {
104 self.cache.as_deref()
105 }
106
107 /// A base directory relative to which user-specific configuration files
108 /// should be stored.
109 ///
110 /// "Config" files are configuration managed by the user, either by editing
111 /// the files directly or through a managing application. Configuration is
112 /// generally expected to be meaningful to the user and portable enough to
113 /// back up and synchronize across the same user's account on multiple
114 /// systems.
115 ///
116 /// This is the same directory for all applications. Applications should
117 /// use a subdirectory for application-specific configuration files.
118 ///
119 /// # Platform-specific behavior
120 ///
121 /// When constructed using platform-specific conventions, the value is:
122 ///
123 /// | OS | Path |
124 /// | -- | ---- |
125 /// | [XDG] (Linux) | `${XDG_CONFIG_HOME:-$HOME/.config}` |
126 /// | [Darwin] (macOS) | [`NSApplicationSupportDirectory`] (`$HOME/Library/Application Support`) |
127 /// | [Windows] | [`{FOLDERID_RoamingAppData}`] (`%APPDATA%`) |
128 ///
129 /// Other paths can be configured via [`set_config_home`](Self::set_config_home).
130 ///
131 /// [XDG]: crate::os::unix::fs::HomeDirsExt
132 /// [Darwin]: crate::os::darwin::fs::HomeDirsExt
133 /// [Windows]: crate::os::windows::fs::HomeDirsExt
134 /// [`NSApplicationSupportDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/applicationsupportdirectory?language=objc
135 /// [`{FOLDERID_RoamingAppData}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_roamingappdata
136 #[unstable(feature = "fs_home_dirs", issue = "162082")]
137 pub fn config_home(&self) -> Option<&Path> {
138 self.config.as_deref()
139 }
140
141 /// A base directory relative to which user-specific data files should be
142 /// stored.
143 ///
144 /// "Data" files are application-specific data that is meaningful to the
145 /// user in some way and does not implicitly rely on system configuration
146 /// or details of how the application is installed otherwise irrelevant to
147 /// the user. As such, data makes sense to back up and synchronize between
148 /// the same user's account on multiple systems. If a file is specific to
149 /// a single machine, it's probably [state](Self::state_home).
150 ///
151 /// This is the same directory for all applications. Applications should
152 /// use a subdirectory for application-specific data files.
153 ///
154 /// # Platform-specific behavior
155 ///
156 /// When constructed using platform-specific conventions, the value is:
157 ///
158 /// | OS | Path |
159 /// | -- | ---- |
160 /// | [XDG] (Linux) | `${XDG_DATA_HOME:-$HOME/.local/share}` |
161 /// | [Darwin] (macOS) | [`NSApplicationSupportDirectory`] (`$HOME/Library/Application Support`) |
162 /// | [Windows] | [`{FOLDERID_RoamingAppData}`] (`%APPDATA%`) |
163 ///
164 /// Other paths can be configured via [`set_data_home`](Self::set_data_home).
165 ///
166 /// [XDG]: crate::os::unix::fs::HomeDirsExt
167 /// [Darwin]: crate::os::darwin::fs::HomeDirsExt
168 /// [Windows]: crate::os::windows::fs::HomeDirsExt
169 /// [`NSApplicationSupportDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/applicationsupportdirectory?language=objc
170 /// [`{FOLDERID_RoamingAppData}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_roamingappdata
171 #[unstable(feature = "fs_home_dirs", issue = "162082")]
172 pub fn data_home(&self) -> Option<&Path> {
173 self.data.as_deref()
174 }
175
176 /// A base directory relative to which user-specific state files should be
177 /// stored.
178 ///
179 /// "State" files are data that should persist between application restarts,
180 /// but which is not important nor portable enough to the user to synchronize
181 /// between multiple systems like [data](Self::data_home) are. Common examples
182 /// include history (such as logs, recently used files, etc) and any current
183 /// state of the application that should be reused (such as view, layout, open
184 /// files, undo history, etc).
185 ///
186 /// This is the same directory for all applications. Applications should
187 /// use a subdirectory for application-specific state files.
188 ///
189 /// # Platform-specific behavior
190 ///
191 /// When constructed using platform-specific conventions, the value is:
192 ///
193 /// | OS | Path |
194 /// | -- | ---- |
195 /// | [XDG] (Linux) | `${XDG_STATE_HOME:-$HOME/.local/state}` |
196 /// | [Darwin] (macOS) | [`NSApplicationSupportDirectory`] (`$HOME/Library/Application Support`) |
197 /// | [Windows] | [`{FOLDERID_LocalAppData}`] (`%LOCALAPPDATA%`) |
198 ///
199 /// Other paths can be configured via [`set_state_home`](Self::set_state_home).
200 ///
201 /// [XDG]: crate::os::unix::fs::HomeDirsExt
202 /// [Darwin]: crate::os::darwin::fs::HomeDirsExt
203 /// [Windows]: crate::os::windows::fs::HomeDirsExt
204 /// [`NSApplicationSupportDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/applicationsupportdirectory?language=objc
205 /// [`{FOLDERID_LocalAppData}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_localappdata
206 #[unstable(feature = "fs_home_dirs", issue = "162082")]
207 pub fn state_home(&self) -> Option<&Path> {
208 self.state.as_deref()
209 }
210}
211
212impl MediaDirs {
213 /// Create a known user directory set with no known directories.
214 ///
215 /// This is useful with the builder `set_*` methods to create a `MediaDirs`
216 /// with exactly the directories you want, without any other defaults.
217 #[unstable(feature = "fs_media_dirs", issue = "162083")]
218 pub fn empty() -> Self {
219 Self {
220 desktop: None,
221 documents: None,
222 downloads: None,
223 music: None,
224 pictures: None,
225 videos: None,
226 extra: Default::default(),
227 }
228 }
229
230 /// The OS-recognized user "Desktop" directory, often the `Desktop`
231 /// folder in the user's home directory.
232 ///
233 /// As a media directory, this should typically be used as a default path
234 /// for file selection dialogs, not for automatically accessed file paths.
235 ///
236 /// # Platform-specific behavior
237 ///
238 /// When constructed using platform-specific conventions, the value is:
239 ///
240 /// | OS | Path |
241 /// | -- | ---- |
242 /// | [XDG] (Linux) | `xdg-user-dir DESKTOP` (`$HOME/Desktop`) |
243 /// | [Darwin] (macOS) | [`NSDesktopDirectory`] (`$HOME/Desktop`) |
244 /// | [Windows] | [`{FOLDERID_Desktop}`] (`%USERPROFILE%\Desktop`) |
245 ///
246 /// Other paths can be configured via [`set_desktop`](Self::set_desktop).
247 ///
248 /// [XDG]: crate::os::unix::fs::MediaDirsExt
249 /// [Darwin]: crate::os::darwin::fs::MediaDirsExt
250 /// [Windows]: crate::os::windows::fs::MediaDirsExt
251 /// [`NSDesktopDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/desktopdirectory?language=objc
252 /// [`{FOLDERID_Desktop}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_desktop
253 #[unstable(feature = "fs_media_dirs", issue = "162083")]
254 pub fn desktop(&self) -> Option<&Path> {
255 self.desktop.as_deref()
256 }
257
258 /// The OS-recognized user "Documents" directory, often the `Documents`
259 /// folder in the user's home directory.
260 ///
261 /// As a media directory, this should typically be used as a default path
262 /// for file selection dialogs, not for automatically accessed file paths.
263 ///
264 /// # Platform-specific behavior
265 ///
266 /// When constructed using platform-specific conventions, the value is:
267 ///
268 /// | OS | Path |
269 /// | -- | ---- |
270 /// | [XDG] (Linux) | `xdg-user-dir DOCUMENTS` (`$HOME/Documents`) |
271 /// | [Darwin] (macOS) | [`NSDocumentDirectory`] (`$HOME/Documents`) |
272 /// | [Windows] | [`{FOLDERID_Documents}`] (`%USERPROFILE%\Documents`) |
273 ///
274 /// Other paths can be configured via [`set_documents`](Self::set_documents).
275 ///
276 /// [XDG]: crate::os::unix::fs::MediaDirsExt
277 /// [Darwin]: crate::os::darwin::fs::MediaDirsExt
278 /// [Windows]: crate::os::windows::fs::MediaDirsExt
279 /// [`NSDocumentDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/documentdirectory?language=objc
280 /// [`{FOLDERID_Documents}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_documents
281 #[unstable(feature = "fs_media_dirs", issue = "162083")]
282 pub fn documents(&self) -> Option<&Path> {
283 self.documents.as_deref()
284 }
285
286 /// The OS-recognized user "Downloads" directory, often the `Downloads`
287 /// folder in the user's home directory.
288 ///
289 /// As a media directory, this should typically be used as a default path
290 /// for file selection dialogs, not for automatically accessed file paths.
291 ///
292 /// # Platform-specific behavior
293 ///
294 /// When constructed using platform-specific conventions, the value is:
295 ///
296 /// | OS | Path |
297 /// | -- | ---- |
298 /// | [XDG] (Linux) | `xdg-user-dir DOWNLOAD` (`$HOME/Downloads`) |
299 /// | [Darwin] (macOS) | [`NSDownloadsDirectory`] (`$HOME/Downloads`) |
300 /// | [Windows] | [`{FOLDERID_Downloads}`] (`%USERPROFILE%\Downloads`) |
301 ///
302 /// Other paths can be configured via [`set_downloads`](Self::set_downloads).
303 ///
304 /// [XDG]: crate::os::unix::fs::MediaDirsExt
305 /// [Darwin]: crate::os::darwin::fs::MediaDirsExt
306 /// [Windows]: crate::os::windows::fs::MediaDirsExt
307 /// [`NSDownloadsDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/downloadsdirectory?language=objc
308 /// [`{FOLDERID_Downloads}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_downloads
309 #[unstable(feature = "fs_media_dirs", issue = "162083")]
310 pub fn downloads(&self) -> Option<&Path> {
311 self.downloads.as_deref()
312 }
313
314 /// The OS-recognized user "Music" directory, often the `Music`
315 /// folder in the user's home directory.
316 ///
317 /// As a media directory, this should typically be used as a default path
318 /// for file selection dialogs, not for automatically accessed file paths.
319 ///
320 /// # Platform-specific behavior
321 ///
322 /// When constructed using platform-specific conventions, the value is:
323 ///
324 /// | OS | Path |
325 /// | -- | ---- |
326 /// | [XDG] (Linux) | `xdg-user-dir MUSIC` (`$HOME/Music`) |
327 /// | [Darwin] (macOS) | [`NSMusicDirectory`] (`$HOME/Music`) |
328 /// | [Windows] | [`{FOLDERID_Music}`] (`%USERPROFILE%\Music`) |
329 ///
330 /// Other paths can be configured via [`set_music`](Self::set_music).
331 ///
332 /// [XDG]: crate::os::unix::fs::MediaDirsExt
333 /// [Darwin]: crate::os::darwin::fs::MediaDirsExt
334 /// [Windows]: crate::os::windows::fs::MediaDirsExt
335 /// [`NSMusicDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/musicdirectory?language=objc
336 /// [`{FOLDERID_Music}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_music
337 #[unstable(feature = "fs_media_dirs", issue = "162083")]
338 pub fn music(&self) -> Option<&Path> {
339 self.music.as_deref()
340 }
341
342 /// The OS-recognized user "Pictures" directory, often the `Pictures`
343 /// folder in the user's home directory.
344 ///
345 /// As a media directory, this should typically be used as a default path
346 /// for file selection dialogs, not for automatically accessed file paths.
347 ///
348 /// # Platform-specific behavior
349 ///
350 /// When constructed using platform-specific conventions, the value is:
351 ///
352 /// | OS | Path |
353 /// | -- | ---- |
354 /// | [XDG] (Linux) | `xdg-user-dir PICTURES` (`$HOME/Pictures`) |
355 /// | [Darwin] (macOS) | [`NSPicturesDirectory`] (`$HOME/Pictures`) |
356 /// | [Windows] | [`{FOLDERID_Pictures}`] (`%USERPROFILE%\Pictures`) |
357 ///
358 /// Other paths can be configured via [`set_pictures`](Self::set_pictures).
359 ///
360 /// [XDG]: crate::os::unix::fs::MediaDirsExt
361 /// [Darwin]: crate::os::darwin::fs::MediaDirsExt
362 /// [Windows]: crate::os::windows::fs::MediaDirsExt
363 /// [`NSPicturesDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/picturesdirectory?language=objc
364 /// [`{FOLDERID_Pictures}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_pictures
365 #[unstable(feature = "fs_media_dirs", issue = "162083")]
366 pub fn pictures(&self) -> Option<&Path> {
367 self.pictures.as_deref()
368 }
369
370 /// The OS-recognized user "Videos" directory, often the `Videos`
371 /// folder in the user's home directory.
372 ///
373 /// As a media directory, this should typically be used as a default path
374 /// for file selection dialogs, not for automatically accessed file paths.
375 ///
376 /// # Platform-specific behavior
377 ///
378 /// When constructed using platform-specific conventions, the value is:
379 ///
380 /// | OS | Path |
381 /// | -- | ---- |
382 /// | [XDG] (Linux) | `xdg-user-dir VIDEOS` (`$HOME/Videos`) |
383 /// | [Darwin] (macOS) | [`NSMoviesDirectory`] (`$HOME/Movies`) |
384 /// | [Windows] | [`{FOLDERID_Videos}`] (`%USERPROFILE%\Videos`) |
385 ///
386 /// Other paths can be configured via [`set_videos`](Self::set_videos).
387 ///
388 /// [XDG]: crate::os::unix::fs::MediaDirsExt
389 /// [Darwin]: crate::os::darwin::fs::MediaDirsExt
390 /// [Windows]: crate::os::windows::fs::MediaDirsExt
391 /// [`NSMoviesDirectory`]: https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/moviesdirectory?language=objc
392 /// [`{FOLDERID_Videos}`]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#folderid_videos
393 #[unstable(feature = "fs_media_dirs", issue = "162083")]
394 pub fn videos(&self) -> Option<&Path> {
395 self.videos.as_deref()
396 }
397}
398
399impl HomeDirs {
400 /// Set the path for [Self::cache_home].
401 ///
402 /// # Panics
403 ///
404 /// Panics if the provided path is not absolute.
405 #[unstable(feature = "fs_home_dirs", issue = "162082")]
406 pub fn set_cache_home(&mut self, path: PathBuf) -> &mut Self {
407 assert!(path.is_absolute(), "cache home directory path must be absolute");
408 self.cache = Some(path);
409 self
410 }
411
412 /// Set the path for [Self::config_home].
413 ///
414 /// # Panics
415 ///
416 /// Panics if the provided path is not absolute.
417 #[unstable(feature = "fs_home_dirs", issue = "162082")]
418 pub fn set_config_home(&mut self, path: PathBuf) -> &mut Self {
419 assert!(path.is_absolute(), "config home directory path must be absolute");
420 self.config = Some(path);
421 self
422 }
423
424 /// Set the path for [Self::data_home].
425 ///
426 /// # Panics
427 ///
428 /// Panics if the provided path is not absolute.
429 #[unstable(feature = "fs_home_dirs", issue = "162082")]
430 pub fn set_data_home(&mut self, path: PathBuf) -> &mut Self {
431 assert!(path.is_absolute(), "data home directory path must be absolute");
432 self.data = Some(path);
433 self
434 }
435
436 /// Set the path for [Self::state_home].
437 ///
438 /// # Panics
439 ///
440 /// Panics if the provided path is not absolute.
441 #[unstable(feature = "fs_home_dirs", issue = "162082")]
442 pub fn set_state_home(&mut self, path: PathBuf) -> &mut Self {
443 assert!(path.is_absolute(), "state home directory path must be absolute");
444 self.state = Some(path);
445 self
446 }
447}
448
449impl MediaDirs {
450 /// Set the path for [Self::desktop].
451 ///
452 /// # Panics
453 ///
454 /// Panics if the provided path is not absolute.
455 #[unstable(feature = "fs_media_dirs", issue = "162083")]
456 pub fn set_desktop(&mut self, path: PathBuf) -> &mut Self {
457 assert!(path.is_absolute(), "desktop directory path must be absolute");
458 self.desktop = Some(path);
459 self
460 }
461
462 /// Set the path for [Self::documents].
463 ///
464 /// # Panics
465 ///
466 /// Panics if the provided path is not absolute.
467 #[unstable(feature = "fs_media_dirs", issue = "162083")]
468 pub fn set_documents(&mut self, path: PathBuf) -> &mut Self {
469 assert!(path.is_absolute(), "documents directory path must be absolute");
470 self.documents = Some(path);
471 self
472 }
473
474 /// Set the path for [Self::downloads].
475 ///
476 /// # Panics
477 ///
478 /// Panics if the provided path is not absolute.
479 #[unstable(feature = "fs_media_dirs", issue = "162083")]
480 pub fn set_downloads(&mut self, path: PathBuf) -> &mut Self {
481 assert!(path.is_absolute(), "downloads directory path must be absolute");
482 self.downloads = Some(path);
483 self
484 }
485
486 /// Set the path for [Self::music].
487 ///
488 /// # Panics
489 ///
490 /// Panics if the provided path is not absolute.
491 #[unstable(feature = "fs_media_dirs", issue = "162083")]
492 pub fn set_music(&mut self, path: PathBuf) -> &mut Self {
493 assert!(path.is_absolute(), "music directory path must be absolute");
494 self.music = Some(path);
495 self
496 }
497
498 /// Set the path for [Self::pictures].
499 ///
500 /// # Panics
501 ///
502 /// Panics if the provided path is not absolute.
503 #[unstable(feature = "fs_media_dirs", issue = "162083")]
504 pub fn set_pictures(&mut self, path: PathBuf) -> &mut Self {
505 assert!(path.is_absolute(), "pictures directory path must be absolute");
506 self.pictures = Some(path);
507 self
508 }
509
510 /// Set the path for [Self::videos].
511 ///
512 /// # Panics
513 ///
514 /// Panics if the provided path is not absolute.
515 #[unstable(feature = "fs_media_dirs", issue = "162083")]
516 pub fn set_videos(&mut self, path: PathBuf) -> &mut Self {
517 assert!(path.is_absolute(), "videos directory path must be absolute");
518 self.videos = Some(path);
519 self
520 }
521}
522
523#[cfg(test)]
524mod tests {
525 use super::*;
526
527 fn test_dir(what: &str) -> PathBuf {
528 crate::env::current_dir().unwrap().ancestors().last().unwrap().join(what)
529 }
530
531 #[test]
532 fn test_home_dirs_field_hookup_matches() {
533 let mut dirs = HomeDirs::empty();
534
535 assert_eq!(dirs.config_home(), None);
536 assert_eq!(dirs.data_home(), None);
537 assert_eq!(dirs.state_home(), None);
538 assert_eq!(dirs.cache_home(), None);
539
540 let config = test_dir("config");
541 let data = test_dir("data");
542 let state = test_dir("state");
543 let cache = test_dir("cache");
544
545 dirs.set_config_home(config.clone());
546 dirs.set_data_home(data.clone());
547 dirs.set_state_home(state.clone());
548 dirs.set_cache_home(cache.clone());
549
550 assert_eq!(dirs.config_home(), Some(config.as_ref()));
551 assert_eq!(dirs.data_home(), Some(data.as_ref()));
552 assert_eq!(dirs.state_home(), Some(state.as_ref()));
553 assert_eq!(dirs.cache_home(), Some(cache.as_ref()));
554 }
555
556 #[test]
557 fn test_media_dirs_field_hookup_matches() {
558 let mut dirs = MediaDirs::empty();
559
560 assert_eq!(dirs.desktop(), None);
561 assert_eq!(dirs.documents(), None);
562 assert_eq!(dirs.downloads(), None);
563 assert_eq!(dirs.music(), None);
564 assert_eq!(dirs.pictures(), None);
565 assert_eq!(dirs.videos(), None);
566
567 let desktop = test_dir("desktop");
568 let documents = test_dir("documents");
569 let downloads = test_dir("downloads");
570 let music = test_dir("music");
571 let pictures = test_dir("pictures");
572 let videos = test_dir("videos");
573
574 dirs.set_desktop(desktop.clone());
575 dirs.set_documents(documents.clone());
576 dirs.set_downloads(downloads.clone());
577 dirs.set_music(music.clone());
578 dirs.set_pictures(pictures.clone());
579 dirs.set_videos(videos.clone());
580
581 assert_eq!(dirs.desktop(), Some(desktop.as_ref()));
582 assert_eq!(dirs.documents(), Some(documents.as_ref()));
583 assert_eq!(dirs.downloads(), Some(downloads.as_ref()));
584 assert_eq!(dirs.music(), Some(music.as_ref()));
585 assert_eq!(dirs.pictures(), Some(pictures.as_ref()));
586 assert_eq!(dirs.videos(), Some(videos.as_ref()));
587 }
588}