use std::io;
use std::path::Path;
use yog_data::Schema;
use yog_sync::{Arc, Mutex};
use crate::Scope;
use crate::shelf::{self, Shelf};
#[derive(Clone)]
pub struct Store {
shelf: Arc<Mutex<Shelf>>,
}
impl Store {
pub fn open(root: &Path, mod_id: &str, scope: Scope<'_>) -> Self {
Store {
shelf: shelf::file(scope.path(root, mod_id)),
}
}
pub fn session(mod_id: &str) -> Self {
Store {
shelf: shelf::session(mod_id),
}
}
pub fn get<T: Schema>(&self, key: &str) -> Option<T> {
yog_data::read_value(self.shelf.lock().values.get(key)?).ok()
}
pub fn get_or_default<T: Schema + Default>(&self, key: &str) -> T {
self.get(key).unwrap_or_default()
}
pub fn set<T: Schema>(&self, key: &str, value: &T) {
let mut shelf = self.shelf.lock();
shelf.values.insert(key, value.write());
shelf.dirty = true;
}
pub fn update<T: Schema + Default, R>(&self, key: &str, change: impl FnOnce(&mut T) -> R) -> R {
let mut value = self.get_or_default(key);
let out = change(&mut value);
self.set(key, &value);
out
}
pub fn remove(&self, key: &str) -> bool {
let mut shelf = self.shelf.lock();
let removed = shelf.values.remove(key).is_some();
shelf.dirty |= removed;
removed
}
pub fn contains(&self, key: &str) -> bool {
self.shelf.lock().values.get(key).is_some()
}
pub fn keys(&self) -> Vec<String> {
self.shelf.lock().values.keys().map(str::to_owned).collect()
}
pub fn flush(&self) -> io::Result<()> {
self.shelf.lock().flush()
}
}