nstreams-core 0.3.1

Generic versioned event stream handler with history replay
Documentation
use crate::event::{EventVersion, StreamEvent};

/// Tracks the last delivered version for gapless client-side verification.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VersionedDelivery {
    pub version: EventVersion,
}

impl VersionedDelivery {
    pub fn first(version: EventVersion) -> Self {
        Self { version }
    }

    /// Verify that `event` continues the monotonic version sequence.
    pub fn verify_next(&self, event: &StreamEvent) -> crate::Result<EventVersion> {
        let expected = self.version.saturating_add(1);
        if event.version != expected {
            return Err(crate::Error::VersionGap {
                expected,
                actual: event.version,
            });
        }
        Ok(event.version)
    }

    /// Verify the first event in a replay sequence.
    pub fn verify_initial(
        last_delivered: Option<EventVersion>,
        event: &StreamEvent,
    ) -> crate::Result<EventVersion> {
        match last_delivered {
            Some(last) => VersionedDelivery { version: last }.verify_next(event),
            None => Ok(event.version),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn detects_version_gaps() {
        let delivery = VersionedDelivery::first(10);
        let event = StreamEvent {
            namespace: "test".into(),
            version: 12,
            payload: vec![],
            filter_value: None,
        };
        assert!(matches!(
            delivery.verify_next(&event),
            Err(crate::Error::VersionGap {
                expected: 11,
                actual: 12
            })
        ));
    }
}