use serde_json::Value;
use uuid::Uuid;
use crate::{
domain_id::DomainIdBindings,
error::SerializationError,
event::{Event, EventEnvelope, StoredEventData},
};
#[derive(Debug, Default)]
pub struct Emit {
events: Vec<EmitEvent>,
}
#[derive(Debug)]
pub struct EmitEvent {
pub event_type: String,
pub data: Value,
pub domain_ids: DomainIdBindings,
pub encryption_scope: Option<String>,
}
impl Emit {
pub fn new() -> Self {
Self { events: Vec::new() }
}
pub fn event<E: Event>(mut self, event: E) -> Self {
let emitted = EmitEvent::new(event);
self.events.push(emitted);
self
}
pub fn try_event<E: Event>(mut self, event: E) -> Result<Self, SerializationError> {
let domain_ids = event.domain_ids();
let encryption_scope = event.encryption_scope();
let emitted = EmitEvent {
event_type: E::EVENT_TYPE.to_string(),
data: serde_json::to_value(event)?,
domain_ids,
encryption_scope,
};
self.events.push(emitted);
Ok(self)
}
pub fn is_empty(&self) -> bool {
self.events.is_empty()
}
pub fn len(&self) -> usize {
self.events.len()
}
pub fn into_events(self) -> Vec<EmitEvent> {
self.events
}
pub fn events(&self) -> &[EmitEvent] {
&self.events
}
pub fn contains_event_type<E: Event>(&self) -> bool {
self.events
.iter()
.any(|event| event.event_type == E::EVENT_TYPE)
}
}
impl EmitEvent {
pub fn new<E: Event>(event: E) -> Self {
let domain_ids = event.domain_ids();
let encryption_scope = event.encryption_scope();
EmitEvent {
event_type: E::EVENT_TYPE.to_string(),
data: serde_json::to_value(event).expect("event serialization failed"),
domain_ids,
encryption_scope,
}
}
}
pub fn encode_with_envelope(
envelope: EventEnvelope,
data: Value,
encryption_scope: Option<String>,
encryption_key_id: Option<Uuid>,
) -> Vec<u8> {
serde_json::to_vec(&StoredEventData {
timestamp: envelope.timestamp,
correlation_id: envelope.correlation_id,
causation_id: envelope.causation_id,
triggering_event_id: envelope.triggering_event_id,
idempotency_key: envelope.idempotency_key,
encryption_scope,
encryption_key_id,
data,
})
.unwrap()
}