1use loftspec::codec::{self, Files};
4use loftspec::document::Document;
5use loftspec::hash::{Roots, hash_document};
6
7use crate::{DocumentStore, Saved, StoreError};
8
9#[derive(Debug, Clone, Default)]
11pub struct MemoryStore {
12 held: Option<(Document, Files)>,
13}
14
15impl MemoryStore {
16 #[must_use]
18 pub fn new() -> Self {
19 Self::default()
20 }
21
22 fn document(&self) -> Result<&Document, StoreError> {
23 self.held
24 .as_ref()
25 .map(|(document, _)| document)
26 .ok_or(StoreError::NoDocument)
27 }
28}
29
30impl DocumentStore for MemoryStore {
31 fn load(&self) -> Result<Document, StoreError> {
32 self.document().cloned()
33 }
34
35 fn save(&mut self, document: &Document) -> Result<Saved, StoreError> {
38 let next = codec::write(document);
39 let saved = match &self.held {
40 Some((_, current)) => Saved::between(current, &next),
41 None => Saved::between(&Files::new(), &next),
42 };
43 self.held = Some((document.clone(), next));
44 Ok(saved)
45 }
46
47 fn roots(&self) -> Result<Roots, StoreError> {
48 hash_document(self.document()?)
49 .map(|hashes| hashes.roots)
50 .map_err(StoreError::Index)
51 }
52}