tauri_plugin_android_fs/models/
entry.rs

1use serde::{Deserialize, Serialize};
2use crate::*;
3
4
5#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
6#[serde(rename_all = "camelCase")]
7pub enum EntryType {
8    File {
9        mime_type: String
10    },
11    Dir,
12}
13
14impl EntryType {
15
16    pub fn is_file(&self) -> bool {
17        matches!(self, Self::File { .. })
18    }
19
20    pub fn is_dir(&self) -> bool {
21        matches!(self, Self::Dir)
22    }
23
24    /// If a file, this is no None.  
25    /// If a directory, this is None.  
26    pub fn file_mime_type(&self) -> Option<&str> {
27        match self {
28            EntryType::File { mime_type } => Some(&mime_type),
29            EntryType::Dir => None,
30        }
31    }
32
33    /// If a file, this is no None.  
34    /// If a directory, this is None.  
35    pub fn into_file_mime_type(self) -> Option<String> {
36        match self {
37            EntryType::File { mime_type } => Some(mime_type),
38            EntryType::Dir => None,
39        }
40    }
41
42    /// If a file, this is no Err.  
43    /// If a directory, this is Err.  
44    pub fn file_mime_type_or_err(&self) -> Result<&str> {
45        self.file_mime_type().ok_or_else(|| Error::with("This is not a file"))
46    }
47
48    /// If a file, this is no Err.  
49    /// If a directory, this is Err.  
50    pub fn into_file_mime_type_or_err(self) -> Result<String> {
51        self.into_file_mime_type().ok_or_else(|| Error::with("This is not a file"))
52    }
53
54 
55    #[deprecated = "Use FileType::file_mime_type instead"]
56    pub fn mime_type(&self) -> Option<&str> {
57        self.file_mime_type()
58    }
59 
60    #[deprecated = "Use FileType::into_file_mime_type instead"]
61    pub fn into_mime_type(self) -> Option<String> {
62        self.into_file_mime_type()
63    }
64}
65
66#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
67#[serde(rename_all = "camelCase")]
68pub enum Entry {
69
70    #[non_exhaustive]
71    File {
72        uri: FileUri,
73        name: String,
74        last_modified: std::time::SystemTime,
75        len: u64,
76        mime_type: String,
77    },
78
79    #[non_exhaustive]
80    Dir {
81        uri: FileUri,
82        name: String,
83        last_modified: std::time::SystemTime,
84    }
85}
86
87impl Entry {
88
89    pub fn is_file(&self) -> bool {
90        matches!(self, Self::File { .. })
91    }
92
93    pub fn is_dir(&self) -> bool {
94        matches!(self, Self::Dir { .. })
95    }
96
97    pub fn uri(&self) -> &FileUri {
98        match self {
99            Entry::File { uri, .. } => uri,
100            Entry::Dir { uri, .. } => uri,
101        }
102    }
103
104    pub fn name(&self) -> &str {
105        match self {
106            Entry::File { name, .. } => name,
107            Entry::Dir { name, .. } => name,
108        }
109    }
110
111    pub fn last_modified(&self) -> std::time::SystemTime {
112        match self {
113            Entry::File { last_modified, .. } => *last_modified,
114            Entry::Dir { last_modified, .. } => *last_modified,
115        }
116    }
117
118    /// If file, this is no None.  
119    /// If directory, this is None.  
120    pub fn file_mime_type(&self) -> Option<&str> {
121        match self {
122            Entry::File { mime_type, .. } => Some(mime_type),
123            Entry::Dir { .. } => None,
124        }
125    }
126
127    /// If a file, this is no None.  
128    /// If a directory, this is None.  
129    pub fn file_len(&self) -> Option<u64> {
130        match self {
131            Entry::File { len, .. } => Some(*len),
132            Entry::Dir { .. } => None,
133        }
134    }
135
136    /// If a file, this is no Err.  
137    /// If a directory, this is Err.  
138    pub fn file_mime_type_or_err(&self) -> Result<&str> {
139        self.file_mime_type().ok_or_else(|| Error::with("This is not a file"))
140    }
141
142    /// If a file, this is no Err.  
143    /// If a directory, this is Err.  
144    pub fn file_len_or_err(&self) -> Result<u64> {
145        self.file_len().ok_or_else(|| Error::with("This is not a file"))
146    }
147 }
148
149#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
150#[serde(rename_all = "camelCase")]
151pub enum OptionalEntry {
152
153    #[non_exhaustive]
154    File {
155        /// If `EntryOptions { uri, .. }` is set to `true`, 
156        /// this will never be `None`.
157        uri: Option<FileUri>,
158
159        /// If `EntryOptions { name, .. }` is set to `true`, 
160        /// this will never be `None`.
161        name: Option<String>,
162
163        /// If `EntryOptions { last_modified, .. }` is set to `true`, 
164        /// this will never be `None`.
165        last_modified: Option<std::time::SystemTime>,
166
167        /// If `EntryOptions { len, .. }` is set to `true`, 
168        /// this will never be `None`.
169        len: Option<u64>,
170
171        /// If `EntryOptions { mime_type, .. }` is set to `true`, 
172        /// this will never be `None`.
173        mime_type: Option<String>,
174    },
175
176    #[non_exhaustive]
177    Dir {
178        /// If `EntryOptions { uri, .. }` is set to `true`, 
179        /// this will never be `None`.
180        uri: Option<FileUri>,
181
182        /// If `EntryOptions { name, .. }` is set to `true`, 
183        /// this will never be `None`.
184        name: Option<String>,
185
186        /// If `EntryOptions { last_modified, .. }` is set to `true`, 
187        /// this will never be `None`.
188        last_modified: Option<std::time::SystemTime>,
189    }
190}
191
192impl OptionalEntry {
193
194    pub fn is_file(&self) -> bool {
195        matches!(self, Self::File { .. })
196    }
197
198    pub fn is_dir(&self) -> bool {
199        matches!(self, Self::Dir { .. })
200    }
201
202    /// If `EntryOptions { uri, .. }` is set to `true`, 
203    /// this will never be `None`.
204    pub fn into_uri(self) -> Option<FileUri> {
205        match self {
206            Self::File { uri, .. } => uri,
207            Self::Dir { uri, .. } => uri,
208        }
209    }
210    
211    /// If `EntryOptions { uri, .. }` is set to `true`, 
212    /// this will never be error.
213    pub fn into_uri_or_err(self) -> Result<FileUri> {
214        self.into_uri().ok_or_else(|| Error::missing_value("uri"))
215    }
216
217    /// If `EntryOptions { uri, .. }` is set to `true`, 
218    /// this will never be error.
219    pub fn uri_or_err(&self) -> Result<&FileUri> {
220        self.uri().ok_or_else(|| Error::missing_value("uri"))
221    }
222
223    /// If `EntryOptions { name, .. }` is set to `true`, 
224    /// this will never be error.
225    pub fn name_or_err(&self) -> Result<&str> {
226        self.name().ok_or_else(|| Error::missing_value("name"))
227    }
228
229    /// If `EntryOptions { last_modified, .. }` is set to `true`, 
230    /// this will never be error.
231    pub fn last_modified_or_err(&self) -> Result<std::time::SystemTime> {
232        self.last_modified().ok_or_else(|| Error::missing_value("last_modified"))
233    }
234
235    /// If a file and `EntryOptions { mime_type, .. }` is set to `true`, 
236    /// this will never be error.
237    pub fn file_mime_type_or_err(&self) -> Result<&str> {
238        self.file_mime_type().ok_or_else(|| Error::with("Not file or missing value: mime_type"))
239    }
240
241    /// If a file and `EntryOptions { len, .. }` is set to `true`, 
242    /// this will never be error.
243    pub fn file_len_or_err(&self) -> Result<u64> {
244        self.file_len().ok_or_else(|| Error::with("Not file or missing value: len"))
245    }
246
247    /// If `EntryOptions { uri, .. }` is set to `true`, 
248    /// this will never be `None`.
249    pub fn uri(&self) -> Option<&FileUri> {
250        match self {
251            Self::File { uri, .. } => uri.as_ref(),
252            Self::Dir { uri, .. } => uri.as_ref(),
253        }
254    }
255
256    /// If `EntryOptions { name, .. }` is set to `true`, 
257    /// this will never be `None`.
258    pub fn name(&self) -> Option<&str> {
259        match self {
260            Self::File { name, .. } => name.as_deref(),
261            Self::Dir { name, .. } => name.as_deref(),
262        }
263    }
264
265    /// If `EntryOptions { last_modified, .. }` is set to `true`, 
266    /// this will never be `None`.
267    pub fn last_modified(&self) -> Option<std::time::SystemTime> {
268        match self {
269            Self::File { last_modified, .. } => *last_modified,
270            Self::Dir { last_modified, .. } => *last_modified,
271        }
272    }
273
274    /// If a file and `EntryOptions { mime_type, .. }` is set to `true`, 
275    /// this will never be `None`.
276    pub fn file_mime_type(&self) -> Option<&str> {
277        match self {
278            Self::File { mime_type, .. } => mime_type.as_deref(),
279            Self::Dir { .. } => None,
280        }
281    }
282
283    /// If a file and `EntryOptions { len, .. }` is set to `true`, 
284    /// this will never be `None`.
285    pub fn file_len(&self) -> Option<u64> {
286        match self {
287            Self::File { len, .. } => *len,
288            Self::Dir { .. } => None,
289        }
290    }
291 }
292
293#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Deserialize, Serialize)]
294#[serde(rename_all = "camelCase")]
295pub struct EntryOptions {
296    pub uri: bool,
297    pub name: bool,
298    pub last_modified: bool,
299    pub len: bool,
300    pub mime_type: bool,
301}
302
303impl EntryOptions {
304
305    pub const ALL: EntryOptions = EntryOptions {
306        uri: true,
307        name: true,
308        last_modified: true,
309        len: true,
310        mime_type: true
311    };
312
313    pub const NONE: EntryOptions = EntryOptions {
314        uri: false,
315        name: false,
316        last_modified: false,
317        len: false,
318        mime_type: false
319    };
320
321    pub const URI_ONLY: EntryOptions = EntryOptions {
322        uri: true,
323        ..Self::NONE
324    };
325
326    pub const URI_AND_NAME: EntryOptions = EntryOptions {
327        uri: true,
328        name: true,
329        ..Self::NONE
330    };
331}
332
333impl TryFrom<OptionalEntry> for Entry {
334    type Error = crate::Error;
335
336    fn try_from(value: OptionalEntry) -> std::result::Result<Self, Self::Error> {
337        Ok(match value {
338            OptionalEntry::File { uri, name, last_modified, len, mime_type } => Entry::File {
339                uri: uri.ok_or_else(|| Error::missing_value("uri"))?,
340                name: name.ok_or_else(|| Error::missing_value("name"))?,
341                last_modified: last_modified.ok_or_else(|| Error::missing_value("last_modified"))?,
342                len: len.ok_or_else(|| Error::missing_value("len"))?,
343                mime_type: mime_type.ok_or_else(|| Error::missing_value("mime_type"))?,
344            },
345            OptionalEntry::Dir { uri, name, last_modified } => Entry::Dir {
346                uri: uri.ok_or_else(|| Error::missing_value("uri"))?,
347                name: name.ok_or_else(|| Error::missing_value("name"))?,
348                last_modified: last_modified.ok_or_else(|| Error::missing_value("last_modified"))?,
349            },
350        })
351    }
352}