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