Skip to main content

lb_rs/service/
pin.rs

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}