Cleanup to follow C-GETTER (#88)

* Cleanup to follow C-GETTER

Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>

* Cleanup to follow C-GETTER
Implemented Debug in event::Data
Exposing event::Data in main cloudevents export
Fixed rebase errors with previous pr

Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>

* cargo fmt

Signed-off-by: Francesco Guardiani <francescoguard@gmail.com>
This commit is contained in:
Francesco Guardiani 2020-10-21 12:04:32 +02:00 committed by GitHub
parent 1858a1caa5
commit c926188d78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 134 additions and 148 deletions

View File

@ -46,21 +46,21 @@ impl fmt::Display for AttributeValue<'_> {
/// Trait to get [CloudEvents Context attributes](https://github.com/cloudevents/spec/blob/master/spec.md#context-attributes). /// Trait to get [CloudEvents Context attributes](https://github.com/cloudevents/spec/blob/master/spec.md#context-attributes).
pub trait AttributesReader { pub trait AttributesReader {
/// Get the [id](https://github.com/cloudevents/spec/blob/master/spec.md#id). /// Get the [id](https://github.com/cloudevents/spec/blob/master/spec.md#id).
fn get_id(&self) -> &str; fn id(&self) -> &str;
/// Get the [source](https://github.com/cloudevents/spec/blob/master/spec.md#source-1). /// Get the [source](https://github.com/cloudevents/spec/blob/master/spec.md#source-1).
fn get_source(&self) -> &Url; fn source(&self) -> &Url;
/// Get the [specversion](https://github.com/cloudevents/spec/blob/master/spec.md#specversion). /// Get the [specversion](https://github.com/cloudevents/spec/blob/master/spec.md#specversion).
fn get_specversion(&self) -> SpecVersion; fn specversion(&self) -> SpecVersion;
/// Get the [type](https://github.com/cloudevents/spec/blob/master/spec.md#type). /// Get the [type](https://github.com/cloudevents/spec/blob/master/spec.md#type).
fn get_type(&self) -> &str; fn ty(&self) -> &str;
/// Get the [datacontenttype](https://github.com/cloudevents/spec/blob/master/spec.md#datacontenttype). /// Get the [datacontenttype](https://github.com/cloudevents/spec/blob/master/spec.md#datacontenttype).
fn get_datacontenttype(&self) -> Option<&str>; fn datacontenttype(&self) -> Option<&str>;
/// Get the [dataschema](https://github.com/cloudevents/spec/blob/master/spec.md#dataschema). /// Get the [dataschema](https://github.com/cloudevents/spec/blob/master/spec.md#dataschema).
fn get_dataschema(&self) -> Option<&Url>; fn dataschema(&self) -> Option<&Url>;
/// Get the [subject](https://github.com/cloudevents/spec/blob/master/spec.md#subject). /// Get the [subject](https://github.com/cloudevents/spec/blob/master/spec.md#subject).
fn get_subject(&self) -> Option<&str>; fn subject(&self) -> Option<&str>;
/// Get the [time](https://github.com/cloudevents/spec/blob/master/spec.md#time). /// Get the [time](https://github.com/cloudevents/spec/blob/master/spec.md#time).
fn get_time(&self) -> Option<&DateTime<Utc>>; fn time(&self) -> Option<&DateTime<Utc>>;
} }
/// Trait to set [CloudEvents Context attributes](https://github.com/cloudevents/spec/blob/master/spec.md#context-attributes). /// Trait to set [CloudEvents Context attributes](https://github.com/cloudevents/spec/blob/master/spec.md#context-attributes).
@ -117,59 +117,59 @@ pub enum Attributes {
} }
impl AttributesReader for Attributes { impl AttributesReader for Attributes {
fn get_id(&self) -> &str { fn id(&self) -> &str {
match self { match self {
Attributes::V03(a) => a.get_id(), Attributes::V03(a) => a.id(),
Attributes::V10(a) => a.get_id(), Attributes::V10(a) => a.id(),
} }
} }
fn get_source(&self) -> &Url { fn source(&self) -> &Url {
match self { match self {
Attributes::V03(a) => a.get_source(), Attributes::V03(a) => a.source(),
Attributes::V10(a) => a.get_source(), Attributes::V10(a) => a.source(),
} }
} }
fn get_specversion(&self) -> SpecVersion { fn specversion(&self) -> SpecVersion {
match self { match self {
Attributes::V03(a) => a.get_specversion(), Attributes::V03(a) => a.specversion(),
Attributes::V10(a) => a.get_specversion(), Attributes::V10(a) => a.specversion(),
} }
} }
fn get_type(&self) -> &str { fn ty(&self) -> &str {
match self { match self {
Attributes::V03(a) => a.get_type(), Attributes::V03(a) => a.ty(),
Attributes::V10(a) => a.get_type(), Attributes::V10(a) => a.ty(),
} }
} }
fn get_datacontenttype(&self) -> Option<&str> { fn datacontenttype(&self) -> Option<&str> {
match self { match self {
Attributes::V03(a) => a.get_datacontenttype(), Attributes::V03(a) => a.datacontenttype(),
Attributes::V10(a) => a.get_datacontenttype(), Attributes::V10(a) => a.datacontenttype(),
} }
} }
fn get_dataschema(&self) -> Option<&Url> { fn dataschema(&self) -> Option<&Url> {
match self { match self {
Attributes::V03(a) => a.get_dataschema(), Attributes::V03(a) => a.dataschema(),
Attributes::V10(a) => a.get_dataschema(), Attributes::V10(a) => a.dataschema(),
} }
} }
fn get_subject(&self) -> Option<&str> { fn subject(&self) -> Option<&str> {
match self { match self {
Attributes::V03(a) => a.get_subject(), Attributes::V03(a) => a.subject(),
Attributes::V10(a) => a.get_subject(), Attributes::V10(a) => a.subject(),
} }
} }
fn get_time(&self) -> Option<&DateTime<Utc>> { fn time(&self) -> Option<&DateTime<Utc>> {
match self { match self {
Attributes::V03(a) => a.get_time(), Attributes::V03(a) => a.time(),
Attributes::V10(a) => a.get_time(), Attributes::V10(a) => a.time(),
} }
} }
} }

