1mod attributes;
4mod builder;
5mod data;
6mod extensions;
7#[macro_use]
8mod format;
9mod message;
10mod spec_version;
11mod types;
12
13pub use attributes::Attributes;
14pub use attributes::{AttributeValue, AttributesReader, AttributesWriter};
15pub use builder::Error as EventBuilderError;
16pub use builder::EventBuilder;
17pub use data::Data;
18pub use extensions::ExtensionValue;
19pub(crate) use message::EventBinarySerializer;
20pub(crate) use message::EventStructuredSerializer;
21pub use spec_version::SpecVersion;
22pub use spec_version::UnknownSpecVersion;
23pub use types::{TryIntoTime, TryIntoUrl, UriReference};
24
25mod v03;
26
27pub use v03::Attributes as AttributesV03;
28pub(crate) use v03::AttributesIntoIterator as AttributesIntoIteratorV03;
29pub use v03::EventBuilder as EventBuilderV03;
30pub(crate) use v03::EventFormatDeserializer as EventFormatDeserializerV03;
31pub(crate) use v03::EventFormatSerializer as EventFormatSerializerV03;
32
33mod v10;
34
35pub use v10::Attributes as AttributesV10;
36pub(crate) use v10::AttributesIntoIterator as AttributesIntoIteratorV10;
37pub use v10::EventBuilder as EventBuilderV10;
38pub(crate) use v10::EventFormatDeserializer as EventFormatDeserializerV10;
39pub(crate) use v10::EventFormatSerializer as EventFormatSerializerV10;
40
41use chrono::{DateTime, Utc};
42use delegate_attr::delegate;
43use std::collections::HashMap;
44use std::fmt;
45use url::Url;
46
47#[derive(PartialEq, Eq, Debug, Clone)]
79pub struct Event {
80 pub(crate) attributes: Attributes,
81 pub(crate) data: Option<Data>,
82 pub(crate) extensions: HashMap<String, ExtensionValue>,
83}
84
85#[delegate(self.attributes)]
86impl AttributesReader for Event {
87 fn id(&self) -> &str {}
88 fn source(&self) -> &UriReference {}
89 fn specversion(&self) -> SpecVersion {}
90 fn ty(&self) -> &str {}
91 fn datacontenttype(&self) -> Option<&str> {}
92 fn dataschema(&self) -> Option<&Url> {}
93 fn subject(&self) -> Option<&str> {}
94 fn time(&self) -> Option<&DateTime<Utc>> {}
95}
96
97#[delegate(self.attributes)]
98impl AttributesWriter for Event {
99 fn set_id(&mut self, id: impl Into<String>) -> String {}
100 fn set_source(&mut self, source: impl Into<UriReference>) -> UriReference {}
101 fn set_type(&mut self, ty: impl Into<String>) -> String {}
102 fn set_subject(&mut self, subject: Option<impl Into<String>>) -> Option<String> {}
103 fn set_time(&mut self, time: Option<impl Into<DateTime<Utc>>>) -> Option<DateTime<Utc>> {}
104 fn set_datacontenttype(
105 &mut self,
106 datacontenttype: Option<impl Into<String>>,
107 ) -> Option<String> {
108 }
109 fn set_dataschema(&mut self, dataschema: Option<impl Into<Url>>) -> Option<Url> {}
110}
111
112impl Default for Event {
113 fn default() -> Self {
114 Event {
115 attributes: Attributes::V10(AttributesV10::default()),
116 data: None,
117 extensions: HashMap::default(),
118 }
119 }
120}
121
122impl fmt::Display for Event {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 writeln!(f, "CloudEvent:")?;
125 self.iter()
126 .try_for_each(|(name, val)| writeln!(f, " {}: '{}'", name, val))?;
127 match self.data() {
128 Some(data) => write!(f, " {}", data)?,
129 None => write!(f, " No data")?,
130 }
131 writeln!(f)
132 }
133}
134
135impl Event {
136 pub fn iter(&self) -> impl Iterator<Item = (&str, AttributeValue)> {
139 self.iter_attributes()
140 .chain(self.extensions.iter().map(|(k, v)| (k.as_str(), v.into())))
141 }
142
143 pub fn iter_attributes(&self) -> impl Iterator<Item = (&str, AttributeValue)> {
146 self.attributes.iter()
147 }
148
149 pub fn iter_extensions(&self) -> impl Iterator<Item = (&str, &ExtensionValue)> {
151 self.extensions.iter().map(|(k, v)| (k.as_str(), v))
152 }
153
154 pub fn data(&self) -> Option<&Data> {
156 self.data.as_ref()
157 }
158
159 pub fn take_data(&mut self) -> (Option<String>, Option<Url>, Option<Data>) {
172 (
173 self.attributes.set_datacontenttype(None as Option<String>),
174 self.attributes.set_dataschema(None as Option<Url>),
175 self.data.take(),
176 )
177 }
178
179 pub fn set_data(
191 &mut self,
192 datacontenttype: impl Into<String>,
193 data: impl Into<Data>,
194 ) -> (Option<String>, Option<Data>) {
195 (
196 self.attributes.set_datacontenttype(Some(datacontenttype)),
197 std::mem::replace(&mut self.data, Some(data.into())),
198 )
199 }
200
201 pub fn set_data_unchecked(&mut self, data: impl Into<Data>) -> Option<Data> {
213 std::mem::replace(&mut self.data, Some(data.into()))
214 }
215
216 pub fn extension(&self, extension_name: &str) -> Option<&ExtensionValue> {
218 self.extensions.get(extension_name)
219 }
220
221 pub fn set_extension<'name, 'event: 'name>(
223 &'event mut self,
224 extension_name: &'name str,
225 extension_value: impl Into<ExtensionValue>,
226 ) {
227 self.extensions
228 .insert(extension_name.to_owned(), extension_value.into());
229 }
230
231 pub fn remove_extension<'name, 'event: 'name>(
233 &'event mut self,
234 extension_name: &'name str,
235 ) -> Option<ExtensionValue> {
236 self.extensions.remove(extension_name)
237 }
238}
239
240#[cfg(test)]
241mod tests {
242 use super::*;
243
244 #[test]
245 fn take_data() {
246 let mut e = Event::default();
247 e.set_data(
248 "application/json",
249 serde_json::json!({
250 "hello": "world"
251 }),
252 );
253
254 let (datacontenttype, dataschema, data) = e.take_data();
255
256 assert!(datacontenttype.is_some());
257 assert!(dataschema.is_none());
258 assert!(data.is_some());
259
260 assert!(e.data().is_none());
261 assert!(e.dataschema().is_none());
262 assert!(e.datacontenttype().is_none());
263 }
264
265 #[test]
266 fn set_id() {
267 let mut e = Event::default();
268 e.set_id("001");
269
270 assert_eq!(e.set_id("002"), String::from("001"));
271 assert_eq!(e.id(), "002")
272 }
273
274 #[test]
275 fn iter() {
276 let mut e = Event::default();
277 e.set_extension("aaa", "bbb");
278 e.set_data(
279 "application/json",
280 serde_json::json!({
281 "hello": "world"
282 }),
283 );
284
285 let mut v: HashMap<&str, AttributeValue> = e.iter().collect();
286
287 assert_eq!(
288 v.remove("specversion"),
289 Some(AttributeValue::SpecVersion(SpecVersion::V10))
290 );
291 assert_eq!(v.remove("aaa"), Some(AttributeValue::String("bbb")))
292 }
293}