nitinol_protocol/
payload.rs

1use std::cmp::Ordering;
2use std::fmt::{Debug, Formatter};
3use time::OffsetDateTime;
4use nitinol_core::errors::{DeserializeError, SerializeError};
5use nitinol_core::event::Event;
6use nitinol_core::identifier::EntityId;
7
8/// Basic format of the data to be saved.
9#[derive(Clone)]
10#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
11pub struct Payload {
12    /// Aggregate entity identifier
13    pub id: String,
14    /// Unique sequence value at a specific Entity
15    pub sequence_id: i64,
16    /// Unique id for each data format used in [`ResolveMapping`](nitinol_core::mapping::ResolveMapping)
17    pub registry_key: String,
18    /// Data body in binary format
19    pub bytes: Vec<u8>,
20    /// Time the Event was generated
21    pub created_at: OffsetDateTime
22}
23
24impl Payload {
25    pub fn new<E: Event>(aggregate_id: EntityId, seq: i64, event: &E) -> Result<Self, SerializeError> {
26        Ok(Self {
27            id: aggregate_id.to_string(),
28            sequence_id: seq,
29            registry_key: E::EVENT_TYPE.to_string(),
30            bytes: event.as_bytes()?,
31            created_at: OffsetDateTime::now_utc()
32        })
33    }
34    
35    pub fn to_event<E: Event>(&self) -> Result<E, DeserializeError> {
36        E::from_bytes(&self.bytes)
37    }
38}
39
40impl Debug for Payload {
41    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42        f.debug_struct(format!("Payload#{}", self.registry_key).as_str())
43            .field("id", &self.id)
44            .field("sequence", &self.sequence_id)
45            .field("bytes", &format!("<{} bytes>", self.bytes.len()))
46            .field("created_at", &self.created_at)
47            .finish()
48    }
49}
50
51impl Eq for Payload {}
52
53impl PartialEq<Self> for Payload {
54    fn eq(&self, other: &Self) -> bool {
55        self.sequence_id.eq(&other.sequence_id)
56        && self.id.eq(&other.id)
57        && self.created_at.eq(&other.created_at)
58    }
59}
60
61impl PartialOrd<Self> for Payload {
62    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
63        Some(self.cmp(other))
64    }
65}
66
67impl Ord for Payload {
68    fn cmp(&self, other: &Self) -> Ordering {
69        self.sequence_id.cmp(&other.sequence_id)
70            .then_with(|| self.created_at.cmp(&other.created_at))
71            .then_with(|| self.id.cmp(&other.id))
72    }
73}