use std::{fmt, hash};
use crate::{ActorId, EventId, Meta};
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(
serialize = "E: serde::Serialize",
deserialize = "E: serde::de::DeserializeOwned"
))
)]
pub struct Envelope<E> {
meta: Meta,
event: E,
}
impl<E> Envelope<E> {
#[must_use]
pub fn new(event: E, actor_id: ActorId) -> Self {
Self {
meta: Meta::new(actor_id, None),
event,
}
}
#[must_use]
pub fn with_parent_id(mut self, parent_id: EventId) -> Self {
self.meta.set_parent(parent_id);
self
}
#[inline]
pub fn event(&self) -> &E {
&self.event
}
#[inline]
pub fn meta(&self) -> &Meta {
&self.meta
}
#[inline]
pub fn id(&self) -> EventId {
self.meta.id()
}
}
impl<E: PartialEq> PartialEq for Envelope<E> {
fn eq(&self, other: &Self) -> bool {
self.meta.id() == other.meta.id() && self.event == other.event
}
}
impl<E: Eq> Eq for Envelope<E> {}
impl<E: hash::Hash> hash::Hash for Envelope<E> {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.meta.id().hash(state);
self.event.hash(state);
}
}
impl<E: fmt::Debug> fmt::Debug for Envelope<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Envelope")
.field("id", &self.meta.id())
.field("sender", &self.meta.actor_name())
.field("event", &self.event)
.field("timestamp", &self.meta.timestamp())
.field("parent_id", &self.meta.parent_id())
.finish()
}
}
impl<E: fmt::Display> fmt::Display for Envelope<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Envelope {{ id: {}, sender: {}, event: {} }}",
self.meta.id(),
self.meta.actor_name(),
self.event
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Event;
#[derive(Clone, Debug)]
#[allow(unused)]
struct TestEvent(i32);
impl Event for TestEvent {}
#[test]
fn envelope_debug() {
let actor = ActorId::new("test-actor");
let envelope = Envelope::new(TestEvent(42), actor);
let debug_str = format!("{:?}", envelope);
assert!(debug_str.contains("TestEvent"));
assert!(debug_str.contains("42"));
assert!(debug_str.contains("test-actor"));
}
}