use std::sync::atomic::{AtomicU32, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
static GLOBAL_MSG_COUNTER: AtomicU32 = AtomicU32::new(1);
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct MessageId(pub u64);
impl MessageId {
pub(crate) fn generate(_counter: u32) -> Self {
let unix_secs = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
let counter = GLOBAL_MSG_COUNTER.fetch_add(1, Ordering::Relaxed);
let id = (unix_secs << 32) | (u64::from(counter) << 2);
Self(id)
}
}
#[derive(Debug)]
pub struct Message {
pub id: MessageId,
pub seq_no: i32,
pub body: Vec<u8>,
}
impl Message {
pub fn plaintext(id: MessageId, seq_no: i32, body: Vec<u8>) -> Self {
Self { id, seq_no, body }
}
pub fn to_plaintext_bytes(&self) -> Vec<u8> {
let mut buf = Vec::with_capacity(8 + 8 + 4 + self.body.len());
buf.extend(0i64.to_le_bytes()); buf.extend(self.id.0.to_le_bytes()); buf.extend((self.body.len() as u32).to_le_bytes()); buf.extend(&self.body);
buf
}
}