use serde::{Deserialize, Serialize, de::DeserializeOwned};
use serde_json::value::RawValue;
use std::borrow::Cow;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(transparent)]
pub struct EphemeralEventType(Cow<'static, str>);
impl EphemeralEventType {
pub const fn new(name: &'static str) -> Self {
Self(Cow::Borrowed(name))
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl std::fmt::Display for EphemeralEventType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
pub trait EphemeralEvent: Serialize + DeserializeOwned + Send + Sync + Unpin + 'static {
const EVENT_TYPE: EphemeralEventType;
}
pub trait EphemeralSelection: Send + Sync + Unpin + 'static + Sized {
const EVENT_TYPES: &'static [EphemeralEventType];
fn decode(
event_type: &EphemeralEventType,
payload: &RawValue,
) -> Option<Result<Self, serde_json::Error>>;
}
impl<T: EphemeralEvent> EphemeralSelection for T {
const EVENT_TYPES: &'static [EphemeralEventType] = &[T::EVENT_TYPE];
fn decode(
event_type: &EphemeralEventType,
payload: &RawValue,
) -> Option<Result<Self, serde_json::Error>> {
(*event_type == T::EVENT_TYPE).then(|| serde_json::from_str(payload.get()))
}
}
pub type RawPayload = Box<RawValue>;
#[derive(Debug, Serialize, Deserialize)]
#[serde(bound(deserialize = "P: DeserializeOwned"))]
pub struct EphemeralOutboxEvent<P> {
pub event_type: EphemeralEventType,
pub payload: P,
pub tracing_context: Option<es_entity::context::TracingContext>,
pub recorded_at: chrono::DateTime<chrono::Utc>,
}
impl<P> EphemeralOutboxEvent<P> {
#[cfg(feature = "tracing")]
pub fn inject_trace_parent(&self) {
if let Some(context) = &self.tracing_context {
context.inject_as_parent();
}
}
}