use crate::{Error, Event, Result};
use cloudevents::event::{Data, Event as CeEvent, EventBuilder, EventBuilderV10};
use serde::Serialize;
use tracing::instrument;
use url::Url;
use uuid::Uuid;
#[derive(Debug, Clone)]
pub struct CloudEvent(pub CeEvent);
impl CloudEvent {
#[must_use]
pub fn into_inner(self) -> CeEvent {
self.0
}
#[instrument(skip(event))]
pub fn from_event_with_source<E>(event: E, source: Url) -> Result<Self>
where
E: Event + Serialize,
{
let id = Uuid::new_v4().to_string();
let data_json = serde_json::to_vec(&event)
.map_err(|e| Error::Validation(format!("failed to serialise event: {e}")))?;
let ce = EventBuilderV10::new()
.id(id)
.ty(event.event_type())
.source(source)
.data("application/json", Data::from(data_json))
.build()
.map_err(|e| Error::Validation(format!("failed to build CloudEvent: {e}")))?;
Ok(Self(ce))
}
}
impl<E> From<E> for CloudEvent
where
E: Event + Serialize,
{
fn from(event: E) -> Self {
let source_str = event.event_source();
let source = Url::parse(source_str)
.unwrap_or_else(|_| Url::parse("urn:sourcerer:event").expect("default URN is valid"));
Self::from_event_with_source(event, source).expect("constructing CloudEvent cannot fail")
}
}