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 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}