1use std::borrow::Cow;
2use std::ops::Deref;
3
4pub struct Frame<'a> {
6 data: Cow<'a, [u8]>,
7}
8
9impl<'a> Frame<'a> {
10 pub fn new(data: &'a [u8]) -> Self {
12 Self {
13 data: Cow::Borrowed(data),
14 }
15 }
16
17 pub fn new_borrowed(data: &'a [u8]) -> Self {
20 Self::new(data)
21 }
22
23 pub fn new_owned(data: Vec<u8>) -> Self {
25 Self {
26 data: Cow::Owned(data),
27 }
28 }
29
30 pub fn len(&self) -> usize {
32 self.data.len()
33 }
34
35 pub fn is_empty(&self) -> bool {
37 self.data.is_empty()
38 }
39
40 pub fn payload(&self) -> &[u8] {
42 self.data.as_ref()
43 }
44}
45
46impl Deref for Frame<'_> {
47 type Target = [u8];
48
49 fn deref(&self) -> &Self::Target {
50 self.data.as_ref()
51 }
52}
53
54impl<'a> From<&'a [u8]> for Frame<'a> {
55 fn from(data: &'a [u8]) -> Self {
56 Self::new(data)
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn new_borrows_zero_copy() {
66 let data = b"hello netmap";
67 let frame = Frame::new(data);
68 assert_eq!(frame.len(), data.len());
69 assert_eq!(frame.payload(), data);
70 assert!(matches!(frame.data, Cow::Borrowed(_)));
71 }
72
73 #[test]
74 fn new_borrowed_is_alias() {
75 let data = b"alias check";
76 let frame = Frame::new_borrowed(data);
77 assert_eq!(frame.len(), data.len());
78 assert_eq!(frame.payload(), data);
79 }
80
81 #[test]
82 fn new_owned_copies() {
83 let owned = b"owned payload".to_vec();
84 let frame = Frame::new_owned(owned.clone());
85 assert_eq!(frame.len(), owned.len());
86 assert_eq!(frame.payload(), owned.as_slice());
87 assert!(matches!(frame.data, Cow::Owned(_)));
88 }
89
90 #[test]
91 fn from_slice_impl() {
92 let data = b"from slice";
93 let frame: Frame = data.as_slice().into();
94 assert_eq!(frame.payload(), data);
95 }
96
97 #[test]
98 fn empty_frame() {
99 let frame = Frame::new(&[]);
100 assert!(frame.is_empty());
101 assert_eq!(frame.len(), 0);
102 assert_eq!(frame.payload(), &[] as &[u8]);
103 }
104
105 #[test]
106 fn deref_to_slice() {
107 let data = b"deref";
108 let frame = Frame::new(data);
109 assert_eq!(&frame[..], data);
110 assert_eq!(frame.len(), data.len());
111 }
112}