Skip to main content

lattice_db/props/
properties.rs

1use bincode::{Decode, Encode, config};
2use redb::ReadableTable;
3
4use crate::{
5    LatticeReader, LatticeWriter,
6    errors::LatticeError,
7    lattice_db::tables::{PROP_NAMES, PROPERTIES},
8};
9
10pub(crate) const QUERY_MATCH: u64 = u64::MAX;
11
12pub(crate) type PropertyId = u64;
13
14#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Encode, Decode)]
15pub struct PropertyHandle(pub(crate) PropertyId);
16
17impl LatticeWriter {
18    /// Register a property and return the handle.
19    /// * If an alias is provided, creates a fast property lookup.
20    /// * If the alias is taken, returns an error.
21    pub fn register_property<'a, A, M>(
22        &mut self,
23        alias: A,
24        meta: &M,
25    ) -> Result<PropertyHandle, LatticeError>
26    where
27        A: Into<Option<&'a str>>,
28        M: Encode,
29    {
30        // incr id
31        let id = self.property_id_cursor;
32        self.property_id_cursor += 1;
33
34        // assign alias, prevents collisions
35        let alias = alias.into();
36        if let Some(name) = alias {
37            let mut name_table = self.wt.open_table(PROP_NAMES)?;
38            if name_table.get(name)?.is_some() {
39                return Err(LatticeError::AliasAlreadyExists);
40            }
41
42            name_table.insert(name, id)?;
43        }
44
45        // write metadata
46        let mut meta_table = self.wt.open_table(PROPERTIES)?;
47        let meta_bytes = bincode::encode_to_vec(meta, config::standard())?;
48        meta_table.insert(id, meta_bytes)?;
49        Ok(PropertyHandle(id))
50    }
51}
52
53impl LatticeReader {
54    /// Get a property handle from an alias.
55    pub fn get_property_handle(&self, alias: &str) -> Result<Option<PropertyHandle>, LatticeError> {
56        let table = self.rt.open_table(PROP_NAMES)?;
57        Ok(table.get(alias)?.map(|v| PropertyHandle(v.value())))
58    }
59
60    /// Get the property metadata.
61    pub fn get_property_meta<M: Decode<()>>(
62        &self,
63        handle: PropertyHandle,
64    ) -> Result<M, LatticeError> {
65        let table = self.rt.open_table(PROPERTIES)?;
66        let bytes = table
67            .get(handle.0)?
68            .ok_or_else(|| LatticeError::PropertyNotFound)?
69            .value();
70        let (meta, _) = bincode::decode_from_slice(&bytes, config::standard())?;
71        Ok(meta)
72    }
73}