lockbook_shared/
file_like.rs

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