use crate::Timestamp;
#[derive(Debug, Clone, Copy)]
pub struct PacketView<'a> {
pub frame: &'a [u8],
pub timestamp: Timestamp,
}
impl<'a> PacketView<'a> {
#[inline]
pub fn new(frame: &'a [u8], timestamp: Timestamp) -> Self {
Self { frame, timestamp }
}
#[inline]
pub fn with_frame<'b>(self, frame: &'b [u8]) -> PacketView<'b>
where
'a: 'b,
{
PacketView {
frame,
timestamp: self.timestamp,
}
}
}
pub trait AsPacketView {
fn as_packet_view(&self) -> PacketView<'_>;
}
impl<'a, T: AsPacketView + ?Sized> From<&'a T> for PacketView<'a> {
fn from(t: &'a T) -> Self {
t.as_packet_view()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_and_fields() {
let buf = [0u8; 8];
let v = PacketView::new(&buf, Timestamp::new(1, 2));
assert_eq!(v.frame.len(), 8);
assert_eq!(v.timestamp, Timestamp::new(1, 2));
}
#[test]
fn with_frame_replaces_slice_keeps_ts() {
let outer = [1u8, 2, 3, 4];
let inner = [9u8, 9];
let v = PacketView::new(&outer, Timestamp::new(7, 0));
let w = v.with_frame(&inner);
assert_eq!(w.frame, &inner);
assert_eq!(w.timestamp, Timestamp::new(7, 0));
}
#[test]
fn as_packet_view_blanket_works() {
struct MyPacket {
bytes: Vec<u8>,
ts: Timestamp,
}
impl AsPacketView for MyPacket {
fn as_packet_view(&self) -> PacketView<'_> {
PacketView::new(&self.bytes, self.ts)
}
}
let pkt = MyPacket {
bytes: vec![1, 2, 3, 4],
ts: Timestamp::new(42, 0),
};
let v = pkt.as_packet_view();
assert_eq!(v.frame, &[1, 2, 3, 4]);
assert_eq!(v.timestamp, Timestamp::new(42, 0));
let v: PacketView<'_> = (&pkt).into();
assert_eq!(v.frame, &[1, 2, 3, 4]);
let boxed: Box<dyn AsPacketView> = Box::new(MyPacket {
bytes: vec![9],
ts: Timestamp::new(1, 0),
});
let v = boxed.as_packet_view();
assert_eq!(v.frame, &[9]);
}
}