Skip to main content

oris_kernel/kernel/
reducer.rs

1//! Reducer: projects events onto state (pure functional semantics).
2//!
3//! Axiom: state is the projection of the event log. Reducer must be deterministic for replay.
4
5use serde::de::DeserializeOwned;
6
7use crate::kernel::event::{Event, SequencedEvent};
8use crate::kernel::state::KernelState;
9use crate::kernel::KernelError;
10
11/// Reducer applies events to state. Must be pure (deterministic) for replay.
12pub trait Reducer<S: KernelState>: Send + Sync {
13    /// Applies a single sequenced event to the state (in place).
14    fn apply(&self, state: &mut S, event: &SequencedEvent) -> Result<(), KernelError>;
15}
16
17/// Reducer that applies only StateUpdated (deserialize payload → replace state); other events no-op.
18/// Use for replay when the event log was produced by the graph (StateUpdated, Interrupted, Resumed, Completed).
19pub struct StateUpdatedOnlyReducer;
20
21impl<S> Reducer<S> for StateUpdatedOnlyReducer
22where
23    S: KernelState + DeserializeOwned,
24{
25    fn apply(&self, state: &mut S, event: &SequencedEvent) -> Result<(), KernelError> {
26        if let Event::StateUpdated { payload, .. } = &event.event {
27            let s: S = serde_json::from_value(payload.clone())
28                .map_err(|e| KernelError::EventStore(e.to_string()))?;
29            *state = s;
30        }
31        Ok(())
32    }
33}