nstreams-core 0.2.2

Generic versioned event stream handler with history replay
Documentation
use serde::{Deserialize, Serialize};

/// A monotonically increasing version assigned per namespace stream.
pub type EventVersion = u64;

/// Wire envelope for a versioned stream event (internal / typed use).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct StreamEventEnvelope<T> {
    pub version: EventVersion,
    pub payload: T,
}

/// Event delivered to a subscriber. Namespace is fixed per subscription so it is omitted.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DeliveredEvent {
    pub request_id: String,
    pub version: EventVersion,
    pub payload: Vec<u8>,
}

impl DeliveredEvent {
    pub fn from_stream_event(request_id: impl Into<String>, event: &StreamEvent) -> Self {
        Self {
            request_id: request_id.into(),
            version: event.version,
            payload: event.payload.clone(),
        }
    }

    pub fn payload_json<T: for<'de> Deserialize<'de>>(&self) -> crate::Result<T> {
        serde_json::from_slice(&self.payload)
            .map_err(|e| crate::Error::Serialization(e.to_string()))
    }
}

/// Opaque serialized event stored in backends.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StreamEvent {
    pub namespace: String,
    pub version: EventVersion,
    pub payload: Vec<u8>,
    /// Bloom filter value (`x-stream-filter-value`) when set at publish time.
    pub filter_value: Option<String>,
}

impl StreamEvent {
    pub fn envelope<T: for<'de> Deserialize<'de>>(
        &self,
    ) -> crate::Result<StreamEventEnvelope<T>> {
        let payload = serde_json::from_slice(&self.payload)
            .map_err(|e| crate::Error::Serialization(e.to_string()))?;
        Ok(StreamEventEnvelope {
            version: self.version,
            payload,
        })
    }
}

/// Encodes and decodes typed payloads for a namespace.
pub trait EventCodec: Send + Sync {
    type Event: Serialize + for<'de> Deserialize<'de> + Send + Sync;

    fn encode(&self, event: &Self::Event) -> crate::Result<Vec<u8>> {
        serde_json::to_vec(event).map_err(|e| crate::Error::Serialization(e.to_string()))
    }

    fn decode(&self, bytes: &[u8]) -> crate::Result<Self::Event> {
        serde_json::from_slice(bytes).map_err(|e| crate::Error::Serialization(e.to_string()))
    }
}