cdevents_sdk/
cloudevents.rs1use cloudevents::{Data, Event};
2use time::format_description::well_known::Rfc3339;
3
4use crate::CDEvent;
5
6pub trait BuilderExt: Sized {
7 type Error;
8 fn with_cdevent(self, cdevent: CDEvent) -> Result<Self, Self::Error>;
9}
10
11impl BuilderExt for cloudevents::EventBuilderV10 {
12 type Error = cloudevents::message::Error;
13
14 fn with_cdevent(self, cdevent: CDEvent) -> Result<Self, Self::Error> {
15 Ok(
16 self.id(cdevent.id())
17 .ty(cdevent.ty())
18 .source(cdevent.source().as_str())
19 .subject(cdevent.subject().id())
20 .time(cdevent.timestamp().format(&Rfc3339).map_err(|e| Self::Error::Other{source: Box::new(e)})?)
21 .data("application/json", serde_json::to_value(cdevent).map_err(Self::Error::from)?)
22 )
23 }
24}
25
26impl TryFrom<CDEvent> for Event {
27 type Error = cloudevents::message::Error;
28
29 fn try_from(value: CDEvent) -> Result<Self, Self::Error> {
30 use ::cloudevents::{EventBuilder, EventBuilderV10};
31 EventBuilderV10::new()
32 .with_cdevent(value)?
33 .build().map_err(Self::Error::from)
34 }
35}
36
37impl TryFrom<Data> for CDEvent {
38 type Error = serde_json::Error;
39
40 fn try_from(value: Data) -> Result<Self, Self::Error> {
41 let json = match value {
42 Data::Binary(v) => serde_json::from_slice(&v)?,
43 Data::Json(v) => v,
44 Data::String(s) => serde_json::from_str(&s)?,
45 };
46 serde_json::from_value(json) }
48}
49
50impl TryFrom<Event> for CDEvent {
51 type Error = crate::Error;
52
53 fn try_from(value: Event) -> Result<Self, Self::Error> {
54 let mut event = value;
55 let (_, _, data) = event.take_data();
56 data.ok_or(Self::Error::DataNotFoundInCloudEvent)?
57 .try_into().map_err(Self::Error::from)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use ::cloudevents::{AttributesReader, EventBuilder, EventBuilderV10};
64 use crate::*;
65 use super::*;
66
67 #[test]
68 fn test_into_cloudevent() -> Result<(), Box<dyn std::error::Error>> {
69 let cdevent = CDEvent::from(
70 Subject::from(latest::build_queued::Content{})
71 .with_id("subject123".try_into()?)
72 .with_source("/event/source/123".try_into()?)
73 )
74 .with_id("271069a8-fc18-44f1-b38f-9d70a1695819".try_into()?)
75 .with_source("https://dev.cdevents".try_into()?)
76 ;
77
78 let cloudevent_via_builder = EventBuilderV10::new()
79 .with_cdevent(cdevent.clone())?
80 .build()?;
81 let mut cloudevent: Event = cdevent.clone().try_into()?;
82 assert_eq!(cloudevent_via_builder, cloudevent);
83
84 assert_eq!(cloudevent.id(), "271069a8-fc18-44f1-b38f-9d70a1695819");
85 assert_eq!(cloudevent.id(), cdevent.id().to_string());
86
87 let (_, _, data) = cloudevent.take_data();
88 let cdevent_extracted: CDEvent = data.ok_or(Error::DataNotFoundInCloudEvent)?.try_into()?;
89 assert_eq!(cloudevent.id(), cdevent_extracted.id().to_string());
90 assert_eq!(cdevent, cdevent_extracted);
91 Ok(())
92 }
93}