1use serde::{Deserialize, Serialize};
2use crate::{Error, Result};
3
4#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
27#[serde(rename_all = "camelCase")]
28pub struct FileUri {
29 pub uri: String,
31
32 pub document_top_tree_uri: Option<String>,
34}
35
36impl FileUri {
37
38 pub fn to_string(&self) -> crate::Result<String> {
39 serde_json::to_string(self).map_err(Into::into)
40 }
41
42 pub fn from_str(s: &str) -> crate::Result<Self> {
43 serde_json::from_str(s).map_err(Into::into)
44 }
45
46 pub fn from_path(path: impl AsRef<std::path::Path>) -> Self {
47 Self { uri: format!("file://{}", path.as_ref().to_string_lossy()), document_top_tree_uri: None }
48 }
49
50 #[allow(unused)]
51 pub(crate) fn as_path(&self) -> Option<&std::path::Path> {
52 if self.uri.starts_with("file://") {
53 return Some(std::path::Path::new(self.uri.trim_start_matches("file://")))
54 }
55 None
56 }
57}
58
59impl From<&std::path::Path> for FileUri {
60
61 fn from(path: &std::path::Path) -> Self {
62 Self::from_path(path)
63 }
64}
65
66impl From<&std::path::PathBuf> for FileUri {
67
68 fn from(path: &std::path::PathBuf) -> Self {
69 Self::from_path(path)
70 }
71}
72
73impl From<std::path::PathBuf> for FileUri {
74
75 fn from(path: std::path::PathBuf) -> Self {
76 Self::from_path(path)
77 }
78}
79
80impl From<tauri_plugin_fs::FilePath> for FileUri {
81
82 fn from(value: tauri_plugin_fs::FilePath) -> Self {
83 match value {
84 tauri_plugin_fs::FilePath::Url(url) => Self { uri: url.to_string(), document_top_tree_uri: None },
85 tauri_plugin_fs::FilePath::Path(path_buf) => path_buf.into(),
86 }
87 }
88}
89
90impl From<FileUri> for tauri_plugin_fs::FilePath {
91
92 fn from(value: FileUri) -> Self {
93 type NeverErr<T> = std::result::Result::<T, std::convert::Infallible>;
94 NeverErr::unwrap(value.uri.parse())
95 }
96}
97
98#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
99#[serde(rename_all = "camelCase")]
100pub struct PublicStorageVolume {
101
102 pub description: String,
111
112 pub is_primary: bool,
115
116 pub id: PublicStorageVolumeId,
117}
118
119#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
120#[serde(rename_all = "camelCase")]
121pub struct PublicStorageVolumeId(pub String);
122
123#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
124#[serde(rename_all = "camelCase")]
125pub enum Entry {
126
127 #[non_exhaustive]
128 File {
129 uri: FileUri,
130 name: String,
131 last_modified: std::time::SystemTime,
132 len: u64,
133 mime_type: String,
134 },
135
136 #[non_exhaustive]
137 Dir {
138 uri: FileUri,
139 name: String,
140 last_modified: std::time::SystemTime,
141 }
142}
143
144#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
145#[serde(rename_all = "camelCase")]
146pub enum EntryType {
147 File {
148 mime_type: String
149 },
150 Dir,
151}
152
153impl EntryType {
154
155 pub fn is_file(&self) -> bool {
156 matches!(self, Self::File { .. })
157 }
158
159 pub fn is_dir(&self) -> bool {
160 matches!(self, Self::Dir)
161 }
162
163 pub fn mime_type(&self) -> Option<&str> {
166 match self {
167 EntryType::File { mime_type } => Some(&mime_type),
168 EntryType::Dir => None,
169 }
170 }
171
172 pub fn into_mime_type(self) -> Option<String> {
175 match self {
176 EntryType::File { mime_type } => Some(mime_type),
177 EntryType::Dir => None,
178 }
179 }
180}
181
182#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
184pub enum PersistableAccessMode {
185
186 Read,
188
189 Write,
191
192 ReadAndWrite,
194}
195
196#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
197pub enum PersistedUriPermission {
198 File {
199 uri: FileUri,
200 can_read: bool,
201 can_write: bool,
202 },
203 Dir {
204 uri: FileUri,
205 can_read: bool,
206 can_write: bool,
207 }
208}
209
210impl PersistedUriPermission {
211
212 pub fn uri(&self) -> &FileUri {
213 match self {
214 PersistedUriPermission::File { uri, .. } => uri,
215 PersistedUriPermission::Dir { uri, .. } => uri,
216 }
217 }
218
219 pub fn into_uri(self) -> FileUri {
220 match self {
221 PersistedUriPermission::File { uri, .. } => uri,
222 PersistedUriPermission::Dir { uri, .. } => uri,
223 }
224 }
225
226 pub fn can_read(&self) -> bool {
227 match self {
228 PersistedUriPermission::File { can_read, .. } => *can_read,
229 PersistedUriPermission::Dir { can_read, .. } => *can_read,
230 }
231 }
232
233 pub fn can_write(&self) -> bool {
234 match self {
235 PersistedUriPermission::File { can_write, .. } => *can_write,
236 PersistedUriPermission::Dir { can_write, .. } => *can_write,
237 }
238 }
239
240 pub fn is_file(&self) -> bool {
241 matches!(self, PersistedUriPermission::File { .. })
242 }
243
244 pub fn is_dir(&self) -> bool {
245 matches!(self, PersistedUriPermission::Dir { .. })
246 }
247}
248
249#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
250pub struct Size {
251 pub width: u32,
252 pub height: u32
253}
254
255#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
256#[non_exhaustive]
257pub enum ImageFormat {
258
259 Png,
262
263 Jpeg,
266
267 Webp,
270
271 JpegWith {
274
275 quality: f32
279 },
280
281 WebpWith {
284
285 quality: f32
289 }
290}
291
292#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
294#[non_exhaustive]
295pub enum FileAccessMode {
296
297 Read,
301
302 #[deprecated(note = "This may or may not truncate existing contents. If the new file is smaller than the old one, this may cause the file to become corrupted.")]
313 Write,
314
315 WriteTruncate,
320
321 WriteAppend,
326
327 ReadWrite,
331
332 ReadWriteTruncate,
337}
338
339#[allow(unused)]
340#[allow(deprecated)]
341impl FileAccessMode {
342
343 pub(crate) fn to_mode(&self) -> &'static str {
344 match self {
345 FileAccessMode::Read => "r",
346 FileAccessMode::Write => "w",
347 FileAccessMode::WriteTruncate => "wt",
348 FileAccessMode::WriteAppend => "wa",
349 FileAccessMode::ReadWriteTruncate => "rwt",
350 FileAccessMode::ReadWrite => "rw",
351 }
352 }
353
354 pub(crate) fn from_mode(mode: &str) -> Result<Self> {
355 match mode {
356 "r" => Ok(Self::Read),
357 "w" => Ok(Self::Write),
358 "wt" => Ok(Self::WriteTruncate),
359 "wa" => Ok(Self::WriteAppend),
360 "rwt" => Ok(Self::ReadWriteTruncate),
361 "rw" => Ok(Self::ReadWrite),
362 mode => Err(Error { msg: format!("Illegal mode: {mode}").into() })
363 }
364 }
365}
366
367#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
369#[non_exhaustive]
370pub enum VisualMediaTarget<'a> {
371
372 ImageOnly,
374
375 VideoOnly,
377
378 ImageAndVideo,
380
381 ImageOrVideo {
383 mime_type: &'a str
384 }
385}
386
387#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
389#[non_exhaustive]
390pub enum PrivateDir {
391
392 Data,
401
402 Cache,
412}
413
414#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
415#[non_exhaustive]
416pub enum PublicDir {
417
418 #[serde(untagged)]
419 Image(PublicImageDir),
420
421 #[serde(untagged)]
422 Video(PublicVideoDir),
423
424 #[serde(untagged)]
425 Audio(PublicAudioDir),
426
427 #[serde(untagged)]
428 GeneralPurpose(PublicGeneralPurposeDir),
429}
430
431#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
433#[non_exhaustive]
434pub enum PublicImageDir {
435
436 Pictures,
440
441 DCIM,
445}
446
447#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
449#[non_exhaustive]
450pub enum PublicVideoDir {
451
452 Movies,
456
457 DCIM,
461}
462
463#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
465#[non_exhaustive]
466pub enum PublicAudioDir {
467
468 Music,
472
473 Alarms,
477
478 Audiobooks,
484
485 Notifications,
489
490 Podcasts,
494
495 Ringtones,
499
500 Recordings,
506}
507
508#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
510#[non_exhaustive]
511pub enum PublicGeneralPurposeDir {
512
513 Documents,
517
518 Download,
525}
526
527impl std::fmt::Display for PublicImageDir {
528 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
529 match self {
530 PublicImageDir::Pictures => write!(f, "Pictures"),
531 PublicImageDir::DCIM => write!(f, "DCIM"),
532 }
533 }
534}
535
536impl std::fmt::Display for PublicVideoDir {
537 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
538 match self {
539 PublicVideoDir::Movies => write!(f, "Movies"),
540 PublicVideoDir::DCIM => write!(f, "DCIM"),
541 }
542 }
543}
544
545impl std::fmt::Display for PublicAudioDir {
546 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
547 match self {
548 PublicAudioDir::Music => write!(f, "Music"),
549 PublicAudioDir::Alarms => write!(f, "Alarms"),
550 PublicAudioDir::Audiobooks => write!(f, "Audiobooks"),
551 PublicAudioDir::Notifications => write!(f, "Notifications"),
552 PublicAudioDir::Podcasts => write!(f, "Podcasts"),
553 PublicAudioDir::Ringtones => write!(f, "Ringtones"),
554 PublicAudioDir::Recordings => write!(f, "Recordings"),
555 }
556 }
557}
558
559impl std::fmt::Display for PublicGeneralPurposeDir {
560 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
561 match self {
562 PublicGeneralPurposeDir::Documents => write!(f, "Documents"),
563 PublicGeneralPurposeDir::Download => write!(f, "Download"),
564 }
565 }
566}
567
568impl std::fmt::Display for PublicDir {
569 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
570 match self {
571 PublicDir::Image(p) => p.fmt(f),
572 PublicDir::Video(p) => p.fmt(f),
573 PublicDir::Audio(p) => p.fmt(f),
574 PublicDir::GeneralPurpose(p) => p.fmt(f),
575 }
576 }
577}
578
579macro_rules! impl_into_pubdir {
580 ($target: ident, $wrapper: ident) => {
581 impl From<$target> for PublicDir {
582 fn from(value: $target) -> Self {
583 Self::$wrapper(value)
584 }
585 }
586 };
587}
588impl_into_pubdir!(PublicImageDir, Image);
589impl_into_pubdir!(PublicVideoDir, Video);
590impl_into_pubdir!(PublicAudioDir, Audio);
591impl_into_pubdir!(PublicGeneralPurposeDir, GeneralPurpose);