View File

@ -1,4 +1,6 @@
use serde::export::Formatter;
use std::convert::{Into, TryFrom}; use std::convert::{Into, TryFrom};
use std::fmt;
/// Event [data attribute](https://github.com/cloudevents/spec/blob/master/spec.md#event-data) representation /// Event [data attribute](https://github.com/cloudevents/spec/blob/master/spec.md#event-data) representation
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
@ -102,3 +104,13 @@ impl TryFrom<Data> for String {
} }
} }
} }
impl fmt::Display for Data {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Data::Binary(vec) => write!(f, "Binary data: {:?}", vec),
Data::String(s) => write!(f, "String data: {}", s),
Data::Json(j) => write!(f, "Json data: {}", j),
}
}
}

View File

@ -6,7 +6,6 @@ use crate::event::attributes::DataAttributesWriter;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use delegate_attr::delegate; use delegate_attr::delegate;
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryFrom;
use url::Url; use url::Url;
/// Data structure that represents a [CloudEvent](https://github.com/cloudevents/spec/blob/master/spec.md). /// Data structure that represents a [CloudEvent](https://github.com/cloudevents/spec/blob/master/spec.md).
@ -16,9 +15,11 @@ use url::Url;
/// ///
/// You can build events using [`super::EventBuilder`] /// You can build events using [`super::EventBuilder`]
/// ``` /// ```
/// use cloudevents::Event; /// use cloudevents::*;
/// use cloudevents::event::AttributesReader; /// use std::convert::TryInto;
/// ///
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// // Create an event using the Default trait /// // Create an event using the Default trait
/// let mut e = Event::default(); /// let mut e = Event::default();
/// e.write_data( /// e.write_data(
@ -27,11 +28,16 @@ use url::Url;
/// ); /// );
/// ///
/// // Print the event id /// // Print the event id
/// println!("Event id: {}", e.get_id()); /// println!("Event id: {}", e.id());
/// ///
/// // Get the event data /// // Get the event data
/// let data: serde_json::Value = e.try_get_data().unwrap().unwrap(); /// let data: Option<Data> = e.data().cloned();
/// println!("Event data: {}", data) /// match data {
/// Some(d) => println!("{}", d),
/// None => println!("No event data")
/// }
/// # Ok(())
/// # }
/// ``` /// ```
#[derive(PartialEq, Debug, Clone)] #[derive(PartialEq, Debug, Clone)]
pub struct Event { pub struct Event {
@ -42,14 +48,14 @@ pub struct Event {
#[delegate(self.attributes)] #[delegate(self.attributes)]
impl AttributesReader for Event { impl AttributesReader for Event {
fn get_id(&self) -> &str; fn id(&self) -> &str;
fn get_source(&self) -> &Url; fn source(&self) -> &Url;
fn get_specversion(&self) -> SpecVersion; fn specversion(&self) -> SpecVersion;
fn get_type(&self) -> &str; fn ty(&self) -> &str;
fn get_datacontenttype(&self) -> Option<&str>; fn datacontenttype(&self) -> Option<&str>;
fn get_dataschema(&self) -> Option<&Url>; fn dataschema(&self) -> Option<&Url>;
fn get_subject(&self) -> Option<&str>; fn subject(&self) -> Option<&str>;
fn get_time(&self) -> Option<&DateTime<Utc>>; fn time(&self) -> Option<&DateTime<Utc>>;
} }
#[delegate(self.attributes)] #[delegate(self.attributes)]
@ -126,6 +132,11 @@ impl Event {
self.data = Some(data.into()); self.data = Some(data.into());
} }
/// Get `data` from this `Event`
pub fn data(&self) -> Option<&Data> {
self.data.as_ref()
}
/// Write `data` into this `Event` with the specified `datacontenttype` and `dataschema`. /// Write `data` into this `Event` with the specified `datacontenttype` and `dataschema`.
/// ///
/// ``` /// ```
@ -152,34 +163,8 @@ impl Event {
self.data = Some(data.into()); self.data = Some(data.into());
} }
/// Get `data` from this `Event`
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,
}
}
/// Try to get `data` from this `Event`
pub fn try_get_data<T: Sized + TryFrom<Data>>(&self) -> Result<Option<T>, T::Error> {
match self.data.as_ref() {
Some(d) => Some(T::try_from(d.clone())),
None => None,
}
.transpose()
}
/// Transform this `Event` into the content of `data`
pub fn into_data<T: Sized + TryFrom<Data>>(self) -> Result<Option<T>, T::Error> {
match self.data {
Some(d) => Some(T::try_from(d)),
None => None,
}
.transpose()
}
/// Get the [extension](https://github.com/cloudevents/spec/blob/master/spec.md#extension-context-attributes) named `extension_name` /// Get the [extension](https://github.com/cloudevents/spec/blob/master/spec.md#extension-context-attributes) named `extension_name`
pub fn get_extension(&self, extension_name: &str) -> Option<&ExtensionValue> { pub fn extension(&self, extension_name: &str) -> Option<&ExtensionValue> {
self.extensions.get(extension_name) self.extensions.get(extension_name)
} }
@ -206,28 +191,6 @@ impl Event {
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn try_get_data_json() {
let expected_data = serde_json::json!({
"hello": "world"
});
let mut e = Event::default();
e.write_data_with_schema(
"application/json",
Url::parse("http://localhost:8080/schema").unwrap(),
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());
assert_eq!(
&Url::parse("http://localhost:8080/schema").unwrap(),
e.get_dataschema().unwrap()
)
}
#[test] #[test]
fn take_data() { fn take_data() {
let mut e = Event::default(); let mut e = Event::default();
@ -238,11 +201,15 @@ mod tests {
}), }),
); );
let _d = e.take_data(); let (datacontenttype, dataschema, data) = e.take_data();
assert!(e.try_get_data::<serde_json::Value>().unwrap().is_none()); assert!(datacontenttype.is_some());
assert!(e.get_dataschema().is_none()); assert!(dataschema.is_none());
assert!(e.get_datacontenttype().is_none()); assert!(data.is_some());
assert!(e.data().is_none());
assert!(e.dataschema().is_none());
assert!(e.datacontenttype().is_none());
} }
#[test] #[test]
@ -251,7 +218,7 @@ mod tests {
e.set_id("001"); e.set_id("001");
assert_eq!(e.set_id("002"), String::from("001")); assert_eq!(e.set_id("002"), String::from("001"));
assert_eq!(e.get_id(), "002") assert_eq!(e.id(), "002")
} }
#[test] #[test]

