use bytes::{BufMut, BytesMut};
use nom::{
number::complete::{be_u32, be_u64},
IResult,
};
use core::time::Duration;
pub struct DeliveryStatus {
pub message_id: u32,
pub timestamp: Duration,
}
impl DeliveryStatus {
pub fn parse_frame(input: &[u8]) -> IResult<&[u8], Self> {
let (rest, message_id) = be_u32(input)?;
let (rest, timestamp) = be_u64(rest)?;
Ok((
rest,
Self {
message_id,
timestamp: Duration::from_millis(timestamp),
},
))
}
pub fn parse(input: &[u8]) -> Option<Self> {
Self::parse_frame(input).ok().map(|(_, message)| message)
}
pub fn serialize(self) -> BytesMut {
let mut out = BytesMut::with_capacity(4 + 8);
out.put_u32(self.message_id);
out.put_u64(self.timestamp.as_millis() as u64);
out
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serialize_deserialize() {
let serialized = DeliveryStatus {
message_id: 13371338u32,
timestamp: Duration::from_millis(13391440),
}
.serialize();
let DeliveryStatus {
message_id,
timestamp,
} = DeliveryStatus::parse(&serialized).unwrap();
assert_eq!(message_id, 13371338u32);
assert_eq!(timestamp, Duration::from_millis(13391440));
}
}