ankurah_core/
storage.rs

1use std::sync::Arc;
2
3use async_trait::async_trait;
4
5use crate::error::RetrievalError;
6use ankurah_proto::{CollectionId, Event, State, ID};
7
8pub fn state_name(name: &str) -> String { format!("{}_state", name) }
9
10pub fn event_name(name: &str) -> String { format!("{}_event", name) }
11
12#[async_trait]
13pub trait StorageEngine: Send + Sync {
14    type Value;
15    // Opens and/or creates a storage collection.
16    async fn collection(&self, id: &CollectionId) -> Result<Arc<dyn StorageCollection>, RetrievalError>;
17}
18
19#[async_trait]
20pub trait StorageCollection: Send + Sync {
21    // TODO - implement merge_states based on event history.
22    // Consider whether to play events forward from a prior checkpoint (probably this)
23    // or maybe to require PropertyBackends to be able to merge states.
24    async fn set_state(&self, id: ID, state: &State) -> anyhow::Result<bool>;
25    async fn get_state(&self, id: ID) -> Result<State, RetrievalError>;
26
27    // Fetch raw entity states matching a predicate
28    async fn fetch_states(&self, predicate: &ankql::ast::Predicate) -> Result<Vec<(ID, State)>, RetrievalError>;
29
30    async fn set_states(&self, entities: Vec<(ID, &State)>) -> anyhow::Result<()> {
31        for (id, state) in entities {
32            self.set_state(id, state).await?;
33        }
34        Ok(())
35    }
36
37    // TODO:
38    async fn add_event(&self, entity_event: &Event) -> anyhow::Result<bool>;
39    async fn get_events(&self, id: ID) -> Result<Vec<Event>, crate::error::RetrievalError>;
40}
41
42/// Manages the storage and state of the collection without any knowledge of the model type
43#[derive(Clone)]
44pub struct StorageCollectionWrapper(pub(crate) Arc<dyn StorageCollection>);
45
46/// Storage interface for a collection
47impl StorageCollectionWrapper {
48    pub fn new(bucket: Arc<dyn StorageCollection>) -> Self { Self(bucket) }
49}
50
51impl std::ops::Deref for StorageCollectionWrapper {
52    type Target = Arc<dyn StorageCollection>;
53    fn deref(&self) -> &Self::Target { &self.0 }
54}