tauri_plugin_android_fs/models.rs
1use serde::{Deserialize, Serialize};
2
3
4/// Path to represent a file or directory.
5///
6/// # Note
7/// For compatibility, an interconversion to [`tauri_plugin_fs::FilePath`] is implemented, such as follwing.
8/// This is lossy and also not guaranteed to work properly with other plugins.
9/// However, reading and writing files by official [`tauri_plugin_fs`] etc. should work well.
10/// ```no_run
11/// use tauri_plugin_android_fs::FileUri;
12/// use tauri_plugin_fs::FilePath;
13///
14/// let uri: FileUri = unimplemented!();
15///
16/// let path: FilePath = uri.into();
17///
18/// let uri: FileUri = path.into();
19/// ```
20///
21/// # Typescript type
22/// You should use the following type because the inner value should not be used directly.
23/// ```typescript
24/// type FileUri = any
25/// type FileUri = string
26/// ```
27#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
28#[serde(rename_all = "camelCase")]
29pub struct FileUri {
30 pub(crate) uri: String,
31 pub(crate) document_top_tree_uri: Option<String>,
32}
33
34impl FileUri {
35
36 pub fn to_string(&self) -> crate::Result<String> {
37 serde_json::to_string(self).map_err(Into::into)
38 }
39
40 pub fn from_str(s: &str) -> crate::Result<Self> {
41 serde_json::from_str(s).map_err(Into::into)
42 }
43}
44
45impl From<&std::path::PathBuf> for FileUri {
46
47 fn from(value: &std::path::PathBuf) -> Self {
48 Self { uri: format!("file://{}", value.to_string_lossy()), document_top_tree_uri: None }
49 }
50}
51
52impl From<std::path::PathBuf> for FileUri {
53
54 fn from(ref value: std::path::PathBuf) -> Self {
55 value.into()
56 }
57}
58
59impl From<tauri_plugin_fs::FilePath> for FileUri {
60
61 fn from(value: tauri_plugin_fs::FilePath) -> Self {
62 match value {
63 tauri_plugin_fs::FilePath::Url(url) => Self { uri: url.to_string(), document_top_tree_uri: None },
64 tauri_plugin_fs::FilePath::Path(path_buf) => path_buf.into(),
65 }
66 }
67}
68
69impl From<FileUri> for tauri_plugin_fs::FilePath {
70
71 fn from(value: FileUri) -> Self {
72 let result: std::result::Result<_, std::convert::Infallible> = value.uri.parse();
73
74 // This will not cause panic. Because result err is infallible.
75 result.unwrap()
76 }
77}
78
79#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
80#[serde(rename_all = "camelCase")]
81pub enum Entry {
82
83 #[non_exhaustive]
84 File {
85 uri: FileUri,
86 name: String,
87 last_modified: std::time::SystemTime,
88 len: u64,
89 mime_type: String,
90 },
91
92 #[non_exhaustive]
93 Dir {
94 uri: FileUri,
95 name: String,
96 last_modified: std::time::SystemTime,
97 }
98}
99
100/// Access mode
101#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
102pub enum PersistableAccessMode {
103
104 /// Read access.
105 Read,
106
107 /// Write access.
108 Write,
109
110 /// Read-write access.
111 ReadAndWrite,
112}
113
114#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
115pub enum PersistedUriPermission {
116 File {
117 uri: FileUri,
118 can_read: bool,
119 can_write: bool,
120 },
121 Dir {
122 uri: FileUri,
123 can_read: bool,
124 can_write: bool,
125 }
126}
127
128impl PersistedUriPermission {
129
130 pub fn uri(&self) -> &FileUri {
131 match self {
132 PersistedUriPermission::File { uri, .. } => uri,
133 PersistedUriPermission::Dir { uri, .. } => uri,
134 }
135 }
136
137 pub fn can_read(&self) -> bool {
138 match self {
139 PersistedUriPermission::File { can_read, .. } => *can_read,
140 PersistedUriPermission::Dir { can_read, .. } => *can_read,
141 }
142 }
143
144 pub fn can_write(&self) -> bool {
145 match self {
146 PersistedUriPermission::File { can_write, .. } => *can_write,
147 PersistedUriPermission::Dir { can_write, .. } => *can_write,
148 }
149 }
150
151 pub fn is_file(&self) -> bool {
152 matches!(self, PersistedUriPermission::File { .. })
153 }
154
155 pub fn is_dir(&self) -> bool {
156 matches!(self, PersistedUriPermission::Dir { .. })
157 }
158}
159
160/// Access mode
161#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
162#[non_exhaustive]
163pub enum FileAccessMode {
164
165 /// Opens the file in read-only mode.
166 ///
167 /// FileDescriptor mode: "r"
168 Read,
169
170 /// Opens the file in write-only mode.
171 /// **This may or may not truncate.**
172 /// So please use `WriteTruncate` or `WriteAppend` instead.
173 ///
174 /// This is there just in case.
175 ///
176 /// FileDescriptor mode: "w"
177 #[deprecated = "This may or may not truncate existing contents. So please use WriteTruncate or WriteAppend instead."]
178 Write,
179
180 /// Opens the file in write-only mode.
181 /// The existing content is truncated (deleted), and new data is written from the beginning.
182 /// Creates a new file if it does not exist.
183 ///
184 /// FileDescriptor mode: "wt"
185 WriteTruncate,
186
187 /// Opens the file in write-only mode.
188 /// The existing content is preserved, and new data is appended to the end of the file.
189 /// Creates a new file if it does not exist.
190 ///
191 /// FileDescriptor mode: "wa"
192 WriteAppend,
193
194 /// Opens the file in read-write mode.
195 ///
196 /// FileDescriptor mode: "rw"
197 ReadWrite,
198
199 /// Opens the file in read-write mode.
200 /// The existing content is truncated (deleted), and new data is written from the beginning.
201 /// Creates a new file if it does not exist.
202 ///
203 /// FileDescriptor mode: "rwt"
204 ReadWriteTruncate,
205}
206
207/// Filters for VisualMediaPicker.
208#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
209#[non_exhaustive]
210pub enum VisualMediaTarget {
211
212 /// Allow only images to be selected.
213 ImageOnly,
214
215 /// Allow only videos to be selected.
216 VideoOnly,
217
218 /// Allow only images and videos to be selected.
219 ImageAndVideo,
220}
221
222/// The application specific directory.
223#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
224#[non_exhaustive]
225pub enum PrivateDir {
226
227 /// The application specific persistent-data directory.
228 ///
229 /// The system prevents other apps and user from accessing these locations.
230 /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.
231 ///
232 /// These files will be deleted when the app is uninstalled and may also be deleted at the user’s request.
233 ///
234 /// ex: `/data/user/0/{app-package-name}/files`
235 Data,
236
237 /// The application specific cache directory.
238 ///
239 /// The system prevents other apps and user from accessing these locations.
240 /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.
241 ///
242 /// These files will be deleted when the app is uninstalled and may also be deleted at the user’s request.
243 /// In addition, the system will automatically delete files in this directory as disk space is needed elsewhere on the device.
244 ///
245 /// ex: `/data/user/0/{app-package-name}/cache`
246 Cache,
247}
248
249#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
250#[non_exhaustive]
251pub enum PublicDir {
252
253 #[serde(untagged)]
254 Image(PublicImageDir),
255
256 #[serde(untagged)]
257 Video(PublicVideoDir),
258
259 #[serde(untagged)]
260 Audio(PublicAudioDir),
261
262 #[serde(untagged)]
263 GeneralPurpose(PublicGeneralPurposeDir),
264}
265
266/// Directory in which to place images that are available to other applications and users.
267#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
268#[non_exhaustive]
269pub enum PublicImageDir {
270
271 /// Standard directory in which to place pictures that are available to the user.
272 ///
273 /// ex: `~/Pictures`
274 Pictures,
275
276 /// The traditional location for pictures and videos when mounting the device as a camera.
277 ///
278 /// ex: `~/DCIM`
279 DCIM,
280}
281
282/// Directory in which to place videos that are available to other applications and users.
283#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
284#[non_exhaustive]
285pub enum PublicVideoDir {
286
287 /// Standard directory in which to place movies that are available to the user.
288 ///
289 /// ex: `~/Movies`
290 Movies,
291
292 /// The traditional location for pictures and videos when mounting the device as a camera.
293 ///
294 /// ex: `~/DCIM`
295 DCIM,
296}
297
298/// Directory in which to place audios that are available to other applications and users.
299#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
300#[non_exhaustive]
301pub enum PublicAudioDir {
302
303 /// Standard directory in which to place movies that are available to the user.
304 ///
305 /// ex: `~/Music`
306 Music,
307
308 /// Standard directory in which to place any audio files that should be in the list of alarms that the user can select (not as regular music).
309 ///
310 /// ex: `~/Alarms`
311 Alarms,
312
313 /// Standard directory in which to place any audio files that should be in the list of audiobooks that the user can select (not as regular music).
314 ///
315 /// This is not available on Android 9 (API level 28) and lower.
316 ///
317 /// ex: `~/Audiobooks`
318 Audiobooks,
319
320 /// Standard directory in which to place any audio files that should be in the list of notifications that the user can select (not as regular music).
321 ///
322 /// ex: `~/Notifications`
323 Notifications,
324
325 /// Standard directory in which to place any audio files that should be in the list of podcasts that the user can select (not as regular music).
326 ///
327 /// ex: `~/Podcasts`
328 Podcasts,
329
330 /// Standard directory in which to place any audio files that should be in the list of ringtones that the user can select (not as regular music).
331 ///
332 /// ex: `~/Ringtones`
333 Ringtones,
334
335 /// Standard directory in which to place any audio files that should be in the list of voice recordings recorded by voice recorder apps that the user can select (not as regular music).
336 ///
337 /// This is not available on Android 11 (API level 30) and lower.
338 ///
339 /// ex: `~/Recordings`
340 Recordings,
341}
342
343/// Directory in which to place files that are available to other applications and users.
344#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
345#[non_exhaustive]
346pub enum PublicGeneralPurposeDir {
347
348 /// Standard directory in which to place documents that have been created by the user.
349 ///
350 /// ex: `~/Documents`
351 Documents,
352
353 /// Standard directory in which to place files that have been downloaded by the user.
354 ///
355 /// ex: `~/Download`
356 Download,
357}
358
359
360macro_rules! impl_into_pubdir {
361 ($target: ident, $wrapper: ident) => {
362 impl From<$target> for PublicDir {
363 fn from(value: $target) -> Self {
364 Self::$wrapper(value)
365 }
366 }
367 };
368}
369impl_into_pubdir!(PublicImageDir, Image);
370impl_into_pubdir!(PublicVideoDir, Video);
371impl_into_pubdir!(PublicAudioDir, Audio);
372impl_into_pubdir!(PublicGeneralPurposeDir, GeneralPurpose);