Skip to main content

ravenrs_app/
files.rs

1//! Where the content of attached files is kept, apart from the records that point to them.
2
3use std::cell::{Cell, RefCell};
4use std::collections::BTreeMap;
5
6/// Keeps the content of files, and gives a key for each. A record holds only that key, so reading
7/// a list does not read every file.
8pub trait AttachmentStore {
9    /// Keeps a file, and says the key to find it by.
10    fn put(&self, name: &str, bytes: &[u8]) -> Result<String, String>;
11    /// The content kept under this key; nothing if it is gone.
12    fn get(&self, key: &str) -> Result<Option<Vec<u8>>, String>;
13    /// Forgets what is kept under this key.
14    fn remove(&self, key: &str) -> Result<(), String>;
15}
16
17/// Files that last as long as the program, as on the web with no server.
18#[derive(Debug, Default)]
19#[cfg_attr(feature = "live", ravenrs_live::expose(part = "fields"))]
20pub struct MemoryAttachmentStore {
21    files: RefCell<BTreeMap<String, Vec<u8>>>,
22    next: Cell<u64>,
23}
24
25impl AttachmentStore for MemoryAttachmentStore {
26    fn put(&self, _name: &str, bytes: &[u8]) -> Result<String, String> {
27        let key = self.next.get() + 1;
28        self.next.set(key);
29        self.files.borrow_mut().insert(key.to_string(), bytes.to_vec());
30        Ok(key.to_string())
31    }
32
33    fn get(&self, key: &str) -> Result<Option<Vec<u8>>, String> {
34        Ok(self.files.borrow().get(key).cloned())
35    }
36
37    fn remove(&self, key: &str) -> Result<(), String> {
38        self.files.borrow_mut().remove(key);
39        Ok(())
40    }
41}