ipfrs_interface/
zerocopy.rs1use bytes::Bytes;
6
7#[derive(Debug, Clone)]
12pub struct ZeroCopyBuffer {
13 data: Bytes,
14}
15
16impl ZeroCopyBuffer {
17 pub fn new(data: Bytes) -> Self {
19 Self { data }
20 }
21
22 pub fn from_vec(vec: Vec<u8>) -> Self {
24 Self {
25 data: Bytes::from(vec),
26 }
27 }
28
29 pub fn from_static(bytes: &'static [u8]) -> Self {
31 Self {
32 data: Bytes::from_static(bytes),
33 }
34 }
35
36 pub fn as_slice(&self) -> &[u8] {
38 &self.data
39 }
40
41 pub fn len(&self) -> usize {
43 self.data.len()
44 }
45
46 pub fn is_empty(&self) -> bool {
48 self.data.is_empty()
49 }
50
51 pub fn slice(&self, range: std::ops::Range<usize>) -> Self {
56 Self {
57 data: self.data.slice(range),
58 }
59 }
60
61 pub fn into_bytes(self) -> Bytes {
63 self.data
64 }
65
66 pub fn bytes(&self) -> &Bytes {
68 &self.data
69 }
70
71 pub fn split_at(&self, at: usize) -> (Self, Self) {
76 let left = self.data.slice(0..at);
77 let right = self.data.slice(at..);
78 (Self { data: left }, Self { data: right })
79 }
80
81 pub fn split_to(&self, at: usize) -> Self {
83 Self {
84 data: self.data.slice(0..at),
85 }
86 }
87
88 pub fn split_from(&self, at: usize) -> Self {
90 Self {
91 data: self.data.slice(at..),
92 }
93 }
94}
95
96impl From<Vec<u8>> for ZeroCopyBuffer {
97 fn from(vec: Vec<u8>) -> Self {
98 Self::from_vec(vec)
99 }
100}
101
102impl From<Bytes> for ZeroCopyBuffer {
103 fn from(bytes: Bytes) -> Self {
104 Self::new(bytes)
105 }
106}
107
108impl From<&'static [u8]> for ZeroCopyBuffer {
109 fn from(bytes: &'static [u8]) -> Self {
110 Self::from_static(bytes)
111 }
112}
113
114impl AsRef<[u8]> for ZeroCopyBuffer {
115 fn as_ref(&self) -> &[u8] {
116 self.as_slice()
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_zero_copy_buffer_basic() {
126 let data = vec![1, 2, 3, 4, 5];
127 let buf = ZeroCopyBuffer::from_vec(data);
128
129 assert_eq!(buf.len(), 5);
130 assert!(!buf.is_empty());
131 assert_eq!(buf.as_slice(), &[1, 2, 3, 4, 5]);
132 }
133
134 #[test]
135 fn test_zero_copy_slice() {
136 let buf = ZeroCopyBuffer::from_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
137 let slice = buf.slice(2..7);
138
139 assert_eq!(slice.len(), 5);
140 assert_eq!(slice.as_slice(), &[2, 3, 4, 5, 6]);
141 }
142
143 #[test]
144 fn test_zero_copy_split_at() {
145 let buf = ZeroCopyBuffer::from_vec(vec![1, 2, 3, 4, 5]);
146 let (left, right) = buf.split_at(3);
147
148 assert_eq!(left.as_slice(), &[1, 2, 3]);
149 assert_eq!(right.as_slice(), &[4, 5]);
150 }
151
152 #[test]
153 fn test_zero_copy_split_to() {
154 let buf = ZeroCopyBuffer::from_vec(vec![1, 2, 3, 4, 5]);
155 let first = buf.split_to(3);
156
157 assert_eq!(first.as_slice(), &[1, 2, 3]);
158 }
159
160 #[test]
161 fn test_zero_copy_split_from() {
162 let buf = ZeroCopyBuffer::from_vec(vec![1, 2, 3, 4, 5]);
163 let last = buf.split_from(3);
164
165 assert_eq!(last.as_slice(), &[4, 5]);
166 }
167
168 #[test]
169 fn test_zero_copy_from_static() {
170 let buf = ZeroCopyBuffer::from_static(b"hello world");
171
172 assert_eq!(buf.len(), 11);
173 assert_eq!(buf.as_slice(), b"hello world");
174 }
175
176 #[test]
177 fn test_zero_copy_empty() {
178 let buf = ZeroCopyBuffer::from_vec(vec![]);
179
180 assert_eq!(buf.len(), 0);
181 assert!(buf.is_empty());
182 }
183}