Skip to main content

lb_rs/service/
pin.rs

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