View File

@ -106,9 +106,7 @@ pub(crate) trait EventFormatDeserializer {
) -> Result<Event, E> { ) -> Result<Event, E> {
let attributes = Self::deserialize_attributes(&mut map)?; let attributes = Self::deserialize_attributes(&mut map)?;
let data = Self::deserialize_data( let data = Self::deserialize_data(
attributes attributes.datacontenttype().unwrap_or("application/json"),
.get_datacontenttype()
.unwrap_or("application/json"),
&mut map, &mut map,
)?; )?;
let extensions = map let extensions = map

View File

@ -17,7 +17,7 @@ impl StructuredDeserializer for Event {
impl BinaryDeserializer for Event { impl BinaryDeserializer for Event {
fn deserialize_binary<R: Sized, V: BinarySerializer<R>>(self, mut visitor: V) -> Result<R> { fn deserialize_binary<R: Sized, V: BinarySerializer<R>>(self, mut visitor: V) -> Result<R> {
visitor = visitor.set_spec_version(self.get_specversion())?; visitor = visitor.set_spec_version(self.specversion())?;
visitor = self.attributes.deserialize_attributes(visitor)?; visitor = self.attributes.deserialize_attributes(visitor)?;
for (k, v) in self.extensions.into_iter() { for (k, v) in self.extensions.into_iter() {
visitor = visitor.set_extension(&k, v.into())?; visitor = visitor.set_extension(&k, v.into())?;

View File

@ -88,35 +88,35 @@ impl<'a> Iterator for AttributesIntoIterator<'a> {
} }
impl AttributesReader for Attributes { impl AttributesReader for Attributes {
fn get_id(&self) -> &str { fn id(&self) -> &str {
&self.id &self.id
} }
fn get_source(&self) -> &Url { fn source(&self) -> &Url {
&self.source &self.source
} }
fn get_specversion(&self) -> SpecVersion { fn specversion(&self) -> SpecVersion {
SpecVersion::V03 SpecVersion::V03
} }
fn get_type(&self) -> &str { fn ty(&self) -> &str {
&self.ty &self.ty
} }
fn get_datacontenttype(&self) -> Option<&str> { fn datacontenttype(&self) -> Option<&str> {
self.datacontenttype.as_deref() self.datacontenttype.as_deref()
} }
fn get_dataschema(&self) -> Option<&Url> { fn dataschema(&self) -> Option<&Url> {
self.schemaurl.as_ref() self.schemaurl.as_ref()
} }
fn get_subject(&self) -> Option<&str> { fn subject(&self) -> Option<&str> {
self.subject.as_deref() self.subject.as_deref()
} }
fn get_time(&self) -> Option<&DateTime<Utc>> { fn time(&self) -> Option<&DateTime<Utc>> {
self.time.as_ref() self.time.as_ref()
} }
} }

View File

@ -88,35 +88,35 @@ impl<'a> Iterator for AttributesIntoIterator<'a> {
} }
impl AttributesReader for Attributes { impl AttributesReader for Attributes {
fn get_id(&self) -> &str { fn id(&self) -> &str {
&self.id &self.id
} }
fn get_source(&self) -> &Url { fn source(&self) -> &Url {
&self.source &self.source
} }
fn get_specversion(&self) -> SpecVersion { fn specversion(&self) -> SpecVersion {
SpecVersion::V10 SpecVersion::V10
} }
fn get_type(&self) -> &str { fn ty(&self) -> &str {
&self.ty &self.ty
} }
fn get_datacontenttype(&self) -> Option<&str> { fn datacontenttype(&self) -> Option<&str> {
self.datacontenttype.as_deref() self.datacontenttype.as_deref()
} }
fn get_dataschema(&self) -> Option<&Url> { fn dataschema(&self) -> Option<&Url> {
self.dataschema.as_ref() self.dataschema.as_ref()
} }
fn get_subject(&self) -> Option<&str> { fn subject(&self) -> Option<&str> {
self.subject.as_deref() self.subject.as_deref()
} }
fn get_time(&self) -> Option<&DateTime<Utc>> { fn time(&self) -> Option<&DateTime<Utc>> {
self.time.as_ref() self.time.as_ref()
} }
} }

View File

@ -13,8 +13,8 @@
//! .build() //! .build()
//! .unwrap(); //! .unwrap();
//! //!
//! println!("CloudEvent Id: {}", event.get_id()); //! println!("CloudEvent Id: {}", event.id());
//! println!("CloudEvent Time: {}", event.get_time().unwrap()); //! println!("CloudEvent Time: {}", event.time().unwrap());
//! ``` //! ```
//! //!
//! If you're looking for Protocol Binding implementations, look at crates: //! If you're looking for Protocol Binding implementations, look at crates:
@ -33,6 +33,7 @@ pub mod event;
/// Provides facilities to implement Protocol Bindings /// Provides facilities to implement Protocol Bindings
pub mod message; pub mod message;
pub use event::Data;
pub use event::Event; pub use event::Event;
pub use event::{AttributesReader, AttributesWriter}; pub use event::{AttributesReader, AttributesWriter};
pub use event::{EventBuilder, EventBuilderV03, EventBuilderV10}; pub use event::{EventBuilder, EventBuilderV03, EventBuilderV10};

View File

@ -6,6 +6,7 @@ use cloudevents::event::{
AttributesReader, EventBuilder, EventBuilderError, ExtensionValue, SpecVersion, AttributesReader, EventBuilder, EventBuilderError, ExtensionValue, SpecVersion,
}; };
use cloudevents::EventBuilderV03; use cloudevents::EventBuilderV03;
use std::convert::TryInto;
use url::Url; use url::Url;
#[test] #[test]
@ -23,7 +24,7 @@ fn build_event() {
"hello": "world" "hello": "world"
}); });
let event = EventBuilderV03::new() let mut event = EventBuilderV03::new()
.id(id) .id(id)
.source(source.clone()) .source(source.clone())
.ty(ty) .ty(ty)
@ -34,20 +35,20 @@ fn build_event() {
.build() .build()
.unwrap(); .unwrap();
assert_eq!(SpecVersion::V03, event.get_specversion()); assert_eq!(SpecVersion::V03, event.specversion());
assert_eq!(id, event.get_id()); assert_eq!(id, event.id());
assert_eq!(source, event.get_source().clone()); assert_eq!(source, event.source().clone());
assert_eq!(ty, event.get_type()); assert_eq!(ty, event.ty());
assert_eq!(subject, event.get_subject().unwrap()); assert_eq!(subject, event.subject().unwrap());
assert_eq!(time, event.get_time().unwrap().clone()); assert_eq!(time, event.time().unwrap().clone());
assert_eq!( assert_eq!(
ExtensionValue::from(extension_value), ExtensionValue::from(extension_value),
event.get_extension(extension_name).unwrap().clone() event.extension(extension_name).unwrap().clone()
); );
assert_eq!(content_type, event.get_datacontenttype().unwrap()); assert_eq!(content_type, event.datacontenttype().unwrap());
assert_eq!(schema, event.get_dataschema().unwrap().clone()); assert_eq!(schema, event.dataschema().unwrap().clone());
let event_data: serde_json::Value = event.try_get_data().unwrap().unwrap(); let event_data: serde_json::Value = event.take_data().2.unwrap().try_into().unwrap();
assert_eq!(data, event_data); assert_eq!(data, event_data);
} }

View File

@ -6,6 +6,7 @@ use cloudevents::event::{
AttributesReader, EventBuilder, EventBuilderError, ExtensionValue, SpecVersion, AttributesReader, EventBuilder, EventBuilderError, ExtensionValue, SpecVersion,
}; };
use cloudevents::EventBuilderV10; use cloudevents::EventBuilderV10;
use std::convert::TryInto;
use url::Url; use url::Url;
#[test] #[test]
@ -23,7 +24,7 @@ fn build_event() {
"hello": "world" "hello": "world"
}); });
let event = EventBuilderV10::new() let mut event = EventBuilderV10::new()
.id(id) .id(id)
.source(source.clone()) .source(source.clone())
.ty(ty) .ty(ty)
@ -34,20 +35,20 @@ fn build_event() {
.build() .build()
.unwrap(); .unwrap();
assert_eq!(SpecVersion::V10, event.get_specversion()); assert_eq!(SpecVersion::V10, event.specversion());
assert_eq!(id, event.get_id()); assert_eq!(id, event.id());
assert_eq!(source, event.get_source().clone()); assert_eq!(source, event.source().clone());
assert_eq!(ty, event.get_type()); assert_eq!(ty, event.ty());
assert_eq!(subject, event.get_subject().unwrap()); assert_eq!(subject, event.subject().unwrap());
assert_eq!(time, event.get_time().unwrap().clone()); assert_eq!(time, event.time().unwrap().clone());
assert_eq!( assert_eq!(
ExtensionValue::from(extension_value), ExtensionValue::from(extension_value),
event.get_extension(extension_name).unwrap().clone() event.extension(extension_name).unwrap().clone()
); );
assert_eq!(content_type, event.get_datacontenttype().unwrap()); assert_eq!(content_type, event.datacontenttype().unwrap());
assert_eq!(schema, event.get_dataschema().unwrap().clone()); assert_eq!(schema, event.dataschema().unwrap().clone());
let event_data: serde_json::Value = event.try_get_data().unwrap().unwrap(); let event_data: serde_json::Value = event.take_data().2.unwrap().try_into().unwrap();
assert_eq!(data, event_data); assert_eq!(data, event_data);
} }

