Skip to main content

brdb/
tables.rs

1use crate::{compression::decompress, errors::BrFsError};
2
3#[derive(Clone, Debug)]
4pub struct BrBlob {
5    pub blob_id: i64,
6    pub compression: i64,
7    pub size_uncompressed: i64,
8    pub size_compressed: i64,
9    pub delta_base_id: Option<i64>, // always null
10    pub hash: Vec<u8>,
11    pub content: Vec<u8>,
12}
13
14impl BrBlob {
15    /// Get the BLAKE3 hash of the given content.
16    pub fn hash(content: &[u8]) -> [u8; 32] {
17        *blake3::hash(content).as_bytes()
18    }
19
20    /// Read (and decompress) the content of a blob in the brdb filesystem.
21    pub fn read(self) -> Result<Vec<u8>, BrFsError> {
22        let content = if self.compression == 0 {
23            self.content
24        } else {
25            // Ensure blob compressed content length is correct
26            if self.content.len() != self.size_compressed as usize {
27                return Err(BrFsError::InvalidSize {
28                    name: "compressed content".to_string(),
29                    found: self.content.len(),
30                    expected: self.size_compressed as usize,
31                });
32            }
33
34            // Decompress the content
35            decompress(&self.content, self.size_uncompressed as usize)
36                .map_err(BrFsError::Decompress)?
37        };
38
39        // Verify the size of the decompressed content
40        if content.len() != self.size_uncompressed as usize {
41            return Err(BrFsError::InvalidSize {
42                name: "uncompressed content".to_string(),
43                found: content.len(),
44                expected: self.size_uncompressed as usize,
45            });
46        }
47
48        let hash = Self::hash(&content);
49
50        // Verify the hash of the decompressed content
51        if hash != self.hash.as_slice() {
52            return Err(BrFsError::InvalidHash {
53                found: hash.to_vec(),
54                expected: self.hash,
55            });
56        }
57
58        Ok(content)
59    }
60}
61
62#[derive(Default, Clone, Debug)]
63pub struct BrRevision {
64    pub revision_id: i64,
65    pub description: String,
66    pub created_at: i64,
67}
68
69#[derive(Default, Clone, Debug)]
70pub struct BrFolder {
71    pub folder_id: i64,
72    pub parent_id: Option<i64>, // references folder_id
73    pub name: String,
74    pub created_at: i64,
75    pub deleted_at: Option<i64>,
76}
77
78#[derive(Default, Clone, Debug)]
79
80pub struct BrFile {
81    pub file_id: i64,
82    pub parent_id: Option<i64>, // references folders(folder_id),
83    pub name: String,
84    pub content_id: Option<i64>,
85    pub created_at: i64,
86    pub deleted_at: Option<i64>,
87}