use coset::iana::CoapContentFormat;
use serde::{Serialize, de::DeserializeOwned};
use crate::error::EncodingError;
pub struct SerializedMessage {
serialized_message_bytes: Vec<u8>,
content_type: CoapContentFormat,
}
impl AsRef<[u8]> for SerializedMessage {
fn as_ref(&self) -> &[u8] {
&self.serialized_message_bytes
}
}
impl SerializedMessage {
pub fn from_bytes(bytes: Vec<u8>, content_type: CoapContentFormat) -> Self {
SerializedMessage {
serialized_message_bytes: bytes,
content_type,
}
}
pub fn as_bytes(&self) -> &[u8] {
&self.serialized_message_bytes
}
pub(crate) fn content_type(&self) -> CoapContentFormat {
self.content_type
}
pub(crate) fn encode<Message: Serialize>(message: &Message) -> Result<Self, EncodingError> {
let mut buffer = Vec::new();
ciborium::ser::into_writer(message, &mut buffer)
.map_err(|_| EncodingError::InvalidCborSerialization)?;
Ok(SerializedMessage {
serialized_message_bytes: buffer,
content_type: CoapContentFormat::Cbor,
})
}
pub fn decode<Message: DeserializeOwned>(&self) -> Result<Message, EncodingError> {
if self.content_type != CoapContentFormat::Cbor {
return Err(EncodingError::InvalidValue("Unsupported content type"));
}
ciborium::de::from_reader(self.serialized_message_bytes.as_slice())
.map_err(|_| EncodingError::InvalidCborSerialization)
}
}
#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
use super::*;
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TestMessage {
field1: String,
field2: u32,
}
#[test]
fn test_serialization() {
let message = TestMessage {
field1: "Hello".to_string(),
field2: 42,
};
let serialized = SerializedMessage::encode(&message).unwrap();
let deserialized: TestMessage = serialized.decode().unwrap();
assert_eq!(message, deserialized);
}
#[test]
fn test_bytes() {
let message = TestMessage {
field1: "Hello".to_string(),
field2: 42,
};
let serialized = SerializedMessage::encode(&message).unwrap();
let deserialized: TestMessage = SerializedMessage::from_bytes(
serialized.as_bytes().to_vec(),
serialized.content_type(),
)
.decode()
.unwrap();
assert_eq!(message, deserialized);
}
}