Skip to main content

keket_redb/
lib.rs

1use keket::{database::path::AssetPath, fetch::container::ContainerPartialFetch};
2use redb::{Database, ReadableDatabase, TableDefinition};
3use std::error::Error;
4
5pub mod third_party {
6    pub use redb;
7}
8
9/// `RedbContainerPartialFetch` represents an asset fetcher that retrieves asset data
10/// stored in a Redb database.
11/// The fetcher uses the asset's `AssetPath` to find the corresponding asset in the database,
12/// reading the data from a specified table in the Redb database.
13pub struct RedbContainerPartialFetch {
14    database: Database,
15    default_table_name: String,
16}
17
18impl RedbContainerPartialFetch {
19    /// Creates a new `RedbContainerPartialFetch` instance using the provided database and default table name.
20    ///
21    /// # Arguments
22    /// - `database`: An instance of the Redb `Database` to use for querying.
23    /// - `default_table_name`: A string representing the default table name to use for querying.
24    ///
25    /// # Returns
26    /// - `Self`: A new `RedbContainerPartialFetch` initialized with the given database and table name.
27    pub fn new(database: Database, default_table_name: impl ToString) -> Self {
28        Self {
29            database,
30            default_table_name: default_table_name.to_string(),
31        }
32    }
33}
34
35impl ContainerPartialFetch for RedbContainerPartialFetch {
36    fn load_bytes(&mut self, path: AssetPath) -> Result<Vec<u8>, Box<dyn Error>> {
37        let transaction = self.database.begin_read()?;
38        let table_name = path.try_meta().unwrap_or(self.default_table_name.as_str());
39        let table_definition = TableDefinition::<String, Vec<u8>>::new(table_name);
40        let table = transaction.open_table(table_definition)?;
41        let access = table.get(path.path().to_owned())?;
42        let bytes = access.map(|access| access.value()).unwrap_or_default();
43        Ok(bytes)
44    }
45}