View File

@ -2,6 +2,7 @@ mod test_data;
use cloudevents::message::{BinaryDeserializer, Result, StructuredDeserializer}; use cloudevents::message::{BinaryDeserializer, Result, StructuredDeserializer};
use cloudevents::{AttributesReader, EventBuilder, EventBuilderV03, EventBuilderV10}; use cloudevents::{AttributesReader, EventBuilder, EventBuilderV03, EventBuilderV10};
use std::convert::TryInto;
use test_data::*; use test_data::*;
#[test] #[test]
@ -18,10 +19,10 @@ fn message_v03_roundtrip_binary() -> Result<()> {
//TODO this code smells because we're missing a proper way in the public APIs //TODO this code smells because we're missing a proper way in the public APIs
// to destructure an event and rebuild it // to destructure an event and rebuild it
let wanna_be_expected = v03::full_json_data(); let wanna_be_expected = v03::full_json_data();
let data: serde_json::Value = wanna_be_expected.try_get_data()?.unwrap(); let data: serde_json::Value = wanna_be_expected.data().unwrap().clone().try_into()?;
let bytes = serde_json::to_vec(&data)?; let bytes = serde_json::to_vec(&data)?;
let expected = EventBuilderV03::from(wanna_be_expected.clone()) let expected = EventBuilderV03::from(wanna_be_expected.clone())
.data(wanna_be_expected.get_datacontenttype().unwrap(), bytes) .data(wanna_be_expected.datacontenttype().unwrap(), bytes)
.build() .build()
.unwrap(); .unwrap();
@ -46,10 +47,15 @@ fn message_v10_roundtrip_binary() -> Result<()> {
//TODO this code smells because we're missing a proper way in the public APIs //TODO this code smells because we're missing a proper way in the public APIs
// to destructure an event and rebuild it // to destructure an event and rebuild it
let wanna_be_expected = v10::full_json_data(); let wanna_be_expected = v10::full_json_data();
let data: serde_json::Value = wanna_be_expected.try_get_data()?.unwrap(); let data: serde_json::Value = wanna_be_expected
.data()
.cloned()
.unwrap()
.try_into()
.unwrap();
let bytes = serde_json::to_vec(&data)?; let bytes = serde_json::to_vec(&data)?;
let expected = EventBuilderV10::from(wanna_be_expected.clone()) let expected = EventBuilderV10::from(wanna_be_expected.clone())
.data(wanna_be_expected.get_datacontenttype().unwrap(), bytes) .data(wanna_be_expected.datacontenttype().unwrap(), bytes)
.build() .build()
.unwrap(); .unwrap();