From 7f6450be48f171d2b5babcc2cbdada3bb44b75e6 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 31 Oct 2020 22:49:17 +0100 Subject: [PATCH] Add message serialization implementation Signed-off-by: trivernis --- Cargo.toml | 5 +++++ src/lib.rs | 3 +++ src/message.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/result.rs | 29 +++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) create mode 100644 src/message.rs create mode 100644 src/result.rs diff --git a/Cargo.toml b/Cargo.toml index 4e65fb7..bddfc4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,8 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +rmp = "0.8.9" +rmp-serde = "0.14.4" +serde = "1.0.117" +crc = "1.8.1" +byteorder = "1.3.4" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 31e1bb2..c63a8fc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,6 @@ +pub mod message; +pub mod result; + #[cfg(test)] mod tests { #[test] diff --git a/src/message.rs b/src/message.rs new file mode 100644 index 0000000..106fa33 --- /dev/null +++ b/src/message.rs @@ -0,0 +1,45 @@ +use serde::Serialize; +use crate::result::VentedResult; +use byteorder::{BigEndian, ByteOrder}; +use crc::crc32; + +#[derive(Clone, Debug)] +pub struct Message { + event_name: String, + payload: T, +} + +impl Message where T: Serialize { + /// Returns the byte representation for the message + /// the format is + /// name-length: u16, + /// name: name-length, + /// payload-length: u64, + /// payload: payload-length, + /// crc: u32 + pub fn to_bytes(&self) -> VentedResult> { + let mut payload_raw = rmp_serde::to_vec(&self.payload)?; + let mut name_raw = self.event_name.as_bytes().to_vec(); + + let name_length = name_raw.len(); + let mut name_length_raw = [0u8; 2]; + BigEndian::write_u16(&mut name_length_raw, name_length as u16); + + let payload_length = payload_raw.len(); + let mut payload_length_raw = [0u8; 8]; + BigEndian::write_u64(&mut payload_length_raw, payload_length as u64); + + let mut data = Vec::new(); + + data.append(&mut name_length_raw.to_vec()); + data.append(&mut name_raw); + data.append(&mut payload_length_raw.to_vec()); + data.append(&mut payload_raw); + let crc = crc32::checksum_ieee(&data); + let mut crc_raw = [0u8; 4]; + BigEndian::write_u32(&mut crc_raw, crc); + data.append(&mut crc_raw.to_vec()); + + Ok(data) + } +} \ No newline at end of file diff --git a/src/result.rs b/src/result.rs new file mode 100644 index 0000000..818ed44 --- /dev/null +++ b/src/result.rs @@ -0,0 +1,29 @@ +use std::{fmt, io}; + +pub type VentedResult = Result; + +pub enum VentedError { + IOError(io::Error), + SerializeError(rmp_serde::encode::Error) +} + +impl fmt::Display for VentedError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::IOError(e) => write!(f, "IO Error: {}", e.to_string()), + Self::SerializeError(e) => write!(f, "Serialization Error: {}", e.to_string()), + } + } +} + +impl From for VentedError { + fn from(other: io::Error) -> Self { + Self::IOError(other) + } +} + +impl From for VentedError { + fn from(other: rmp_serde::encode::Error) -> Self { + Self::SerializeError(other) + } +} \ No newline at end of file