use super::{Attributes, AttributesReader, AttributesWriter, Data, ExtensionValue, SpecVersion, AttributesV10};
use chrono::{DateTime, FixedOffset};
use delegate::delegate;
use std::convert::{TryFrom};
use crate::event::attributes::DataAttributesWriter;
pub struct Event {
pub attributes: Attributes,
pub data: Option<Data>,
}
impl AttributesReader for Event {
delegate! {
to self.attributes {
fn get_id(&self) -> &str;
fn get_source(&self) -> &str;
fn get_specversion(&self) -> SpecVersion;
fn get_type(&self) -> &str;
fn get_datacontenttype(&self) -> Option<&str>;
fn get_dataschema(&self) -> Option<&str>;
fn get_subject(&self) -> Option<&str>;
fn get_time(&self) -> Option<&DateTime<FixedOffset>>;
fn get_extension(&self, extension_name: &str) -> Option<&ExtensionValue>;
fn get_extensions(&self) -> Vec<(&str, &ExtensionValue)>;
}
}
}
impl AttributesWriter for Event {
delegate! {
to self.attributes {
fn set_id(&mut self, id: impl Into<String>);
fn set_source(&mut self, source: impl Into<String>);
fn set_type(&mut self, ty: impl Into<String>);
fn set_subject(&mut self, subject: Option<impl Into<String>>);
fn set_time(&mut self, time: Option<impl Into<DateTime<FixedOffset>>>);
fn set_extension<'name, 'event: 'name>(
&'event mut self,
extension_name: &'name str,
extension_value: impl Into<ExtensionValue>,
);
fn remove_extension<'name, 'event: 'name>(
&'event mut self,
extension_name: &'name str,
) -> Option<ExtensionValue>;
}
}
}
impl Default for Event {
fn default() -> Self {
Event {
attributes: Attributes::V10(AttributesV10::default()),
data: None
}
}
}
impl Event {
pub fn remove_data(&mut self) {
self.data = None;
}
pub fn write_data<S: Into<String>, D: Into<Data>>(&mut self, content_type: S, schema: Option<S>, value: D) {
self.attributes.set_datacontenttype(Some(content_type));
self.attributes.set_dataschema(schema);
self.data = Some(value.into());
}
pub fn get_data<T: Sized + From<Data>>(
&self,
) -> Option<T> {
match self.data.as_ref() {
Some(d) => Some(T::from(d.clone())),
None => None,
}
}
pub fn try_get_data<T: Sized + TryFrom<Data, Error = E>, E: std::error::Error>(
&self,
) -> Option<Result<T, E>> {
match self.data.as_ref() {
Some(d) => Some(T::try_from(d.clone())),
None => None,
}
}
pub fn into_data<T: Sized + TryFrom<Data, Error = E>, E: std::error::Error>(
self,
) -> Option<Result<T, E>> {
match self.data {
Some(d) => Some(T::try_from(d)),
None => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn try_get_data_json() {
let expected_data = serde_json::json!({
"hello": "world"
});
let mut e = Event::default();
e.write_data(
"application/json",
None,
expected_data.clone()
);
let data: serde_json::Value = e.try_get_data().unwrap().unwrap();
assert_eq!(expected_data, data);
assert_eq!("application/json", e.get_datacontenttype().unwrap())
}
}