use std::{
hash::Hash,
io::{Read, Write},
};
use serde::{de::DeserializeOwned, Serialize};
use crate::{
event::{serialization::error::BincodeError, AttributeMap, AttributeValue, DefaultEvent},
traits::Event,
};
pub trait BincodeSerializable {
fn to_bincode(&self) -> Result<Vec<u8>, BincodeError>;
fn write_bincode<W: Write>(&self, writer: W) -> Result<(), BincodeError>;
}
pub trait BincodeDeserializable {
fn from_bincode(bincode_bytes: &[u8]) -> Result<Self, BincodeError>
where
Self: Sized;
fn read_bincode<R: Read>(reader: R) -> Result<Self, BincodeError>
where
Self: Sized;
}
impl BincodeSerializable for DefaultEvent {
fn to_bincode(&self) -> Result<Vec<u8>, BincodeError> {
bincode::serialize(self.attributes()).map_err(BincodeError::SerializationError)
}
fn write_bincode<W: Write>(&self, mut writer: W) -> Result<(), BincodeError> {
let bytes = self.to_bincode()?;
writer.write_all(&bytes).map_err(BincodeError::IoError)?;
Ok(())
}
}
impl BincodeDeserializable for DefaultEvent {
fn from_bincode(bincode_bytes: &[u8]) -> Result<Self, BincodeError> {
let attribute_map: AttributeMap<String, AttributeValue> =
bincode::deserialize(bincode_bytes).map_err(BincodeError::DeserializationError)?;
DefaultEvent::from_attributes(attribute_map).map_err(BincodeError::from)
}
fn read_bincode<R: Read>(mut reader: R) -> Result<Self, BincodeError> {
let mut buffer = Vec::new();
reader
.read_to_end(&mut buffer)
.map_err(BincodeError::IoError)?;
Self::from_bincode(&buffer)
}
}
impl<K: Serialize, V: Serialize> BincodeSerializable for AttributeMap<K, V> {
fn to_bincode(&self) -> Result<Vec<u8>, BincodeError> {
bincode::serialize(self).map_err(BincodeError::SerializationError)
}
fn write_bincode<W: Write>(&self, mut writer: W) -> Result<(), BincodeError> {
let bytes = self.to_bincode()?;
writer.write_all(&bytes).map_err(BincodeError::IoError)?;
Ok(())
}
}
impl<K: Hash + Eq + DeserializeOwned, V: DeserializeOwned> BincodeDeserializable
for AttributeMap<K, V>
{
fn from_bincode(bincode_bytes: &[u8]) -> Result<Self, BincodeError> {
bincode::deserialize(bincode_bytes).map_err(BincodeError::DeserializationError)
}
fn read_bincode<R: Read>(mut reader: R) -> Result<Self, BincodeError> {
let mut buffer = Vec::new();
reader
.read_to_end(&mut buffer)
.map_err(BincodeError::IoError)?;
Self::from_bincode(&buffer)
}
}
#[cfg(test)]
mod tests {
use std::io::Cursor;
use crate::event::{
helpers::*,
serialization::bincode::{BincodeDeserializable, BincodeSerializable},
AttributeMap, AttributeValue, DefaultEvent, Event,
};
#[test]
fn test_basic_bincode_serialization() {
let event = DefaultEvent::new("test.event".to_string())
.with_attribute("key".to_string(), string_attr("value"));
let bincode_bytes = event.to_bincode().unwrap();
assert!(!bincode_bytes.is_empty());
}
#[test]
fn test_all_attribute_types_bincode_serialization() {
let event = create_test_event_all_types();
let bincode_bytes = event.to_bincode().unwrap();
assert!(!bincode_bytes.is_empty());
}
#[test]
fn test_bincode_deserialization() {
let original_event = create_test_event_all_types();
let bincode_bytes = original_event.to_bincode().unwrap();
let deserialized_event = DefaultEvent::from_bincode(&bincode_bytes).unwrap();
assert_eq!(original_event.topic(), deserialized_event.topic());
assert_eq!(original_event, deserialized_event);
}
#[test]
fn test_write_read_bincode() {
let original_event = create_test_event_all_types();
let mut buffer = Vec::new();
original_event.write_bincode(&mut buffer).unwrap();
let deserialized_event = DefaultEvent::read_bincode(Cursor::new(&buffer)).unwrap();
assert_eq!(original_event.topic(), deserialized_event.topic());
assert_eq!(original_event, deserialized_event);
}
#[test]
fn test_invalid_bincode_deserialization() {
let invalid_bincode = vec![0xFF, 0xFE, 0xFD, 0xFC];
let result = DefaultEvent::from_bincode(&invalid_bincode);
assert!(result.is_err());
}
#[test]
fn test_nested_structures_bincode() {
let event = create_deeply_nested_event();
let bincode_bytes = event.to_bincode().unwrap();
let deserialized_event = DefaultEvent::from_bincode(&bincode_bytes).unwrap();
match deserialized_event.get_attribute("nested") {
Some(AttributeValue::Map(map)) => match map.get("level1") {
Some(AttributeValue::Map(level1)) => match level1.get("level2") {
Some(AttributeValue::Map(level2)) => match level2.get("level3") {
Some(AttributeValue::String(s)) => assert_eq!(s, "deeply nested value"),
_ => panic!("nested.level1.level2.level3 wrong type or missing"),
},
_ => panic!("nested.level1.level2 wrong type or missing"),
},
_ => panic!("nested.level1 wrong type or missing"),
},
_ => panic!("nested attribute wrong type or missing"),
}
match deserialized_event.get_attribute("nested_lists") {
Some(AttributeValue::List(outer_list)) => {
assert_eq!(outer_list.len(), 2);
match &outer_list[0] {
AttributeValue::List(inner_list) => {
assert_eq!(inner_list.len(), 2);
match &inner_list[0] {
AttributeValue::Integer(i) => assert_eq!(*i, 1),
_ => panic!("nested_lists[0][0] wrong type"),
}
match &inner_list[1] {
AttributeValue::Integer(i) => assert_eq!(*i, 2),
_ => panic!("nested_lists[0][1] wrong type"),
}
}
_ => panic!("nested_lists[0] wrong type"),
}
match &outer_list[1] {
AttributeValue::List(inner_list) => {
assert_eq!(inner_list.len(), 1);
match &inner_list[0] {
AttributeValue::Map(map) => match map.get("key") {
Some(AttributeValue::String(s)) => assert_eq!(s, "value"),
_ => panic!("nested_lists[1][0].key wrong type or missing"),
},
_ => panic!("nested_lists[1][0] wrong type"),
}
}
_ => panic!("nested_lists[1] wrong type"),
}
}
_ => panic!("nested_lists attribute wrong type or missing"),
}
}
#[test]
fn test_large_event_bincode() {
let mut large_event = DefaultEvent::new("large.event".to_string());
for i in 0..100 {
large_event = large_event.with_attribute(format!("int_{i}"), int_attr(i as i64));
}
for i in 0..50 {
large_event = large_event.with_attribute(
format!("string_{i}"),
string_attr(&format!(
"This is a longer string value for testing Bincode serialization efficiency {i}"
)),
);
}
let bincode_bytes = large_event.to_bincode().unwrap();
let deserialized_event = DefaultEvent::from_bincode(&bincode_bytes).unwrap();
assert_eq!(
large_event.attributes().len(),
deserialized_event.attributes().len()
);
assert_eq!(deserialized_event.attributes().len(), 151);
}
#[test]
fn test_bincode_size_efficiency() {
let event = create_test_event_all_types();
let bincode_bytes = event.to_bincode().unwrap();
assert!(bincode_bytes.len() <= 270);
let deserialized = DefaultEvent::from_bincode(&bincode_bytes).unwrap();
assert_eq!(event, deserialized);
}
fn create_test_event_all_types() -> DefaultEvent {
let mut map = AttributeMap::new();
map.insert("nested".to_string(), string_attr("value"));
DefaultEvent::new("test.event".to_string())
.with_attribute("string_attr".to_string(), string_attr("text"))
.with_attribute("int_attr".to_string(), int_attr(42))
.with_attribute("float_attr".to_string(), float_attr(std::f64::consts::PI))
.with_attribute("bool_attr".to_string(), bool_attr(true))
.with_attribute(
"list_attr".to_string(),
list_attr(vec![int_attr(1), int_attr(2)]),
)
.with_attribute("map_attr".to_string(), map_attr(map))
}
fn create_deeply_nested_event() -> DefaultEvent {
let mut level3 = AttributeMap::new();
level3.insert("level3".to_string(), string_attr("deeply nested value"));
let mut level2 = AttributeMap::new();
level2.insert("level2".to_string(), map_attr(level3));
let mut level1 = AttributeMap::new();
level1.insert("level1".to_string(), map_attr(level2));
let mut inner_map = AttributeMap::new();
inner_map.insert("key".to_string(), string_attr("value"));
DefaultEvent::new("nested.test".to_string())
.with_attribute("nested".to_string(), map_attr(level1))
.with_attribute(
"nested_lists".to_string(),
list_attr(vec![
list_attr(vec![int_attr(1), int_attr(2)]),
list_attr(vec![map_attr(inner_map)]),
]),
)
}
}