Add message serialization implementation

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/1/head
trivernis 4 years ago
parent b821bf4590
commit 7f6450be48
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -7,3 +7,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
rmp = "0.8.9"
rmp-serde = "0.14.4"
serde = "1.0.117"
crc = "1.8.1"
byteorder = "1.3.4"

@ -1,3 +1,6 @@
pub mod message;
pub mod result;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]

@ -0,0 +1,45 @@
use serde::Serialize;
use crate::result::VentedResult;
use byteorder::{BigEndian, ByteOrder};
use crc::crc32;
#[derive(Clone, Debug)]
pub struct Message<T> {
event_name: String,
payload: T,
}
impl<T> Message<T> 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<Vec<u8>> {
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)
}
}

@ -0,0 +1,29 @@
use std::{fmt, io};
pub type VentedResult<T> = Result<T, VentedError>;
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<io::Error> for VentedError {
fn from(other: io::Error) -> Self {
Self::IOError(other)
}
}
impl From<rmp_serde::encode::Error> for VentedError {
fn from(other: rmp_serde::encode::Error) -> Self {
Self::SerializeError(other)
}
}
Loading…
Cancel
Save