diff options
Diffstat (limited to 'src/access')
| -rw-r--r-- | src/access/screen.rs | 43 |
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 { |
