use sim_kernel::{ContentId, Datum};
use thiserror::Error;
use crate::{JournalBackend, JournalError, JournalObject};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct StoredDatumRef {
pub meaning: ContentId,
pub storage: ContentId,
}
#[derive(Clone, Debug, PartialEq, Eq, Error)]
pub enum StoreError {
#[error(transparent)]
Journal(#[from] JournalError),
}
pub trait PersistentSemanticObjects {
fn put(&mut self, value: Datum) -> Result<StoredDatumRef, StoreError>;
fn get(&self, meaning: &ContentId) -> Result<Datum, StoreError>;
fn rebuild_index(&mut self) -> Result<Vec<StoredDatumRef>, StoreError>;
}
pub struct PersistentObjectStore<B> {
backend: B,
}
impl<B: JournalBackend> PersistentObjectStore<B> {
pub fn open(backend: B) -> Result<Self, StoreError> {
backend.rebuild_datum_index()?;
Ok(Self { backend })
}
pub fn into_inner(self) -> B {
self.backend
}
}
impl<B: JournalBackend> PersistentSemanticObjects for PersistentObjectStore<B> {
fn put(&mut self, value: Datum) -> Result<StoredDatumRef, StoreError> {
Ok(self.backend.put_datum(JournalObject::from_datum(value)?)?)
}
fn get(&self, meaning: &ContentId) -> Result<Datum, StoreError> {
let value = self.backend.get_datum(meaning)?;
if value
.content_id()
.map_err(|_| JournalError::NonCanonicalDatum)?
!= *meaning
{
return Err(JournalError::CorruptObject(meaning.clone()).into());
}
Ok(value)
}
fn rebuild_index(&mut self) -> Result<Vec<StoredDatumRef>, StoreError> {
Ok(self.backend.rebuild_datum_index()?)
}
}