use std::borrow::Cow;
use bytes::{Buf, BufMut};
use crate::protocol::{BinaryMessage, BinaryPayload, ParseError};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MessageData<'a> {
pub channel_id: u32,
pub data: Cow<'a, [u8]>,
}
impl<'a> MessageData<'a> {
pub fn new(channel_id: u32, data: impl Into<Cow<'a, [u8]>>) -> Self {
Self {
channel_id,
data: data.into(),
}
}
pub fn into_owned(self) -> MessageData<'static> {
MessageData {
channel_id: self.channel_id,
data: Cow::Owned(self.data.into_owned()),
}
}
}
impl<'a> BinaryPayload<'a> for MessageData<'a> {
fn parse_payload(mut data: &'a [u8]) -> Result<Self, ParseError> {
if data.len() < 4 {
return Err(ParseError::BufferTooShort);
}
let channel_id = data.get_u32_le();
Ok(Self {
channel_id,
data: Cow::Borrowed(data),
})
}
fn payload_size(&self) -> usize {
4 + self.data.len()
}
fn write_payload(&self, buf: &mut impl BufMut) {
buf.put_u32_le(self.channel_id);
buf.put_slice(&self.data);
}
}
impl<'a> BinaryMessage<'a> for MessageData<'a> {
const OPCODE: u8 = 1;
}
#[cfg(test)]
mod tests {
use super::*;
fn message() -> MessageData<'static> {
MessageData::new(30, br#"{"key": "value"}"#)
}
#[test]
fn test_roundtrip() {
let orig = message();
let mut buf = Vec::new();
BinaryPayload::write_payload(&orig, &mut buf);
let parsed = MessageData::parse_payload(&buf).unwrap();
assert_eq!(parsed, orig);
}
}