pub fn fold(
events: &[MeshEvent],
liveness: &dyn Fn(&StreamId) -> StreamLiveness,
) -> CooperationStateExpand description
Fold events into state. liveness answers for each stream; the caller supplies the
journal’s verdicts, a test supplies whatever it is testing.
Liveness is a parameter rather than something read here because it is the one input that is not in the events: whether a stream still beats is a local observation, and making it an argument is what keeps the fold itself pure — the same events with the same verdicts give the same state, in any order and however often they are repeated.
use std::sync::Arc;
use majordomus_cli::mesh::identity::NodeIdentity;
use majordomus_cli::mesh::journal::{ClaimMode, EventBody, Journal, StreamLiveness};
use majordomus_cli::mesh::state::{fold, ClaimState};
let j = Journal::open(Arc::new(NodeIdentity::ephemeral().unwrap()), "0000000000000001",
"repo".into(), None).unwrap();
j.append_own(EventBody::ClaimAcquired { claim: "c1".into(), session: "s1".into(),
scope: vec!["apps".into()], intent: None, mode: ClaimMode::Exclusive, issue: None })
.unwrap();
// read where the writer is alive, the claim holds
let here = fold(&j.events(), &|_| StreamLiveness::Own);
assert_eq!(here.claims[0].state, ClaimState::Held);
// read where its beat has stopped, it ended on its own; nobody released it
let elsewhere = fold(&j.events(), &|_| StreamLiveness::Expired);
assert!(matches!(elsewhere.claims[0].state, ClaimState::Expired(_)));