summaryrefslogtreecommitdiffstats
path: root/src/document/store.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/document/store.rs')
-rw-r--r--src/document/store.rs29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/document/store.rs b/src/document/store.rs
index 9db8300..573b811 100644
--- a/src/document/store.rs
+++ b/src/document/store.rs
@@ -2,9 +2,9 @@
use anyhow::anyhow;
use automerge::{
- transaction::Transactable, ActorId, AutoCommit, ObjId, ObjType, ReadDoc, ScalarValue, Value,
+ ActorId, AutoCommit, ObjId, ObjType, ReadDoc, ScalarValue, Value, transaction::Transactable,
};
-use base64::{engine::general_purpose::STANDARD as BASE64, Engine};
+use base64::{Engine, engine::general_purpose::STANDARD as BASE64};
use serde::Serialize;
use serde_json::Value as JsonValue;
use std::collections::BTreeSet;
@@ -97,7 +97,7 @@ fn resolved_to_json(
let maps = match resolved {
Resolved::Maps(maps) => maps,
Resolved::Other(Value::Scalar(scalar), _) => {
- return scalar_to_json(scalar.clone().into_owned())
+ return scalar_to_json(scalar.clone().into_owned());
}
Resolved::Other(Value::Object(_), id) => return object_to_json(doc, id, log),
};
@@ -243,6 +243,29 @@ pub fn keys_at(doc: &AutoCommit, path: &[String]) -> Result<Vec<String>, StoreEr
Ok(merged_keys(doc, &maps).into_iter().collect())
}
+/// Every concurrent value at `path`, newest first; empty if there is none. Where
+/// `read_path` picks one (or merges concurrent maps into one), this keeps them apart.
+pub(crate) fn read_candidates(
+ doc: &AutoCommit,
+ path: &[String],
+) -> Result<Vec<JsonValue>, StoreError> {
+ let (leaf, parents) = path.split_last().ok_or(StoreError::NotFound)?;
+ let mut maps = vec![automerge::ROOT];
+ for segment in parents {
+ maps = match resolve(doc, &maps, segment, None)? {
+ Some(Resolved::Maps(next)) => next,
+ _ => return Ok(Vec::new()),
+ };
+ }
+ candidates(doc, &maps, leaf)?
+ .into_iter()
+ .map(|(value, id)| match value {
+ Value::Scalar(scalar) => scalar_to_json(scalar.into_owned()),
+ Value::Object(_) => object_to_json(doc, &id, None),
+ })
+ .collect()
+}
+
/// Writes (replaces) the value at `path`, creating intermediate maps.
pub fn write_path(
doc: &mut AutoCommit,