Skip to main content

weavatrix_memory/
event.rs

1use crate::{AgentId, EventId, MemoryError, Result, SessionId, StreamId, Timestamp};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
5pub struct NewEvent<E> {
6    pub id: EventId,
7    pub event_type: String,
8    pub occurred_at: Timestamp,
9    pub recorded_at: Timestamp,
10    pub agent_id: AgentId,
11    pub session_id: SessionId,
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub correlation_id: Option<EventId>,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub causation_id: Option<EventId>,
16    pub payload: E,
17}
18
19impl<E> NewEvent<E> {
20    /// Creates an uncommitted event with caller-controlled time and identity.
21    ///
22    /// # Errors
23    ///
24    /// Rejects an empty event type or surrounding whitespace.
25    pub fn new(
26        id: EventId,
27        event_type: impl Into<String>,
28        occurred_at: Timestamp,
29        recorded_at: Timestamp,
30        agent_id: AgentId,
31        session_id: SessionId,
32        payload: E,
33    ) -> Result<Self> {
34        let event_type = event_type.into();
35        if event_type.is_empty() || event_type.trim() != event_type {
36            return Err(MemoryError::InvalidValue {
37                field: "event_type",
38                reason: "must be non-empty without surrounding whitespace",
39            });
40        }
41        if occurred_at > recorded_at {
42            return Err(MemoryError::InvalidValue {
43                field: "occurred_at",
44                reason: "must not be later than recorded_at",
45            });
46        }
47        Ok(Self {
48            id,
49            event_type,
50            occurred_at,
51            recorded_at,
52            agent_id,
53            session_id,
54            correlation_id: None,
55            causation_id: None,
56            payload,
57        })
58    }
59
60    #[must_use]
61    pub fn correlated_with(mut self, id: EventId) -> Self {
62        self.correlation_id = Some(id);
63        self
64    }
65
66    #[must_use]
67    pub fn caused_by(mut self, id: EventId) -> Self {
68        self.causation_id = Some(id);
69        self
70    }
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
74pub struct EventMetadata {
75    pub id: EventId,
76    pub stream_id: StreamId,
77    pub stream_version: u64,
78    pub global_position: u64,
79    pub event_type: String,
80    pub occurred_at: Timestamp,
81    pub recorded_at: Timestamp,
82    pub agent_id: AgentId,
83    pub session_id: SessionId,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub correlation_id: Option<EventId>,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub causation_id: Option<EventId>,
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
91pub struct StoredEvent<E> {
92    pub metadata: EventMetadata,
93    pub payload: E,
94}