Skip to main content

fold

Function fold 

Source
pub fn fold(
    events: &[MeshEvent],
    liveness: &dyn Fn(&StreamId) -> StreamLiveness,
) -> CooperationState
Expand 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(_)));