From 313974559058c69b0320218ef2d6fc499484c768 Mon Sep 17 00:00:00 2001 From: trivernis Date: Sat, 31 Oct 2020 23:07:49 +0100 Subject: [PATCH] Rename Message to Event and add from_bytes implementation Signed-off-by: trivernis --- Cargo.toml | 1 - src/event.rs | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 +- src/message.rs | 45 ------------------------------------- src/result.rs | 12 +++++++++- 5 files changed, 72 insertions(+), 48 deletions(-) create mode 100644 src/event.rs delete mode 100644 src/message.rs diff --git a/Cargo.toml b/Cargo.toml index bddfc4e..7f1d55b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,4 @@ edition = "2018" 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/event.rs b/src/event.rs new file mode 100644 index 0000000..50830e1 --- /dev/null +++ b/src/event.rs @@ -0,0 +1,60 @@ +use serde::{Serialize}; +use crate::result::{VentedResult, VentedError}; +use byteorder::{BigEndian, ByteOrder, ReadBytesExt}; +use std::io::Read; +use serde::de::DeserializeOwned; + +/// A single event that has a name and payload. +/// The payload is encoded with message pack +#[derive(Clone, Debug)] +pub struct Event { + event_name: String, + payload: T, +} + +impl Event where T: Serialize + DeserializeOwned { + /// Returns the byte representation for the message + /// the format is + /// `name-length`: `u16`, + /// `name`: `name-length`, + /// `payload-length`: `u64`, + /// `payload`: `payload-length`, + 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); + + Ok(data) + } + + /// Deserializes the message from bytes that can be read from the given reader + /// The result will be the Message with the specific message payload type + pub fn from_bytes(bytes: &mut R) -> VentedResult { + let name_length = bytes.read_u16::()?; + let mut name_buf = vec![0u8; name_length as usize]; + bytes.read_exact(&mut name_buf)?; + let event_name = String::from_utf8(name_buf).map_err(|_| VentedError::NameDecodingError)?; + + let payload_length = bytes.read_u64::()?; + let payload = rmp_serde::from_read(bytes.take(payload_length))?; + + Ok(Self { + event_name, + payload, + }) + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c63a8fc..ace3ff1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -pub mod message; +pub mod event; pub mod result; #[cfg(test)] diff --git a/src/message.rs b/src/message.rs deleted file mode 100644 index 106fa33..0000000 --- a/src/message.rs +++ /dev/null @@ -1,45 +0,0 @@ -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 index 818ed44..92923b3 100644 --- a/src/result.rs +++ b/src/result.rs @@ -3,15 +3,19 @@ use std::{fmt, io}; pub type VentedResult = Result; pub enum VentedError { + NameDecodingError, IOError(io::Error), - SerializeError(rmp_serde::encode::Error) + SerializeError(rmp_serde::encode::Error), + DeserializeError(rmp_serde::decode::Error), } impl fmt::Display for VentedError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { + Self::NameDecodingError => write!(f, "Failed to decode event name"), Self::IOError(e) => write!(f, "IO Error: {}", e.to_string()), Self::SerializeError(e) => write!(f, "Serialization Error: {}", e.to_string()), + Self::DeserializeError(e) => write!(f, "Deserialization Error: {}", e.to_string()), } } } @@ -26,4 +30,10 @@ impl From for VentedError { fn from(other: rmp_serde::encode::Error) -> Self { Self::SerializeError(other) } +} + +impl From for VentedError { + fn from(other: rmp_serde::decode::Error) -> Self { + Self::DeserializeError(other) + } } \ No newline at end of file