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