use std::path::Path;
use std::sync::{Arc, Mutex, MutexGuard};
use crate::core::{AppError, ErrorKind};
pub enum NativeThingdEngine {
Memory(thingd::MemoryEngine),
Persistent(thingd::PersistentEngine),
}
#[derive(Clone)]
pub struct NativeThingdStore {
engine: Arc<Mutex<NativeThingdEngine>>,
}
fn lock_engine(
store: &Mutex<NativeThingdEngine>,
) -> Result<MutexGuard<'_, NativeThingdEngine>, AppError> {
store.lock().map_err(|e| {
AppError::new(
ErrorKind::Internal,
format!("thingd engine mutex poisoned: {e}"),
)
})
}
impl NativeThingdStore {
#[must_use]
pub fn memory() -> Self {
Self {
engine: Arc::new(Mutex::new(NativeThingdEngine::Memory(
thingd::MemoryEngine::new(),
))),
}
}
pub fn persistent(path: impl AsRef<Path>) -> Result<Self, thingd::ThingdError> {
let engine = thingd::PersistentEngine::open(path)
.map_err(|error| thingd::ThingdError::Storage(error.to_string()))?;
Ok(Self {
engine: Arc::new(Mutex::new(NativeThingdEngine::Persistent(engine))),
})
}
pub fn with_engine<R>(
&self,
operation: impl FnOnce(&mut NativeThingdEngine) -> R,
) -> Result<R, AppError> {
let mut engine = lock_engine(&self.engine)?;
Ok(operation(&mut engine))
}
pub fn lock(&self) -> Result<MutexGuard<'_, NativeThingdEngine>, AppError> {
lock_engine(&self.engine)
}
}