unistore 0.3.0

simple storage abstraction that works on wasm and native Targets
Documentation
use crate::{AsKey, Key, UniTable, Value};

pub struct UniIndex<'a, I: Key, K: Key, V: Value> {
    pub table: &'a UniTable<'a, K, V>,
    pub index: UniTable<'a, String, ()>,
    phantom: std::marker::PhantomData<I>,
}

impl<I: Key, K: Key, V: Value> std::fmt::Debug for UniIndex<'_, I, K, V> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("UniIndex")
            .field("table", &self.table.name)
            .field("index", &self.index.name)
            .finish()
    }
}

impl<I: Key, K: Key + Clone, V: Value> UniIndex<'_, I, K, V> {
    pub async fn get(&self, key: impl AsKey<I>) -> Result<Vec<(K, V)>, crate::Error> {
        let index_entries = self.index.get_prefix(key.as_key().to_key_string()).await?;
        let mut results = Vec::new();
        for (index_key, _) in index_entries {
            let (_, key) = index_key
                .split_once('\0')
                .expect("Index key should contain a separator");
            let key = K::from_key_string(key)?;
            if let Some(value) = self.table.get(key.clone()).await? {
                results.push((key, value));
            }
        }
        Ok(results)
    }

    pub async fn insert(
        &self,
        value: impl AsKey<I>,
        key: impl AsKey<K>,
    ) -> Result<(), crate::Error> {
        let key = key.as_key();
        let index_key = format!(
            "{}\0{}",
            value.as_key().to_key_string(),
            key.as_key().to_key_string()
        );
        self.index.insert(index_key, ()).await?;
        Ok(())
    }
}

impl<K: Key, V: Value> UniTable<'_, K, V> {
    pub async fn create_index<I: Key>(
        &self,
        index: &'static str,
    ) -> Result<UniIndex<'_, I, K, V>, crate::Error> {
        let index_table = self
            .store
            .create_table(&format!("{}_index_{index}", self.name), false)
            .await?;
        Ok(UniIndex {
            table: self,
            index: index_table,
            phantom: std::marker::PhantomData,
        })
    }
}