1use std::io;
4use std::path::Path;
5
6use yog_data::Schema;
7use yog_sync::{Arc, Mutex};
8
9use crate::Scope;
10use crate::shelf::{self, Shelf};
11
12#[derive(Clone)]
15pub struct Store {
16 shelf: Arc<Mutex<Shelf>>,
17}
18
19impl Store {
20 pub fn open(root: &Path, mod_id: &str, scope: Scope<'_>) -> Self {
22 Store {
23 shelf: shelf::file(scope.path(root, mod_id)),
24 }
25 }
26
27 pub fn session(mod_id: &str) -> Self {
29 Store {
30 shelf: shelf::session(mod_id),
31 }
32 }
33
34 pub fn get<T: Schema>(&self, key: &str) -> Option<T> {
36 yog_data::read_value(self.shelf.lock().values.get(key)?).ok()
37 }
38
39 pub fn get_or_default<T: Schema + Default>(&self, key: &str) -> T {
41 self.get(key).unwrap_or_default()
42 }
43
44 pub fn set<T: Schema>(&self, key: &str, value: &T) {
46 let mut shelf = self.shelf.lock();
47 shelf.values.insert(key, value.write());
48 shelf.dirty = true;
49 }
50
51 pub fn update<T: Schema + Default, R>(&self, key: &str, change: impl FnOnce(&mut T) -> R) -> R {
53 let mut value = self.get_or_default(key);
54 let out = change(&mut value);
55 self.set(key, &value);
56 out
57 }
58
59 pub fn remove(&self, key: &str) -> bool {
61 let mut shelf = self.shelf.lock();
62 let removed = shelf.values.remove(key).is_some();
63 shelf.dirty |= removed;
64 removed
65 }
66
67 pub fn contains(&self, key: &str) -> bool {
68 self.shelf.lock().values.get(key).is_some()
69 }
70
71 pub fn keys(&self) -> Vec<String> {
73 self.shelf.lock().values.keys().map(str::to_owned).collect()
74 }
75
76 pub fn flush(&self) -> io::Result<()> {
78 self.shelf.lock().flush()
79 }
80}