1use std::{fmt, hash};
2
3use crate::{ActorId, EventId, Meta};
4
5#[derive(Clone)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12#[cfg_attr(
13 feature = "serde",
14 serde(bound(
15 serialize = "E: serde::Serialize",
16 deserialize = "E: serde::de::DeserializeOwned"
17 ))
18)]
19pub struct Envelope<E> {
20 meta: Meta,
21 event: E,
22}
23
24impl<E> Envelope<E> {
25 #[must_use]
27 pub fn new(event: E, actor_id: ActorId) -> Self {
28 Self {
29 meta: Meta::new(actor_id, None),
30 event,
31 }
32 }
33
34 #[must_use]
40 pub fn with_parent_id(mut self, parent_id: EventId) -> Self {
41 self.meta.set_parent(parent_id);
42 self
43 }
44
45 #[inline]
58 pub fn event(&self) -> &E {
59 &self.event
60 }
61
62 #[inline]
64 pub fn meta(&self) -> &Meta {
65 &self.meta
66 }
67
68 #[inline]
70 pub fn id(&self) -> EventId {
71 self.meta.id()
72 }
73}
74
75impl<E: PartialEq> PartialEq for Envelope<E> {
76 fn eq(&self, other: &Self) -> bool {
77 self.meta.id() == other.meta.id() && self.event == other.event
78 }
79}
80
81impl<E: Eq> Eq for Envelope<E> {}
82
83impl<E: hash::Hash> hash::Hash for Envelope<E> {
84 fn hash<H: hash::Hasher>(&self, state: &mut H) {
85 self.meta.id().hash(state);
86 self.event.hash(state);
87 }
88}
89
90impl<E: fmt::Debug> fmt::Debug for Envelope<E> {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 f.debug_struct("Envelope")
93 .field("id", &self.meta.id())
94 .field("sender", &self.meta.actor_name())
95 .field("event", &self.event)
96 .field("timestamp", &self.meta.timestamp())
97 .field("parent_id", &self.meta.parent_id())
98 .finish()
99 }
100}
101
102impl<E: fmt::Display> fmt::Display for Envelope<E> {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 write!(
105 f,
106 "Envelope {{ id: {}, sender: {}, event: {} }}",
107 self.meta.id(),
108 self.meta.actor_name(),
109 self.event
110 )
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117 use crate::Event;
118
119 #[derive(Clone, Debug)]
120 #[allow(unused)]
121 struct TestEvent(i32);
122 impl Event for TestEvent {}
123
124 #[test]
125 fn envelope_debug() {
126 let actor = ActorId::new("test-actor");
127 let envelope = Envelope::new(TestEvent(42), actor);
128 let debug_str = format!("{:?}", envelope);
129
130 assert!(debug_str.contains("TestEvent"));
131 assert!(debug_str.contains("42"));
132 assert!(debug_str.contains("test-actor"));
133 }
134}