use crate::message::flags::MsgFlags;
use crate::message::metadata::Metadata;
use bytes::Bytes;
use std::fmt;
#[derive(Clone, Default)]
pub struct Msg {
data: Option<Bytes>,
flags: MsgFlags,
metadata: Metadata, }
impl Msg {
pub fn new() -> Self {
Self::default()
}
pub fn from_vec(data: Vec<u8>) -> Self {
Self {
data: Some(Bytes::from(data)),
..Default::default()
}
}
pub fn from_bytes(data: Bytes) -> Self {
Self {
data: Some(data),
..Default::default()
}
}
pub fn from_static(data: &'static [u8]) -> Self {
Self {
data: Some(Bytes::from_static(data)),
..Default::default()
}
}
pub fn data(&self) -> Option<&[u8]> {
self.data.as_deref()
}
pub fn size(&self) -> usize {
self.data.as_ref().map_or(0, |d| d.len())
}
pub fn flags(&self) -> MsgFlags {
self.flags
}
pub fn set_flags(&mut self, flags: MsgFlags) {
self.flags = flags;
}
pub fn metadata(&self) -> &Metadata {
&self.metadata
}
pub fn metadata_mut(&mut self) -> &mut Metadata {
&mut self.metadata
}
pub fn is_more(&self) -> bool {
self.flags.contains(MsgFlags::MORE)
}
pub fn is_command(&self) -> bool {
self.flags.contains(MsgFlags::COMMAND)
}
pub fn data_bytes(&self) -> Option<Bytes> {
self.data.clone()
}
}
#[cfg(test)]
mod additional_msg_tests {
use super::*;
#[test]
fn test_msg_zero_copy_clone() {
let payload = bytes::Bytes::from_static(b"shared-payload");
let msg_a = Msg::from_bytes(payload.clone());
let msg_b = msg_a.clone();
assert_eq!(
msg_a.data().unwrap().as_ptr(),
msg_b.data().unwrap().as_ptr()
);
assert_eq!(msg_a.size(), msg_b.size());
}
#[test]
fn test_msg_flag_mutations() {
let mut msg = Msg::new();
assert!(!msg.is_more());
assert!(!msg.is_command());
msg.set_flags(MsgFlags::MORE);
assert!(msg.is_more());
assert!(!msg.is_command());
msg.set_flags(MsgFlags::COMMAND);
assert!(!msg.is_more());
assert!(msg.is_command());
}
#[test]
fn test_msg_empty_payload() {
let msg = Msg::new();
assert_eq!(msg.size(), 0);
assert!(msg.data().is_none());
assert!(msg.data_bytes().is_none());
}
}
impl fmt::Debug for Msg {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Msg")
.field("size", &self.size())
.field("flags", &self.flags)
.field("data", &self.data().map(|d| format!("{} bytes", d.len()))) .field("metadata", &self.metadata) .finish()
}
}