lockbook_shared/
file_like.rs1use std::fmt::Debug;
2
3use uuid::Uuid;
4
5use crate::access_info::{EncryptedFolderAccessKey, UserAccessInfo, UserAccessMode};
6use crate::file_metadata::{DocumentHmac, FileMetadata, FileType, Owner};
7use crate::secret_filename::SecretFileName;
8use crate::server_file::ServerFile;
9use crate::signed_file::SignedFile;
10
11pub trait FileLike: PartialEq + Debug + Clone + AsRef<FileMetadata> {
12 fn id(&self) -> &Uuid;
13 fn file_type(&self) -> FileType;
14 fn parent(&self) -> &Uuid;
15 fn secret_name(&self) -> &SecretFileName;
16 fn owner(&self) -> Owner;
17 fn explicitly_deleted(&self) -> bool;
18 fn document_hmac(&self) -> Option<&DocumentHmac>;
19 fn display(&self) -> String;
20 fn user_access_keys(&self) -> &Vec<UserAccessInfo>;
21 fn folder_access_key(&self) -> &EncryptedFolderAccessKey;
22
23 fn is_folder(&self) -> bool {
24 self.file_type() == FileType::Folder
25 }
26
27 fn is_link(&self) -> bool {
28 matches!(self.file_type(), FileType::Link { .. })
29 }
30
31 fn is_document(&self) -> bool {
32 self.file_type() == FileType::Document
33 }
34
35 fn is_root(&self) -> bool {
36 self.id() == self.parent()
37 }
38
39 fn access_mode(&self, pk: &Owner) -> Option<UserAccessMode> {
40 self.user_access_keys()
41 .iter()
42 .filter(|k| !k.deleted)
43 .find(|k| k.encrypted_for == pk.0)
44 .map(|k| k.mode)
45 }
46
47 fn is_shared(&self) -> bool {
48 self.user_access_keys()
49 .iter()
50 .any(|k| !k.deleted && k.encrypted_for != k.encrypted_by)
51 }
52}
53
54impl<F> FileLike for F
55where
56 F: AsRef<FileMetadata> + PartialEq + Debug + Clone,
57{
58 fn id(&self) -> &Uuid {
59 let fm: &FileMetadata = self.as_ref();
60 &fm.id
61 }
62
63 fn file_type(&self) -> FileType {
64 let fm: &FileMetadata = self.as_ref();
65 fm.file_type
66 }
67
68 fn parent(&self) -> &Uuid {
69 let fm: &FileMetadata = self.as_ref();
70 &fm.parent
71 }
72
73 fn secret_name(&self) -> &SecretFileName {
74 let fm: &FileMetadata = self.as_ref();
75 &fm.name
76 }
77
78 fn owner(&self) -> Owner {
79 let fm: &FileMetadata = self.as_ref();
80 fm.owner
81 }
82
83 fn explicitly_deleted(&self) -> bool {
84 let fm: &FileMetadata = self.as_ref();
85 fm.is_deleted
86 }
87
88 fn document_hmac(&self) -> Option<&DocumentHmac> {
89 let fm: &FileMetadata = self.as_ref();
90 fm.document_hmac.as_ref()
91 }
92
93 fn display(&self) -> String {
94 let fm: &FileMetadata = self.as_ref();
95 match fm.file_type() {
96 FileType::Folder => format!("id: {}/", fm.id),
97 FileType::Document => format!("id: {}", fm.id),
98 FileType::Link { target } => format!("id: {}, target: {}", fm.id, target),
99 }
100 }
101
102 fn user_access_keys(&self) -> &Vec<UserAccessInfo> {
103 let fm: &FileMetadata = self.as_ref();
104 &fm.user_access_keys
105 }
106
107 fn folder_access_key(&self) -> &EncryptedFolderAccessKey {
108 let fm: &FileMetadata = self.as_ref();
109 &fm.folder_access_key
110 }
111}
112
113impl AsRef<FileMetadata> for FileMetadata {
114 fn as_ref(&self) -> &FileMetadata {
115 self
116 }
117}
118
119impl AsRef<FileMetadata> for SignedFile {
120 fn as_ref(&self) -> &FileMetadata {
121 &self.timestamped_value.value
122 }
123}
124
125impl AsRef<FileMetadata> for ServerFile {
126 fn as_ref(&self) -> &FileMetadata {
127 self.file.as_ref()
128 }
129}