aboutsummaryrefslogtreecommitdiffstats
path: root/src/access/screen.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/access/screen.rs')
-rw-r--r--src/access/screen.rs43
1 files changed, 41 insertions, 2 deletions
diff --git a/src/access/screen.rs b/src/access/screen.rs
index aa16b42..ae61416 100644
--- a/src/access/screen.rs
+++ b/src/access/screen.rs
@@ -433,7 +433,7 @@ pub(crate) fn apply(
if relevant(&paths[index]) || reaches_signed(doc, &paths[index]) {
// What rules read changed: in before the next is judged.
screened.applied += accepted.len();
- doc.apply_changes_log_patches(std::mem::take(&mut accepted), log)?;
+ apply_taken(doc, std::mem::take(&mut accepted), log)?;
frontier.clear();
} else {
frontier.insert(hash, seen_at);
@@ -460,7 +460,7 @@ pub(crate) fn apply(
}
screened.applied += accepted.len();
if !accepted.is_empty() {
- doc.apply_changes_log_patches(accepted, log)?;
+ apply_taken(doc, accepted, log)?;
}
for (hash, root) in refused {
refusals.insert(hash, root);
@@ -473,6 +473,45 @@ pub(crate) fn apply(
Ok(screened)
}
+/// `accepted` applied to `doc`. Automerge takes them all or none: one it won't take (a
+/// fork of an actor's changes, under a policy without signatures) fails the lot, so the
+/// error names them (the first few), with the node each says made it, for the log of
+/// whoever brought them.
+fn apply_taken(
+ doc: &mut Document,
+ accepted: Vec<Change>,
+ log: &mut crate::document::PatchLog,
+) -> Result<()> {
+ const NAMED: usize = 8;
+ let count = accepted.len();
+ let mut named: Vec<String> = accepted
+ .iter()
+ .take(NAMED)
+ .map(|change| {
+ let author = change
+ .author()
+ .and_then(|author| {
+ std::str::from_utf8(author.as_bytes())
+ .ok()
+ .map(str::to_owned)
+ })
+ .unwrap_or_else(|| "its actor's node".to_owned());
+ format!("{} (seq {} by {author})", change.hash(), change.seq())
+ })
+ .collect();
+ if count > NAMED {
+ named.push(format!("{} more", count - NAMED));
+ }
+ doc.apply_changes_log_patches(accepted, log)
+ .map_err(|error| {
+ anyhow::anyhow!(
+ "Automerge took none of the {count} changes judged: {error} ({})",
+ named.join(", ")
+ )
+ })?;
+ Ok(())
+}
+
/// What `apply_bytes` did.
#[derive(Debug, Default, Clone)]
pub(crate) struct Outcome {