use byte::{TryRead, TryWrite, BytesExt, Result}; use byte::ctx::{Endian, LE, Str}; use serde_json; use serde::Serialize; #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] #[repr(C)] pub struct Message { opcode: u32, message: String, } impl<'a> TryRead<'a, Endian> for Message { fn try_read(bytes: &'a [u8], endian: Endian) -> Result<(Self, usize)> { let offset = &mut 0; let opcode: u32 = bytes.read_with(offset, endian)?; let message_length = bytes.read_with::(offset, endian)? as usize; let message = bytes.read_with::<&str>(offset, Str::Len(message_length))?.to_string(); Ok((Message { opcode, message }, *offset)) } } impl TryWrite for Message { fn try_write(self, bytes: &mut [u8], endian: Endian) -> Result { let offset = &mut 0; bytes.write_with::(offset, self.opcode, endian)?; bytes.write_with::(offset, self.message.len() as u32, endian)?; bytes.write_with::<&str>(offset, self.message.as_ref(), ())?; Ok(*offset) } } impl Message { pub fn new(opcode: u32, message: T) -> Self where T: Serialize { Message { opcode, message: serde_json::to_string(&message).unwrap() } } pub fn encode(&self) -> Result> { let mut bytes: Vec = vec![0; 2*4+self.message.len()]; bytes.write_with(&mut 0, self.clone(), LE)?; bytes.shrink_to_fit(); Ok(bytes) } #[allow(dead_code)] pub fn decode<'a>(bytes: &'a [u8]) -> Result { let message: Message = bytes.read_with(&mut 0, LE)?; Ok(message) } } #[cfg(test)] mod tests { use super::*; #[derive(Debug, PartialEq, Serialize, Deserialize)] struct Something { empty: bool } #[test] fn test_encoder() { let msg = Message::new(1, Something { empty: true }); let encoded = msg.encode().unwrap(); let decoded = Message::decode(encoded.as_ref()).unwrap(); assert_eq!(msg, decoded); } }