use bytes::Bytes;
#[derive(Debug, Clone, Default)]
pub struct Message {
frames: Vec<Bytes>,
}
impl Message {
#[must_use]
pub const fn new() -> Self {
Self { frames: Vec::new() }
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
frames: Vec::with_capacity(capacity),
}
}
pub fn push(mut self, frame: impl Into<Bytes>) -> Self {
self.frames.push(frame.into());
self
}
#[must_use]
pub fn push_str(mut self, s: &str) -> Self {
self.frames.push(Bytes::copy_from_slice(s.as_bytes()));
self
}
#[must_use]
pub fn push_empty(mut self) -> Self {
self.frames.push(Bytes::new());
self
}
#[cfg(feature = "serde")]
pub fn push_json<T: serde::Serialize>(mut self, value: &T) -> Result<Self, serde_json::Error> {
let json = serde_json::to_vec(value)?;
self.frames.push(Bytes::from(json));
Ok(self)
}
#[cfg(feature = "msgpack")]
pub fn push_msgpack<T: serde::Serialize>(
mut self,
value: &T,
) -> Result<Self, rmp_serde::encode::Error> {
let msgpack = rmp_serde::to_vec(value)?;
self.frames.push(Bytes::from(msgpack));
Ok(self)
}
#[must_use]
pub fn push_u32(mut self, value: u32) -> Self {
self.frames
.push(Bytes::copy_from_slice(&value.to_be_bytes()));
self
}
#[must_use]
pub fn push_u64(mut self, value: u64) -> Self {
self.frames
.push(Bytes::copy_from_slice(&value.to_be_bytes()));
self
}
#[must_use]
pub fn len(&self) -> usize {
self.frames.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.frames.is_empty()
}
#[must_use]
pub fn into_frames(self) -> Vec<Bytes> {
self.frames
}
#[must_use]
pub fn frames(&self) -> &[Bytes] {
&self.frames
}
#[must_use]
pub const fn from_frames(frames: Vec<Bytes>) -> Self {
Self { frames }
}
}
impl From<Vec<Bytes>> for Message {
fn from(frames: Vec<Bytes>) -> Self {
Self::from_frames(frames)
}
}
impl From<Message> for Vec<Bytes> {
fn from(msg: Message) -> Self {
msg.into_frames()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_empty_message() {
let msg = Message::new();
assert_eq!(msg.len(), 0);
assert!(msg.is_empty());
}
#[test]
fn test_build_message() {
let msg = Message::new()
.push_str("topic")
.push_str("Hello")
.push(Vec::from(&b"World"[..]));
assert_eq!(msg.len(), 3);
assert!(!msg.is_empty());
let frames = msg.into_frames();
assert_eq!(frames[0], Bytes::from_static(b"topic"));
assert_eq!(frames[1], Bytes::from_static(b"Hello"));
assert_eq!(frames[2], Bytes::from_static(b"World"));
}
#[test]
fn test_push_empty() {
let msg = Message::new()
.push(Vec::from(&b"id"[..]))
.push_empty()
.push_str("body");
let frames = msg.into_frames();
assert_eq!(frames.len(), 3);
assert_eq!(frames[1].len(), 0);
}
#[test]
fn test_push_integers() {
let msg = Message::new().push_u32(12345).push_u64(67890);
let frames = msg.into_frames();
assert_eq!(frames[0].len(), 4);
assert_eq!(frames[1].len(), 8);
let val32 = u32::from_be_bytes(frames[0].as_ref().try_into().unwrap());
assert_eq!(val32, 12345);
let val64 = u64::from_be_bytes(frames[1].as_ref().try_into().unwrap());
assert_eq!(val64, 67890);
}
#[test]
fn test_with_capacity() {
let msg = Message::with_capacity(10);
assert_eq!(msg.len(), 0);
assert!(msg.frames.capacity() >= 10);
}
#[test]
fn test_from_frames() {
let frames = vec![Bytes::from_static(b"a"), Bytes::from_static(b"b")];
let msg = Message::from_frames(frames.clone());
assert_eq!(msg.len(), 2);
assert_eq!(msg.frames(), &frames[..]);
}
}