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 /// FileDescriptor mode: "w"
175 #[deprecated = "This may or may not truncate existing contents. So please use WriteTruncate or WriteAppend instead."]
176 Write,
177
178 /// Opens the file in write-only mode.
179 /// The existing content is truncated (deleted), and new data is written from the beginning.
180 /// Creates a new file if it does not exist.
181 ///
182 /// FileDescriptor mode: "wt"
183 WriteTruncate,
184
185 /// Opens the file in write-only mode.
186 /// The existing content is preserved, and new data is appended to the end of the file.
187 /// Creates a new file if it does not exist.
188 ///
189 /// FileDescriptor mode: "wa"
190 WriteAppend,
191
192 /// Opens the file in read-write mode.
193 ///
194 /// FileDescriptor mode: "rw"
195 ReadWrite,
196
197 /// Opens the file in read-write mode.
198 /// The existing content is truncated (deleted), and new data is written from the beginning.
199 /// Creates a new file if it does not exist.
200 ///
201 /// FileDescriptor mode: "rwt"
202 ReadWriteTruncate,
203}
204
205/// Filters for VisualMediaPicker.
206#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
207#[non_exhaustive]
208pub enum VisualMediaTarget {
209
210 /// Allow only images to be selected.
211 ImageOnly,
212
213 /// Allow only videos to be selected.
214 VideoOnly,
215
216 /// Allow only images and videos to be selected.
217 ImageAndVideo,
218}
219
220/// The application specific directory.
221#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
222#[non_exhaustive]
223pub enum PrivateDir {
224
225 /// The application specific persistent-data directory.
226 ///
227 /// The system prevents other apps and user from accessing these locations.
228 /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.
229 ///
230 /// These files will be deleted when the app is uninstalled and may also be deleted at the user’s request.
231 ///
232 /// ex: `/data/user/0/{app-package-name}/files`
233 Data,
234
235 /// The application specific cache directory.
236 ///
237 /// The system prevents other apps and user from accessing these locations.
238 /// In cases where the device is rooted or the user has special permissions, the user may be able to access this.
239 ///
240 /// These files will be deleted when the app is uninstalled and may also be deleted at the user’s request.
241 /// In addition, the system will automatically delete files in this directory as disk space is needed elsewhere on the device.
242 ///
243 /// ex: `/data/user/0/{app-package-name}/cache`
244 Cache,
245}
246
247#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
248#[non_exhaustive]
249pub enum PublicDir {
250
251 #[serde(untagged)]
252 Image(PublicImageDir),
253
254 #[serde(untagged)]
255 Video(PublicVideoDir),
256
257 #[serde(untagged)]
258 Audio(PublicAudioDir),
259
260 #[serde(untagged)]
261 GeneralPurpose(PublicGeneralPurposeDir),
262}
263
264/// Directory in which to place images that are available to other applications and users.
265#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
266#[non_exhaustive]
267pub enum PublicImageDir {
268
269 /// Standard directory in which to place pictures that are available to the user.
270 ///
271 /// ex: `~/Pictures`
272 Pictures,
273
274 /// The traditional location for pictures and videos when mounting the device as a camera.
275 ///
276 /// ex: `~/DCIM`
277 DCIM,
278}
279
280/// Directory in which to place videos that are available to other applications and users.
281#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
282#[non_exhaustive]
283pub enum PublicVideoDir {
284
285 /// Standard directory in which to place movies that are available to the user.
286 ///
287 /// ex: `~/Movies`
288 Movies,
289
290 /// The traditional location for pictures and videos when mounting the device as a camera.
291 ///
292 /// ex: `~/DCIM`
293 DCIM,
294}
295
296/// Directory in which to place audios that are available to other applications and users.
297#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
298#[non_exhaustive]
299pub enum PublicAudioDir {
300
301 /// Standard directory in which to place movies that are available to the user.
302 ///
303 /// ex: `~/Music`
304 Music,
305
306 /// 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).
307 ///
308 /// ex: `~/Alarms`
309 Alarms,
310
311 /// 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).
312 ///
313 /// This is not available on Android 9 (API level 28) and lower.
314 ///
315 /// ex: `~/Audiobooks`
316 Audiobooks,
317
318 /// 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).
319 ///
320 /// ex: `~/Notifications`
321 Notifications,
322
323 /// 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).
324 ///
325 /// ex: `~/Podcasts`
326 Podcasts,
327
328 /// 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).
329 ///
330 /// ex: `~/Ringtones`
331 Ringtones,
332
333 /// 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).
334 ///
335 /// This is not available on Android 11 (API level 30) and lower.
336 ///
337 /// ex: `~/Recordings`
338 Recordings,
339}
340
341/// Directory in which to place files that are available to other applications and users.
342#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
343#[non_exhaustive]
344pub enum PublicGeneralPurposeDir {
345
346 /// Standard directory in which to place documents that have been created by the user.
347 ///
348 /// ex: `~/Documents`
349 Documents,
350
351 /// Standard directory in which to place files that have been downloaded by the user.
352 ///
353 /// ex: `~/Download`
354 Download,
355}
356
357
358macro_rules! impl_into_pubdir {
359 ($target: ident, $wrapper: ident) => {
360 impl From<$target> for PublicDir {
361 fn from(value: $target) -> Self {
362 Self::$wrapper(value)
363 }
364 }
365 };
366}
367impl_into_pubdir!(PublicImageDir, Image);
368impl_into_pubdir!(PublicVideoDir, Video);
369impl_into_pubdir!(PublicAudioDir, Audio);
370impl_into_pubdir!(PublicGeneralPurposeDir, GeneralPurpose);