1use crate::LocalLb;
2use crate::model::errors::{LbErrKind, LbResult};
3use crate::model::file_like::FileLike;
4use crate::model::tree_like::TreeLike;
5use uuid::Uuid;
6
7impl LocalLb {
8 #[instrument(level = "debug", skip(self), err(Debug))]
9 pub async fn pin_file(&self, id: Uuid) -> LbResult<()> {
10 let mut tx = self.begin_tx().await;
11 let db = tx.db();
12
13 let mut tree = (&db.base_metadata).to_staged(&db.local_metadata).to_lazy();
14
15 let file = tree.maybe_find(&id).ok_or(LbErrKind::FileNonexistent)?;
16
17 if !file.is_document() {
18 return Err(LbErrKind::FileNotDocument.into());
19 }
20
21 if tree.calculate_deleted(&id)? {
22 return Err(LbErrKind::FileNonexistent.into());
23 }
24
25 if db.pinned_files.get().contains(&id) {
26 return Ok(());
27 }
28
29 db.pinned_files.push(id)?;
30 Ok(())
31 }
32
33 #[instrument(level = "debug", skip(self), err(Debug))]
34 pub async fn unpin_file(&self, id: Uuid) -> LbResult<()> {
35 let mut tx = self.begin_tx().await;
36 let db = tx.db();
37
38 let entries: Vec<Uuid> = db
39 .pinned_files
40 .get()
41 .iter()
42 .filter(|pinned| **pinned != id)
43 .copied()
44 .collect();
45
46 db.pinned_files.clear()?;
47 for entry in entries {
48 db.pinned_files.push(entry)?;
49 }
50
51 Ok(())
52 }
53
54 #[instrument(level = "debug", skip(self), err(Debug))]
55 pub async fn list_pinned(&self) -> LbResult<Vec<Uuid>> {
56 let db = self.ro_tx().await;
57 let db = db.db();
58
59 let mut tree = (&db.base_metadata).to_staged(&db.local_metadata).to_lazy();
60
61 let mut result = Vec::new();
62 for id in db.pinned_files.get().iter() {
63 if tree.maybe_find(id).is_none() {
64 continue;
65 }
66 if tree.calculate_deleted(id)? {
67 continue;
68 }
69 if tree.in_pending_share(id)? {
70 continue;
71 }
72 result.push(*id);
73 }
74
75 Ok(result)
76 }
77}