Skip to main content

lb_rs/model/
file_like.rs

1use std::fmt::Debug;
2
3use uuid::Uuid;
4
5use crate::model::access_info::{EncryptedFolderAccessKey, UserAccessInfo, UserAccessMode};
6use crate::model::file_metadata::{DocumentHmac, FileMetadata, FileType, Owner};
7use crate::model::secret_filename::SecretFileName;
8use crate::model::server_file::ServerFile;
9use crate::model::signed_file::SignedFile;
10
11use super::meta::Meta;
12use super::server_meta::ServerMeta;
13use super::signed_meta::SignedMeta;
14
15pub trait FileLike: PartialEq + Debug + Clone {
16    fn id(&self) -> &Uuid;
17    fn file_type(&self) -> FileType;
18    fn parent(&self) -> &Uuid;
19    fn secret_name(&self) -> &SecretFileName;
20    fn owner(&self) -> Owner;
21    fn explicitly_deleted(&self) -> bool;
22    fn document_hmac(&self) -> Option<&DocumentHmac>;
23    fn user_access_keys(&self) -> &Vec<UserAccessInfo>;
24    fn folder_access_key(&self) -> &EncryptedFolderAccessKey;
25    fn doc_size(&self) -> Option<usize>;
26
27    fn display(&self) -> String {
28        match self.file_type() {
29            FileType::Folder => format!("id: {}/", self.id()),
30            FileType::Document => format!("id: {}", self.id()),
31            FileType::Link { target } => format!("id: {}, target: {}", self.id(), target),
32        }
33    }
34
35    fn is_folder(&self) -> bool {
36        self.file_type() == FileType::Folder
37    }
38
39    fn is_link(&self) -> bool {
40        matches!(self.file_type(), FileType::Link { .. })
41    }
42
43    fn is_document(&self) -> bool {
44        self.file_type() == FileType::Document
45    }
46
47    fn is_root(&self) -> bool {
48        self.id() == self.parent()
49    }
50
51    fn access_mode(&self, pk: &Owner) -> Option<UserAccessMode> {
52        self.user_access_keys()
53            .iter()
54            .filter(|k| !k.deleted)
55            .find(|k| k.encrypted_for == pk.0)
56            .map(|k| k.mode)
57    }
58
59    fn is_shared(&self) -> bool {
60        self.user_access_keys()
61            .iter()
62            .any(|k| !k.deleted && k.encrypted_for != k.encrypted_by)
63    }
64}
65
66impl FileLike for Meta {
67    fn id(&self) -> &Uuid {
68        match self {
69            Meta::V1 { id, .. } => id,
70        }
71    }
72
73    fn file_type(&self) -> FileType {
74        match self {
75            Meta::V1 { file_type, .. } => *file_type,
76        }
77    }
78
79    fn parent(&self) -> &Uuid {
80        match self {
81            Meta::V1 { parent, .. } => parent,
82        }
83    }
84
85    fn secret_name(&self) -> &SecretFileName {
86        match self {
87            Meta::V1 { name, .. } => name,
88        }
89    }
90
91    fn owner(&self) -> Owner {
92        match self {
93            Meta::V1 { owner, .. } => *owner,
94        }
95    }
96
97    fn explicitly_deleted(&self) -> bool {
98        match self {
99            Meta::V1 { is_deleted, .. } => *is_deleted,
100        }
101    }
102
103    fn document_hmac(&self) -> Option<&DocumentHmac> {
104        match self {
105            Meta::V1 { doc_hmac: document_hmac, .. } => document_hmac.as_ref(),
106        }
107    }
108
109    fn user_access_keys(&self) -> &Vec<UserAccessInfo> {
110        match self {
111            Meta::V1 { user_access_keys, .. } => user_access_keys,
112        }
113    }
114
115    fn folder_access_key(&self) -> &EncryptedFolderAccessKey {
116        match self {
117            Meta::V1 { folder_access_key, .. } => folder_access_key,
118        }
119    }
120
121    fn doc_size(&self) -> Option<usize> {
122        match self {
123            Meta::V1 { doc_size, .. } => *doc_size,
124        }
125    }
126}
127
128impl<F> FileLike for F
129where
130    F: AsRef<FileMetadata> + PartialEq + Debug + Clone,
131{
132    fn id(&self) -> &Uuid {
133        let fm: &FileMetadata = self.as_ref();
134        &fm.id
135    }
136
137    fn file_type(&self) -> FileType {
138        let fm: &FileMetadata = self.as_ref();
139        fm.file_type
140    }
141
142    fn parent(&self) -> &Uuid {
143        let fm: &FileMetadata = self.as_ref();
144        &fm.parent
145    }
146
147    fn secret_name(&self) -> &SecretFileName {
148        let fm: &FileMetadata = self.as_ref();
149        &fm.name
150    }
151
152    fn owner(&self) -> Owner {
153        let fm: &FileMetadata = self.as_ref();
154        fm.owner
155    }
156
157    fn explicitly_deleted(&self) -> bool {
158        let fm: &FileMetadata = self.as_ref();
159        fm.is_deleted
160    }
161
162    fn document_hmac(&self) -> Option<&DocumentHmac> {
163        let fm: &FileMetadata = self.as_ref();
164        fm.document_hmac.as_ref()
165    }
166
167    fn user_access_keys(&self) -> &Vec<UserAccessInfo> {
168        let fm: &FileMetadata = self.as_ref();
169        &fm.user_access_keys
170    }
171
172    fn folder_access_key(&self) -> &EncryptedFolderAccessKey {
173        let fm: &FileMetadata = self.as_ref();
174        &fm.folder_access_key
175    }
176
177    fn doc_size(&self) -> Option<usize> {
178        // FileMetadata doesn't have doc_size field
179        None
180    }
181}
182
183impl AsRef<FileMetadata> for FileMetadata {
184    fn as_ref(&self) -> &FileMetadata {
185        self
186    }
187}
188
189impl AsRef<FileMetadata> for SignedFile {
190    fn as_ref(&self) -> &FileMetadata {
191        &self.timestamped_value.value
192    }
193}
194
195impl AsRef<FileMetadata> for ServerFile {
196    fn as_ref(&self) -> &FileMetadata {
197        self.file.as_ref()
198    }
199}
200
201impl FileLike for SignedMeta {
202    fn id(&self) -> &Uuid {
203        self.timestamped_value.value.id()
204    }
205
206    fn file_type(&self) -> FileType {
207        self.timestamped_value.value.file_type()
208    }
209
210    fn parent(&self) -> &Uuid {
211        self.timestamped_value.value.parent()
212    }
213
214    fn secret_name(&self) -> &SecretFileName {
215        self.timestamped_value.value.secret_name()
216    }
217
218    fn owner(&self) -> Owner {
219        self.timestamped_value.value.owner()
220    }
221
222    fn explicitly_deleted(&self) -> bool {
223        self.timestamped_value.value.explicitly_deleted()
224    }
225
226    fn document_hmac(&self) -> Option<&DocumentHmac> {
227        self.timestamped_value.value.document_hmac()
228    }
229
230    fn user_access_keys(&self) -> &Vec<UserAccessInfo> {
231        self.timestamped_value.value.user_access_keys()
232    }
233
234    fn folder_access_key(&self) -> &EncryptedFolderAccessKey {
235        self.timestamped_value.value.folder_access_key()
236    }
237
238    fn doc_size(&self) -> Option<usize> {
239        *self.timestamped_value.value.doc_size()
240    }
241}
242
243impl FileLike for ServerMeta {
244    fn id(&self) -> &Uuid {
245        self.file.timestamped_value.value.id()
246    }
247
248    fn file_type(&self) -> FileType {
249        self.file.timestamped_value.value.file_type()
250    }
251
252    fn parent(&self) -> &Uuid {
253        self.file.timestamped_value.value.parent()
254    }
255
256    fn secret_name(&self) -> &SecretFileName {
257        self.file.timestamped_value.value.secret_name()
258    }
259
260    fn owner(&self) -> Owner {
261        self.file.timestamped_value.value.owner()
262    }
263
264    fn explicitly_deleted(&self) -> bool {
265        self.file.timestamped_value.value.explicitly_deleted()
266    }
267
268    fn document_hmac(&self) -> Option<&DocumentHmac> {
269        self.file.timestamped_value.value.document_hmac()
270    }
271
272    fn user_access_keys(&self) -> &Vec<UserAccessInfo> {
273        self.file.timestamped_value.value.user_access_keys()
274    }
275
276    fn folder_access_key(&self) -> &EncryptedFolderAccessKey {
277        self.file.timestamped_value.value.folder_access_key()
278    }
279
280    fn doc_size(&self) -> Option<usize> {
281        *self.file.timestamped_value.value.doc_size()
282    }
283}