sysdirs/lib.rs
1#![cfg_attr(docsrs, feature(doc_cfg))]
2//! # sysdirs
3//!
4//! A low-level library with a minimal API that provides platform-specific, user-accessible
5//! locations for finding and storing configuration, cache and other data on Linux,
6//! Windows (≥ Vista), macOS, **iOS, Android, and WASM**.
7//!
8//! The library provides the location of these directories by leveraging the mechanisms defined by:
9//!
10//! * the [XDG base directory](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html)
11//! and the [XDG user directory](https://www.freedesktop.org/wiki/Software/xdg-user-dirs/) specifications on Linux
12//! * the [Known Folder](https://msdn.microsoft.com/en-us/library/windows/desktop/bb776911(v=vs.85).aspx) system on Windows
13//! * the [Standard Directories](https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html#//apple_ref/doc/uid/TP40010672-CH2-SW6) on macOS and iOS
14//! * the app sandbox directories on Android (requires initialization)
15//!
16//! ## Usage
17//!
18//! ```rust
19//! use sysdirs;
20//!
21//! sysdirs::home_dir();
22//! // Lin: Some(/home/alice)
23//! // Win: Some(C:\Users\Alice)
24//! // Mac: Some(/Users/Alice)
25//! // iOS: Some(/var/mobile/Containers/Data/Application/<UUID>)
26//! // Android: Some(/data/data/com.example.app/files) [after init]
27//!
28//! sysdirs::cache_dir();
29//! // Lin: Some(/home/alice/.cache)
30//! // Win: Some(C:\Users\Alice\AppData\Local)
31//! // Mac: Some(/Users/Alice/Library/Caches)
32//! // iOS: Some(<sandbox>/Library/Caches)
33//! // Android: Some(<filesDir>/cache)
34//! ```
35//!
36//! ## Android Setup
37//!
38//! There are two ways to use sysdirs on Android:
39//!
40//! ### Option 1: Pure Rust Android apps (android-activity/ndk-glue)
41//!
42//! Enable the `android-auto` feature and paths are detected automatically:
43//!
44//! ```toml
45//! [dependencies]
46//! sysdirs = { version = "0.1", features = ["android-auto"] }
47//! ```
48//!
49//! ### Option 2: Kotlin/Java apps embedding Rust
50//!
51//! Call `init_android()` once at startup from your JNI layer:
52//!
53//! ```rust,ignore
54//! // Called from Kotlin/Java via JNI at app startup
55//! sysdirs::init_android("/data/data/com.example.app/files");
56//! ```
57//!
58//! The path should be obtained from `Context.getFilesDir()` in Kotlin/Java.
59//!
60//! ## Platform Support
61//!
62//! | Function | Linux | macOS | Windows | iOS | Android | WASM |
63//! |----------|-------|-------|---------|-----|---------|------|
64//! | `home_dir` | ✓ | ✓ | ✓ | ✓ | ✓* | ✗ |
65//! | `cache_dir` | ✓ | ✓ | ✓ | ✓ | ✓* | ✗ |
66//! | `config_dir` | ✓ | ✓ | ✓ | ✓ | ✓* | ✗ |
67//! | `config_local_dir` | ✓ | ✓ | ✓ | ✓ | ✓* | ✗ |
68//! | `data_dir` | ✓ | ✓ | ✓ | ✓ | ✓* | ✗ |
69//! | `data_local_dir` | ✓ | ✓ | ✓ | ✓ | ✓* | ✗ |
70//! | `document_dir` | ✓ | ✓ | ✓ | ✓ | ✗ | ✗ |
71//! | `download_dir` | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
72//! | `preference_dir` | ✓ | ✓ | ✓ | ✓ | ✓* | ✗ |
73//! | `audio_dir` | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
74//! | `desktop_dir` | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
75//! | `executable_dir` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
76//! | `font_dir` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
77//! | `picture_dir` | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
78//! | `public_dir` | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
79//! | `runtime_dir` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
80//! | `state_dir` | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
81//! | `template_dir` | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ |
82//! | `video_dir` | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ |
83//!
84//! \* Requires either the `android-auto` feature or [`init_android()`] to be called first
85
86use std::io;
87use std::path::Path;
88use std::path::PathBuf;
89
90// =============================================================================
91// Path Extension Trait
92// =============================================================================
93
94/// Extension trait for `Option<PathBuf>` that adds chainable path operations.
95///
96/// This trait makes it easy to work with directory paths in a fluent style:
97///
98/// ```rust
99/// use sysdirs::PathExt;
100///
101/// // Chain joins and ensure the directory exists
102/// let app_cache = sysdirs::cache_dir()
103/// .join("my-app")
104/// .join("data")
105/// .ensure();
106/// ```
107pub trait PathExt {
108 /// Joins a path component to the contained path, if present.
109 ///
110 /// This is chainable, allowing multiple joins in sequence.
111 ///
112 /// # Example
113 ///
114 /// ```rust
115 /// use sysdirs::PathExt;
116 ///
117 /// let path = sysdirs::data_dir()
118 /// .join("my-app")
119 /// .join("cache");
120 /// // Linux: Some(/home/alice/.local/share/my-app/cache)
121 /// ```
122 fn join<P: AsRef<Path>>(self, path: P) -> Option<PathBuf>;
123
124 /// Ensures the directory exists, creating it if necessary.
125 ///
126 /// Returns the path if successful, or an error if:
127 /// - The original `Option` was `None` (directory not available on this platform)
128 /// - Directory creation failed (permissions, disk full, etc.)
129 ///
130 /// # Example
131 ///
132 /// ```rust,ignore
133 /// use sysdirs::PathExt;
134 ///
135 /// let app_data = sysdirs::data_dir()
136 /// .join("my-app")
137 /// .ensure()?;
138 /// // Directory now exists, ready to use
139 /// ```
140 fn ensure(self) -> io::Result<PathBuf>;
141}
142
143impl PathExt for Option<PathBuf> {
144 fn join<P: AsRef<Path>>(self, path: P) -> Option<PathBuf> {
145 self.map(|p| p.join(path))
146 }
147
148 fn ensure(self) -> io::Result<PathBuf> {
149 match self {
150 Some(path) => {
151 std::fs::create_dir_all(&path)?;
152 Ok(path)
153 }
154 None => Err(io::Error::new(
155 io::ErrorKind::NotFound,
156 "directory not available on this platform",
157 )),
158 }
159 }
160}
161
162// =============================================================================
163// Platform Modules
164// =============================================================================
165
166#[cfg(any(
167 target_os = "macos",
168 target_os = "ios",
169 target_os = "tvos",
170 target_os = "watchos",
171 target_os = "visionos"
172))]
173mod apple;
174#[cfg(any(
175 target_os = "macos",
176 target_os = "ios",
177 target_os = "tvos",
178 target_os = "watchos",
179 target_os = "visionos"
180))]
181use apple as platform;
182
183#[cfg(target_os = "linux")]
184mod linux;
185#[cfg(target_os = "linux")]
186use linux as platform;
187
188#[cfg(target_os = "windows")]
189mod windows;
190#[cfg(target_os = "windows")]
191use windows as platform;
192
193#[cfg(target_os = "android")]
194mod android;
195#[cfg(target_os = "android")]
196use android as platform;
197
198#[cfg(target_arch = "wasm32")]
199mod wasm;
200#[cfg(target_arch = "wasm32")]
201use wasm as platform;
202
203// Fallback for other platforms (FreeBSD, etc.)
204#[cfg(not(any(
205 target_os = "macos",
206 target_os = "ios",
207 target_os = "tvos",
208 target_os = "watchos",
209 target_os = "visionos",
210 target_os = "linux",
211 target_os = "windows",
212 target_os = "android",
213 target_arch = "wasm32"
214)))]
215mod unix;
216#[cfg(not(any(
217 target_os = "macos",
218 target_os = "ios",
219 target_os = "tvos",
220 target_os = "watchos",
221 target_os = "visionos",
222 target_os = "linux",
223 target_os = "windows",
224 target_os = "android",
225 target_arch = "wasm32"
226)))]
227use unix as platform;
228
229// =============================================================================
230// Apple Search Path Domain (Apple platforms only)
231// =============================================================================
232
233/// Search path domain for Apple platforms.
234///
235/// Controls which domain to search when looking up directories on macOS, iOS, etc.
236/// Defaults to `User`.
237///
238/// This is only available on Apple platforms.
239#[cfg(any(
240 target_os = "macos",
241 target_os = "ios",
242 target_os = "tvos",
243 target_os = "watchos",
244 target_os = "visionos"
245))]
246#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
247pub enum SearchPathDomain {
248 /// User's home directory (e.g., ~/Library/...)
249 #[default]
250 User,
251 /// Local machine (e.g., /Library/...)
252 Local,
253 /// Network locations (e.g., /Network/Library/...)
254 Network,
255 /// System (e.g., /System/Library/...)
256 System,
257}
258
259/// Set the search path domain for Apple directory lookups.
260///
261/// By default, sysdirs uses the `User` domain which returns paths like `~/Library/Caches`.
262/// System utilities or admin tools may want to use `Local` or `System` domains.
263///
264/// This function is only available on Apple platforms.
265///
266/// # Example
267///
268/// ```rust,ignore
269/// use sysdirs::{SearchPathDomain, set_domain, cache_dir};
270///
271/// // Default: user domain
272/// cache_dir(); // ~/Library/Caches
273///
274/// // Switch to local domain
275/// set_domain(SearchPathDomain::Local);
276/// cache_dir(); // /Library/Caches
277/// ```
278#[cfg(any(
279 target_os = "macos",
280 target_os = "ios",
281 target_os = "tvos",
282 target_os = "watchos",
283 target_os = "visionos"
284))]
285pub fn set_domain(domain: SearchPathDomain) {
286 platform::set_domain(domain);
287}
288
289// =============================================================================
290// Android Initialization
291// =============================================================================
292
293/// Initialize Android-specific paths.
294///
295/// Must be called once at app startup on Android before using any directory functions.
296/// The path should be obtained from `Context.getFilesDir()` in Kotlin/Java.
297///
298/// This function is only available on Android.
299///
300/// # Example
301///
302/// ```rust,ignore
303/// // Called from JNI at app startup
304/// sysdirs::init_android("/data/data/com.example.app/files");
305/// ```
306#[cfg(target_os = "android")]
307pub fn init_android(files_dir: &str) {
308 platform::init_android(files_dir);
309}
310
311/// Initialize Android-specific paths with separate directories.
312///
313/// Like [`init_android()`], but allows specifying both the files directory
314/// and the cache directory separately. Use this if your app needs the actual
315/// cache directory from `Context.getCacheDir()`.
316///
317/// This function is only available on Android.
318///
319/// # Example
320///
321/// ```rust,ignore
322/// sysdirs::init_android_with_cache(
323/// "/data/data/com.example.app/files",
324/// "/data/data/com.example.app/cache"
325/// );
326/// ```
327#[cfg(target_os = "android")]
328pub fn init_android_with_cache(files_dir: &str, cache_dir: &str) {
329 platform::init_android_with_cache(files_dir, cache_dir);
330}
331
332// =============================================================================
333// Base Directories
334// =============================================================================
335
336/// Returns the path to the user's home directory.
337///
338/// The returned value depends on the operating system and is either a `Some`, containing a value
339/// from the following table, or a `None`.
340///
341/// |Platform | Value | Example |
342/// | ------- | ---------------------------------------- | -------------------------------- |
343/// | Linux | `$HOME` | /home/alice |
344/// | macOS | `$HOME` | /Users/Alice |
345/// | Windows | `{FOLDERID_Profile}` | C:\Users\Alice |
346/// | iOS | sandbox container | /var/mobile/.../<UUID> |
347/// | Android | files directory (after init) | /data/data/com.example/files |
348/// | WASM | `None` | |
349pub fn home_dir() -> Option<PathBuf> {
350 platform::home_dir()
351}
352
353/// Returns the path to the user's cache directory.
354///
355/// The returned value depends on the operating system and is either a `Some`, containing a value
356/// from the following table, or a `None`.
357///
358/// |Platform | Value | Example |
359/// | ------- | ----------------------------------- | ---------------------------------- |
360/// | Linux | `$XDG_CACHE_HOME` or `$HOME`/.cache | /home/alice/.cache |
361/// | macOS | `$HOME`/Library/Caches | /Users/Alice/Library/Caches |
362/// | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Local |
363/// | iOS | sandbox/Library/Caches | <sandbox>/Library/Caches |
364/// | Android | files/cache (after init) | /data/data/com.example/files/cache |
365/// | WASM | `None` | |
366pub fn cache_dir() -> Option<PathBuf> {
367 platform::cache_dir()
368}
369
370/// Returns the path to the user's config directory.
371///
372/// The returned value depends on the operating system and is either a `Some`, containing a value
373/// from the following table, or a `None`.
374///
375/// |Platform | Value | Example |
376/// | ------- | ------------------------------------- | ------------------------------------------ |
377/// | Linux | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config |
378/// | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support |
379/// | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming |
380/// | iOS | sandbox/Library/Application Support | <sandbox>/Library/Application Support |
381/// | Android | files directory (after init) | /data/data/com.example/files |
382/// | WASM | `None` | |
383pub fn config_dir() -> Option<PathBuf> {
384 platform::config_dir()
385}
386
387/// Returns the path to the user's local config directory.
388///
389/// The returned value depends on the operating system and is either a `Some`, containing a value
390/// from the following table, or a `None`.
391///
392/// |Platform | Value | Example |
393/// | ------- | ------------------------------------- | ------------------------------------------ |
394/// | Linux | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config |
395/// | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support |
396/// | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Local |
397/// | iOS | sandbox/Library/Application Support | <sandbox>/Library/Application Support |
398/// | Android | files directory (after init) | /data/data/com.example/files |
399/// | WASM | `None` | |
400pub fn config_local_dir() -> Option<PathBuf> {
401 platform::config_local_dir()
402}
403
404/// Returns the path to the user's data directory.
405///
406/// The returned value depends on the operating system and is either a `Some`, containing a value
407/// from the following table, or a `None`.
408///
409/// |Platform | Value | Example |
410/// | ------- | ------------------------------------------- | ------------------------------------------ |
411/// | Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share |
412/// | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support |
413/// | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming |
414/// | iOS | sandbox/Library/Application Support | <sandbox>/Library/Application Support |
415/// | Android | files directory (after init) | /data/data/com.example/files |
416/// | WASM | `None` | |
417pub fn data_dir() -> Option<PathBuf> {
418 platform::data_dir()
419}
420
421/// Returns the path to the user's local data directory.
422///
423/// The returned value depends on the operating system and is either a `Some`, containing a value
424/// from the following table, or a `None`.
425///
426/// |Platform | Value | Example |
427/// | ------- | ------------------------------------------- | ------------------------------------------ |
428/// | Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share |
429/// | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support |
430/// | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Local |
431/// | iOS | sandbox/Library/Application Support | <sandbox>/Library/Application Support |
432/// | Android | files directory (after init) | /data/data/com.example/files |
433/// | WASM | `None` | |
434pub fn data_local_dir() -> Option<PathBuf> {
435 platform::data_local_dir()
436}
437
438/// Returns the path to the user's executable directory.
439///
440/// The returned value depends on the operating system and is either a `Some`, containing a value
441/// from the following table, or a `None`.
442///
443/// |Platform | Value | Example |
444/// | ------- | ---------------------------------------- | -------------------------- |
445/// | Linux | `$XDG_BIN_HOME` or `$HOME`/.local/bin | /home/alice/.local/bin |
446/// | macOS | `None` | |
447/// | Windows | `None` | |
448/// | iOS | `None` | |
449/// | Android | `None` | |
450/// | WASM | `None` | |
451pub fn executable_dir() -> Option<PathBuf> {
452 platform::executable_dir()
453}
454
455/// Returns the path to the user's preference directory.
456///
457/// The returned value depends on the operating system and is either a `Some`, containing a value
458/// from the following table, or a `None`.
459///
460/// |Platform | Value | Example |
461/// | ------- | ------------------------------------- | ---------------------------------------- |
462/// | Linux | `$XDG_CONFIG_HOME` or `$HOME`/.config | /home/alice/.config |
463/// | macOS | `$HOME`/Library/Preferences | /Users/Alice/Library/Preferences |
464/// | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming |
465/// | iOS | sandbox/Library/Preferences | <sandbox>/Library/Preferences |
466/// | Android | files directory (after init) | /data/data/com.example/files |
467/// | WASM | `None` | |
468pub fn preference_dir() -> Option<PathBuf> {
469 platform::preference_dir()
470}
471
472/// Returns the path to the user's runtime directory.
473///
474/// The returned value depends on the operating system and is either a `Some`, containing a value
475/// from the following table, or a `None`.
476///
477/// |Platform | Value | Example |
478/// | ------- | ------------------ | --------------- |
479/// | Linux | `$XDG_RUNTIME_DIR` | /run/user/1000 |
480/// | macOS | `None` | |
481/// | Windows | `None` | |
482/// | iOS | `None` | |
483/// | Android | `None` | |
484/// | WASM | `None` | |
485pub fn runtime_dir() -> Option<PathBuf> {
486 platform::runtime_dir()
487}
488
489/// Returns the path to the user's state directory.
490///
491/// The returned value depends on the operating system and is either a `Some`, containing a value
492/// from the following table, or a `None`.
493///
494/// |Platform | Value | Example |
495/// | ------- | ------------------------------------------- | -------------------------- |
496/// | Linux | `$XDG_STATE_HOME` or `$HOME`/.local/state | /home/alice/.local/state |
497/// | macOS | `None` | |
498/// | Windows | `None` | |
499/// | iOS | `None` | |
500/// | Android | `None` | |
501/// | WASM | `None` | |
502pub fn state_dir() -> Option<PathBuf> {
503 platform::state_dir()
504}
505
506// =============================================================================
507// User Directories
508// =============================================================================
509
510/// Returns the path to the user's audio directory.
511///
512/// The returned value depends on the operating system and is either a `Some`, containing a value
513/// from the following table, or a `None`.
514///
515/// |Platform | Value | Example |
516/// | ------- | --------------------- | ------------------------ |
517/// | Linux | `XDG_MUSIC_DIR` | /home/alice/Music |
518/// | macOS | `$HOME`/Music | /Users/Alice/Music |
519/// | Windows | `{FOLDERID_Music}` | C:\Users\Alice\Music |
520/// | iOS | `None` | |
521/// | Android | `None` | |
522/// | WASM | `None` | |
523pub fn audio_dir() -> Option<PathBuf> {
524 platform::audio_dir()
525}
526
527/// Returns the path to the user's desktop directory.
528///
529/// The returned value depends on the operating system and is either a `Some`, containing a value
530/// from the following table, or a `None`.
531///
532/// |Platform | Value | Example |
533/// | ------- | --------------------- | ------------------------ |
534/// | Linux | `XDG_DESKTOP_DIR` | /home/alice/Desktop |
535/// | macOS | `$HOME`/Desktop | /Users/Alice/Desktop |
536/// | Windows | `{FOLDERID_Desktop}` | C:\Users\Alice\Desktop |
537/// | iOS | `None` | |
538/// | Android | `None` | |
539/// | WASM | `None` | |
540pub fn desktop_dir() -> Option<PathBuf> {
541 platform::desktop_dir()
542}
543
544/// Returns the path to the user's document directory.
545///
546/// The returned value depends on the operating system and is either a `Some`, containing a value
547/// from the following table, or a `None`.
548///
549/// |Platform | Value | Example |
550/// | ------- | ----------------------- | -------------------------- |
551/// | Linux | `XDG_DOCUMENTS_DIR` | /home/alice/Documents |
552/// | macOS | `$HOME`/Documents | /Users/Alice/Documents |
553/// | Windows | `{FOLDERID_Documents}` | C:\Users\Alice\Documents |
554/// | iOS | sandbox/Documents | <sandbox>/Documents |
555/// | Android | `None` | |
556/// | WASM | `None` | |
557pub fn document_dir() -> Option<PathBuf> {
558 platform::document_dir()
559}
560
561/// Returns the path to the user's download directory.
562///
563/// The returned value depends on the operating system and is either a `Some`, containing a value
564/// from the following table, or a `None`.
565///
566/// |Platform | Value | Example |
567/// | ------- | ----------------------- | -------------------------- |
568/// | Linux | `XDG_DOWNLOAD_DIR` | /home/alice/Downloads |
569/// | macOS | `$HOME`/Downloads | /Users/Alice/Downloads |
570/// | Windows | `{FOLDERID_Downloads}` | C:\Users\Alice\Downloads |
571/// | iOS | `None` | |
572/// | Android | `None` | |
573/// | WASM | `None` | |
574pub fn download_dir() -> Option<PathBuf> {
575 platform::download_dir()
576}
577
578/// Returns the path to the user's font directory.
579///
580/// The returned value depends on the operating system and is either a `Some`, containing a value
581/// from the following table, or a `None`.
582///
583/// |Platform | Value | Example |
584/// | ------- | -------------------------------------------------- | ---------------------------------- |
585/// | Linux | `$XDG_DATA_HOME`/fonts or `$HOME`/.local/share/fonts | /home/alice/.local/share/fonts |
586/// | macOS | `$HOME`/Library/Fonts | /Users/Alice/Library/Fonts |
587/// | Windows | `None` | |
588/// | iOS | `None` | |
589/// | Android | `None` | |
590/// | WASM | `None` | |
591pub fn font_dir() -> Option<PathBuf> {
592 platform::font_dir()
593}
594
595/// Returns the path to the user's picture directory.
596///
597/// The returned value depends on the operating system and is either a `Some`, containing a value
598/// from the following table, or a `None`.
599///
600/// |Platform | Value | Example |
601/// | ------- | ----------------------- | -------------------------- |
602/// | Linux | `XDG_PICTURES_DIR` | /home/alice/Pictures |
603/// | macOS | `$HOME`/Pictures | /Users/Alice/Pictures |
604/// | Windows | `{FOLDERID_Pictures}` | C:\Users\Alice\Pictures |
605/// | iOS | `None` | |
606/// | Android | `None` | |
607/// | WASM | `None` | |
608pub fn picture_dir() -> Option<PathBuf> {
609 platform::picture_dir()
610}
611
612/// Returns the path to the user's public directory.
613///
614/// The returned value depends on the operating system and is either a `Some`, containing a value
615/// from the following table, or a `None`.
616///
617/// |Platform | Value | Example |
618/// | ------- | ----------------------- | -------------------------- |
619/// | Linux | `XDG_PUBLICSHARE_DIR` | /home/alice/Public |
620/// | macOS | `$HOME`/Public | /Users/Alice/Public |
621/// | Windows | `{FOLDERID_Public}` | C:\Users\Public |
622/// | iOS | `None` | |
623/// | Android | `None` | |
624/// | WASM | `None` | |
625pub fn public_dir() -> Option<PathBuf> {
626 platform::public_dir()
627}
628
629/// Returns the path to the user's template directory.
630///
631/// The returned value depends on the operating system and is either a `Some`, containing a value
632/// from the following table, or a `None`.
633///
634/// |Platform | Value | Example |
635/// | ------- | ----------------------- | ------------------------------------ |
636/// | Linux | `XDG_TEMPLATES_DIR` | /home/alice/Templates |
637/// | macOS | `None` | |
638/// | Windows | `{FOLDERID_Templates}` | C:\Users\Alice\AppData\Roaming\Microsoft\Windows\Templates |
639/// | iOS | `None` | |
640/// | Android | `None` | |
641/// | WASM | `None` | |
642pub fn template_dir() -> Option<PathBuf> {
643 platform::template_dir()
644}
645
646/// Returns the path to the user's video directory.
647///
648/// The returned value depends on the operating system and is either a `Some`, containing a value
649/// from the following table, or a `None`.
650///
651/// |Platform | Value | Example |
652/// | ------- | --------------------- | ------------------------ |
653/// | Linux | `XDG_VIDEOS_DIR` | /home/alice/Videos |
654/// | macOS | `$HOME`/Movies | /Users/Alice/Movies |
655/// | Windows | `{FOLDERID_Videos}` | C:\Users\Alice\Videos |
656/// | iOS | `None` | |
657/// | Android | `None` | |
658/// | WASM | `None` | |
659pub fn video_dir() -> Option<PathBuf> {
660 platform::video_dir()
661}
662
663// =============================================================================
664// sysdirs Extensions
665// =============================================================================
666
667/// Returns the path to the app's temporary directory.
668///
669/// This is a sysdirs extension not present in the `dirs` crate.
670///
671/// The returned value depends on the operating system and is either a `Some`, containing a value
672/// from the following table, or a `None`.
673///
674/// |Platform | Value | Example |
675/// | ------- | ---------------------------- | ---------------------------- |
676/// | Linux | `$TMPDIR` or /tmp | /tmp |
677/// | macOS | `$TMPDIR` | /var/folders/.../T/ |
678/// | Windows | `{FOLDERID_LocalAppData}`\Temp | C:\Users\Alice\AppData\Local\Temp |
679/// | iOS | sandbox/tmp | <sandbox>/tmp |
680/// | Android | files/tmp (after init) | /data/data/com.example/files/tmp |
681/// | WASM | `None` | |
682pub fn temp_dir() -> Option<PathBuf> {
683 platform::temp_dir()
684}
685
686/// Returns the path to the app's Library directory (Apple platforms only).
687///
688/// This is a sysdirs extension not present in the `dirs` crate.
689///
690/// The returned value depends on the operating system and is either a `Some`, containing a value
691/// from the following table, or a `None`.
692///
693/// |Platform | Value | Example |
694/// | ------- | ---------------------------- | ---------------------------- |
695/// | Linux | `None` | |
696/// | macOS | `$HOME`/Library | /Users/Alice/Library |
697/// | Windows | `None` | |
698/// | iOS | sandbox/Library | <sandbox>/Library |
699/// | Android | `None` | |
700/// | WASM | `None` | |
701pub fn library_dir() -> Option<PathBuf> {
702 platform::library_dir()
703}
704
705// =============================================================================
706// Tests
707// =============================================================================
708
709#[cfg(test)]
710mod tests {
711 use super::*;
712
713 #[test]
714 fn test_home_dir() {
715 // On most platforms we should get something
716 #[cfg(not(target_arch = "wasm32"))]
717 assert!(home_dir().is_some());
718 }
719
720 #[test]
721 fn test_cache_dir() {
722 #[cfg(not(any(target_arch = "wasm32", target_os = "android")))]
723 assert!(cache_dir().is_some());
724 }
725
726 #[test]
727 fn test_config_dir() {
728 #[cfg(not(any(target_arch = "wasm32", target_os = "android")))]
729 assert!(config_dir().is_some());
730 }
731
732 #[test]
733 fn test_data_dir() {
734 #[cfg(not(any(target_arch = "wasm32", target_os = "android")))]
735 assert!(data_dir().is_some());
736 }
737
738 #[test]
739 #[cfg(target_os = "android")]
740 fn test_android_init() {
741 init_android("/data/data/com.test/files");
742 assert_eq!(home_dir(), Some(PathBuf::from("/data/data/com.test/files")));
743 assert_eq!(
744 cache_dir(),
745 Some(PathBuf::from("/data/data/com.test/files/cache"))
746 );
747 }
748}