use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use serde_json::Value;
use uuid::Uuid;
use crate::{domain_id::DomainIds, error::SerializationError};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct EventEnvelope {
pub timestamp: DateTime<Utc>,
pub correlation_id: Uuid,
pub causation_id: Uuid,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub triggering_event_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub idempotency_key: Option<Uuid>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct StoredEvent<T> {
pub id: Uuid,
pub position: u64,
pub event_type: String,
pub tags: Vec<String>,
pub timestamp: DateTime<Utc>,
pub correlation_id: Uuid,
pub causation_id: Uuid,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub triggering_event_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub idempotency_key: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub encryption_scope: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub encryption_key_id: Option<Uuid>,
pub data: T,
}
impl<T> StoredEvent<T> {
pub fn with_data<U>(self, data: U) -> StoredEvent<U> {
StoredEvent {
id: self.id,
position: self.position,
event_type: self.event_type,
tags: self.tags,
timestamp: self.timestamp,
correlation_id: self.correlation_id,
causation_id: self.causation_id,
triggering_event_id: self.triggering_event_id,
idempotency_key: self.idempotency_key,
encryption_scope: self.encryption_scope,
encryption_key_id: self.encryption_key_id,
data,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct StoredEventData<T> {
pub timestamp: DateTime<Utc>,
pub correlation_id: Uuid,
pub causation_id: Uuid,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub triggering_event_id: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub idempotency_key: Option<Uuid>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub encryption_scope: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub encryption_key_id: Option<Uuid>,
pub data: T,
}
pub trait Event: DomainIds + Serialize + DeserializeOwned + Sized {
const EVENT_TYPE: &'static str;
fn encryption_scope(&self) -> Option<String> {
None
}
}
#[derive(Clone, Copy, Debug)]
pub struct EventDomainId {
pub event_type: &'static str,
pub dynamic_fields: &'static [&'static str],
pub static_fields: &'static [(&'static str, &'static str)],
}
pub trait EventSet: Sized {
type Item;
fn event_types() -> Vec<&'static str>;
fn event_domain_ids() -> Vec<EventDomainId>;
fn from_event(event_type: &str, data: &Value)
-> Option<Result<Self::Item, SerializationError>>;
}
pub trait AsEvent<E> {
fn as_event(&self) -> Option<&E>;
}
pub trait IntoEvent<E> {
fn into_event(self) -> Option<E>;
}