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}