Skip to main content

tauri_plugin_android_fs/api/models/
dir.rs

1use std::str::FromStr;
2use serde::{Deserialize, Serialize};
3use crate::*;
4
5
6/// Directory for the app’s use only.
7/// 
8/// # Serialization
9/// Serialized by `serde` as the following TypeScript type:
10///
11/// ```ts
12/// // NOTE: New variants may be added in the future
13/// type PrivateDir = "Data" | "Cache" | "NoBackupData";
14/// ```
15#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
16#[non_exhaustive]
17pub enum PrivateDir {
18
19    /// The application specific persistent-data directory.  
20    /// 
21    /// Files stored in this directory are included in [Android Auto Backup](https://developer.android.com/identity/data/autobackup).  
22    /// 
23    /// The system prevents other apps and user from accessing these locations. 
24    /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.   
25    ///  
26    /// This will be deleted when the app is uninstalled and may also be deleted at the user’s request.  
27    /// 
28    /// e.g. `/data/user/0/{app-package-name}/files`
29    /// 
30    /// <https://developer.android.com/reference/android/content/Context#getFilesDir()>
31    Data,
32
33    /// The application specific cache directory.  
34    /// 
35    /// Files stored in this directory are **not** included in [Android Auto Backup](https://developer.android.com/identity/data/autobackup).  
36    /// 
37    /// The system prevents other apps and user from accessing these locations. 
38    /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.   
39    /// 
40    /// This will be deleted when the app is uninstalled and may also be deleted at the user’s request. 
41    ///
42    /// In addition, the system will automatically delete files in this directory as disk space is needed elsewhere on the device. 
43    /// But you should not rely on this. The cache should be explicitly cleared by yourself.
44    /// 
45    /// e.g. `/data/user/0/{app-package-name}/cache`
46    /// 
47    /// <https://developer.android.com/reference/android/content/Context#getCacheDir()>
48    Cache,
49
50    /// The application specific persistent-data directory.  
51    /// 
52    /// This is similar to [`PrivateDir::Data`].
53    /// But files stored in this directory are **not** included in [Android Auto Backup](https://developer.android.com/identity/data/autobackup).  
54    /// 
55    /// The system prevents other apps and user from accessing these locations. 
56    /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.   
57    ///  
58    /// This will be deleted when the app is uninstalled and may also be deleted at the user’s request.  
59    /// 
60    /// e.g. `/data/user/0/{app-package-name}/no_backup`
61    /// 
62    /// <https://developer.android.com/reference/android/content/Context#getNoBackupFilesDir()>
63    NoBackupData,
64}
65
66/// Directory for the app’s use.  
67/// 
68/// # Serialization
69/// Serialized by `serde` as the following TypeScript type:
70///
71/// ```ts
72/// // NOTE: New variants may be added in the future
73/// type AppDir = "Data" | "Cache" | "PublicMedia";
74/// ```
75#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
76#[non_exhaustive]
77pub enum AppDir {
78
79    /// The directory for persistent-data files.  
80    /// 
81    /// This will be deleted when the app is uninstalled and may also be deleted at the user’s request.  
82    ///
83    /// This may be accessible by other apps.
84    /// 
85    /// e.g. 
86    /// - `/storage/emulated/{user-id}/Android/data/{app-package-name}/files`
87    /// - `/storage/{sd-card-id}/Android/data/{app-package-name}/files`
88    ///
89    /// <https://developer.android.com/reference/android/content/Context#getExternalFilesDirs(java.lang.String)>
90    Data,
91    
92    /// The directory for cache files.  
93    /// 
94    /// This will be deleted when the app is uninstalled and may also be deleted at the user’s request. 
95    ///
96    /// This may be accessible by other apps.
97    /// 
98    /// e.g. 
99    /// - `/storage/emulated/{user-id}/Android/data/{app-package-name}/cache`
100    /// - `/storage/{sd-card-id}/Android/data/{app-package-name}/cache`
101    ///
102    /// <https://developer.android.com/reference/android/content/Context#getExternalCacheDirs()>
103    Cache,
104
105    /// The directory for shared media files to other apps or user.  
106    /// 
107    /// This will be deleted when the app is uninstalled and may also be deleted at the user’s request. 
108    ///
109    /// For Android 11 (API level 30) or higher, 
110    /// this has been marked as deprecated. 
111    /// It still works, but you should consider migrating to [`PublicStorage`](crate::api::api_async::PublicStorage).
112    ///
113    /// e.g. 
114    /// - `/storage/emulated/{user-id}/Android/media/{app-package-name}`
115    /// - `/storage/{sd-card-id}/Android/media/{app-package-name}`
116    /// 
117    /// <https://developer.android.com/reference/android/content/Context#getExternalMediaDirs()>
118    #[deprecated(note = "For Android 11 (API level 30) or higher, this is deprecated. Use `PublicDir` of `PublicStorage` instead.")]
119    PublicMedia
120}
121
122/// Directory in which to place files that are available to other applications and users. 
123/// 
124/// # Serialization
125/// Serialized by `serde` as the following TypeScript type:
126///
127/// ```ts
128/// // NOTE: New variants may be added in the future
129/// type PublicDir = "Pictures" | "Movies" | "DCIM" | "Music" | "Alarms" | "Audiobooks" | "Notifications" | "Podcasts" | "Ringtones" | "Recordings" | "Documents" | "Download";
130/// ```
131#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
132#[non_exhaustive]
133pub enum PublicDir {
134    
135    #[serde(untagged)]
136    Image(PublicImageDir),
137
138    #[serde(untagged)]
139    Video(PublicVideoDir),
140
141    #[serde(untagged)]
142    Audio(PublicAudioDir),
143
144    #[serde(untagged)]
145    GeneralPurpose(PublicGeneralPurposeDir),
146}
147
148/// Directory in which to place images that are available to other applications and users.  
149/// 
150/// # Serialization
151/// Serialized by `serde` as the following TypeScript type:
152///
153/// ```ts
154/// // NOTE: New variants may be added in the future
155/// type PublicImageDir = "Pictures" | "DCIM";
156/// ```
157#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
158#[non_exhaustive]
159pub enum PublicImageDir {
160
161    Pictures,
162
163    DCIM,
164}
165
166/// Directory in which to place videos that are available to other applications and users.  
167/// 
168/// # Serialization
169/// Serialized by `serde` as the following TypeScript type:
170///
171/// ```ts
172/// // NOTE: New variants may be added in the future
173/// type PublicVideoDir = "Movies" | "DCIM" | "Pictures";
174/// ```
175#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
176#[non_exhaustive]
177pub enum PublicVideoDir {
178
179	Movies,
180
181	DCIM,
182
183    Pictures,
184}
185
186/// Directory in which to place audios that are available to other applications and users.  
187/// 
188/// # Serialization
189/// Serialized by `serde` as the following TypeScript type:
190///
191/// ```ts
192/// // NOTE: New variants may be added in the future
193/// type PublicAudioDir = "Music" | "Alarms" | "Audiobooks" | "Notifications" | "Podcasts" | "Ringtones" | "Recordings";
194/// ```
195#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
196#[non_exhaustive]
197pub enum PublicAudioDir {
198
199    Music,
200
201    Alarms,
202
203    /// This is not available on Android 9 (API level 28) and lower.  
204    Audiobooks,
205
206    Notifications,
207
208    Podcasts,
209
210    Ringtones,
211
212    /// This is not available on Android 11 (API level 30) and lower.  
213    Recordings,
214}
215
216/// Directory in which to place files that are available to other applications and users. 
217/// 
218/// # Serialization
219/// Serialized by `serde` as the following TypeScript type:
220///
221/// ```ts
222/// // NOTE: New variants may be added in the future
223/// type PublicGeneralPurposeDir = "Documents" | "Download";
224/// ```
225#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
226#[non_exhaustive]
227pub enum PublicGeneralPurposeDir {
228
229    Documents,
230
231    /// This is not the plural "Downloads", but the singular "Download".
232    /// <https://developer.android.com/reference/android/os/Environment#DIRECTORY_DOWNLOADS>
233    Download,
234}
235
236impl std::fmt::Display for PublicImageDir {
237    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238        match self {
239            PublicImageDir::Pictures => write!(f, "Pictures"),
240            PublicImageDir::DCIM => write!(f, "DCIM"),
241        }
242    }
243}
244
245impl std::fmt::Display for PublicVideoDir {
246    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
247        match self {
248            PublicVideoDir::Movies => write!(f, "Movies"),
249            PublicVideoDir::DCIM => write!(f, "DCIM"),
250            PublicVideoDir::Pictures => write!(f, "Pictures")
251        }
252    }
253}
254
255impl std::fmt::Display for PublicAudioDir {
256    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
257        match self {
258            PublicAudioDir::Music => write!(f, "Music"),
259            PublicAudioDir::Alarms => write!(f, "Alarms"),
260            PublicAudioDir::Audiobooks => write!(f, "Audiobooks"),
261            PublicAudioDir::Notifications => write!(f, "Notifications"),
262            PublicAudioDir::Podcasts => write!(f, "Podcasts"),
263            PublicAudioDir::Ringtones => write!(f, "Ringtones"),
264            PublicAudioDir::Recordings => write!(f, "Recordings"),
265        }
266    }
267}
268
269impl std::fmt::Display for PublicGeneralPurposeDir {
270    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
271        match self {
272            PublicGeneralPurposeDir::Documents => write!(f, "Documents"),
273            PublicGeneralPurposeDir::Download => write!(f, "Download"),
274        }
275    }
276}
277
278impl std::fmt::Display for PublicDir {
279    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
280        match self {
281            PublicDir::Image(p) => p.fmt(f),
282            PublicDir::Video(p) => p.fmt(f),
283            PublicDir::Audio(p) => p.fmt(f),
284            PublicDir::GeneralPurpose(p) => p.fmt(f),
285        }
286    }
287}
288
289macro_rules! impl_into_pubdir {
290    ($target: ident, $wrapper: ident) => {
291        impl From<$target> for PublicDir {
292            fn from(value: $target) -> Self {
293                Self::$wrapper(value)
294            }
295        }
296    };
297}
298impl_into_pubdir!(PublicImageDir, Image);
299impl_into_pubdir!(PublicVideoDir, Video);
300impl_into_pubdir!(PublicAudioDir, Audio);
301impl_into_pubdir!(PublicGeneralPurposeDir, GeneralPurpose);
302
303impl FromStr for PublicImageDir {
304    type Err = Error;
305
306    fn from_str(s: &str) -> Result<Self> {
307        if s.eq_ignore_ascii_case("pictures") {
308            Ok(PublicImageDir::Pictures)
309        } 
310        else if s.eq_ignore_ascii_case("dcim") {
311            Ok(PublicImageDir::DCIM)
312        } 
313        else {
314            Err(Error::with(format!("invalid PublicImageDir: {s}")))
315        }
316    }
317}
318
319impl FromStr for PublicVideoDir {
320    type Err = Error;
321
322    fn from_str(s: &str) -> Result<Self> {
323        if s.eq_ignore_ascii_case("movies") {
324            Ok(PublicVideoDir::Movies)
325        }
326        else if s.eq_ignore_ascii_case("dcim") {
327            Ok(PublicVideoDir::DCIM)
328        }
329        else if s.eq_ignore_ascii_case("pictures") {
330            Ok(PublicVideoDir::Pictures)
331        }
332        else {
333            Err(Error::with(format!("invalid PublicVideoDir: {s}")))
334        }
335    }
336}
337
338impl FromStr for PublicAudioDir {
339    type Err = Error;
340
341    fn from_str(s: &str) -> Result<Self> {
342        if s.eq_ignore_ascii_case("music") {
343            Ok(PublicAudioDir::Music)
344        } 
345        else if s.eq_ignore_ascii_case("alarms") {
346            Ok(PublicAudioDir::Alarms)
347        }
348        else if s.eq_ignore_ascii_case("audiobooks") {
349            Ok(PublicAudioDir::Audiobooks)
350        }
351        else if s.eq_ignore_ascii_case("notifications") {
352            Ok(PublicAudioDir::Notifications)
353        } 
354        else if s.eq_ignore_ascii_case("podcasts") {
355            Ok(PublicAudioDir::Podcasts)
356        } 
357        else if s.eq_ignore_ascii_case("ringtones") {
358            Ok(PublicAudioDir::Ringtones)
359        } 
360        else if s.eq_ignore_ascii_case("recordings") {
361            Ok(PublicAudioDir::Recordings)
362        } 
363        else {
364            Err(Error::with(format!("invalid PublicAudioDir: {s}")))
365        }
366    }
367}
368
369impl FromStr for PublicGeneralPurposeDir {
370    type Err = Error;
371
372    fn from_str(s: &str) -> Result<Self> {
373        if s.eq_ignore_ascii_case("documents") {
374            Ok(PublicGeneralPurposeDir::Documents)
375        }
376        else if s.eq_ignore_ascii_case("download") || s.eq_ignore_ascii_case("downloads") {
377            Ok(PublicGeneralPurposeDir::Download)
378        } 
379        else {
380            Err(Error::with(format!("invalid PublicGeneralPurposeDir: {s}")))
381        }
382    }
383}
384
385impl FromStr for PublicDir {
386    type Err = Error;
387
388    fn from_str(s: &str) -> Result<Self> {
389        if let Ok(v) = PublicImageDir::from_str(s) {
390            Ok(PublicDir::Image(v))
391        }
392        else if let Ok(v) = PublicVideoDir::from_str(s) {
393            Ok(PublicDir::Video(v))
394        }
395        else if let Ok(v) = PublicAudioDir::from_str(s) {
396            Ok(PublicDir::Audio(v))
397        }
398        else if let Ok(v) = PublicGeneralPurposeDir::from_str(s) {
399            Ok(PublicDir::GeneralPurpose(v))
400        }
401        else {
402            Err(Error::with(format!("invalid PublicDir: {s}")))
403        }
404    }
405}