use crate::event::vector_clock::VectorClock;
use crate::event::{JournalEvent, JournalWriterId};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct JournalGroupMember {
pub index: u32,
pub size: u32,
}
#[derive(Debug, Clone)]
pub struct EventEnvelope<T>
where
T: JournalEvent,
{
pub journal_writer_id: JournalWriterId,
pub vector_clock: VectorClock,
pub timestamp: DateTime<Utc>,
pub journal_group_id: Option<String>,
pub journal_group_member: Option<JournalGroupMember>,
pub event: T,
}
impl<T> Serialize for EventEnvelope<T>
where
T: JournalEvent,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("EventEnvelope", 6)?;
state.serialize_field("journal_writer_id", &self.journal_writer_id)?;
state.serialize_field("vector_clock", &self.vector_clock)?;
state.serialize_field("timestamp", &self.timestamp)?;
state.serialize_field("journal_group_id", &self.journal_group_id)?;
state.serialize_field("journal_group_member", &self.journal_group_member)?;
state.serialize_field("event", &self.event)?;
state.end()
}
}
impl<'de, T> Deserialize<'de> for EventEnvelope<T>
where
T: JournalEvent,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Deserialize)]
struct EventEnvelopeData<T> {
journal_writer_id: JournalWriterId,
vector_clock: VectorClock,
timestamp: DateTime<Utc>,
#[serde(default)]
journal_group_id: Option<String>,
#[serde(default)]
journal_group_member: Option<JournalGroupMember>,
event: T,
}
let data = EventEnvelopeData::<T>::deserialize(deserializer)?;
Ok(EventEnvelope {
journal_writer_id: data.journal_writer_id,
vector_clock: data.vector_clock,
timestamp: data.timestamp,
journal_group_id: data.journal_group_id,
journal_group_member: data.journal_group_member,
event: data.event,
})
}
}
impl<T> EventEnvelope<T>
where
T: JournalEvent,
{
pub fn new(journal_writer_id: JournalWriterId, event: T) -> Self {
Self {
journal_writer_id,
vector_clock: VectorClock::new(),
timestamp: Utc::now(),
journal_group_id: None,
journal_group_member: None,
event,
}
}
}
use super::chain_event::ChainEvent;
use super::system_event::SystemEvent;
pub type ChainEventEnvelope = EventEnvelope<ChainEvent>;
pub type SystemEventEnvelope = EventEnvelope<SystemEvent>;