1pub trait Buffer {
5 type Freeze;
7
8 fn with_capacity(capacity: usize) -> Self
10 where
11 Self: Sized;
12
13 fn is_empty(&self) -> bool;
15
16 #[inline]
21 fn extend(&mut self, src: &str) {
22 unsafe {
24 self.extend_from_slice(src.as_bytes());
25 }
26 }
27
28 fn len(&self) -> usize;
29
30 unsafe fn extend_from_slice(&mut self, src: &[u8]);
38
39 fn reserve(&mut self, additional: usize);
45
46 fn freeze(self) -> Self::Freeze;
48
49 unsafe fn advance(&mut self, cnt: usize);
57
58 unsafe fn buf_ptr(&mut self) -> *mut u8;
63}
64
65impl Buffer for Vec<u8> {
66 type Freeze = Vec<u8>;
67
68 #[inline]
69 fn with_capacity(capacity: usize) -> Self
70 where
71 Self: Sized,
72 {
73 Vec::with_capacity(capacity)
74 }
75
76 #[inline]
77 fn is_empty(&self) -> bool {
78 self.is_empty()
79 }
80
81 #[inline]
82 fn len(&self) -> usize {
83 self.len()
84 }
85
86 #[inline]
87 unsafe fn extend_from_slice(&mut self, src: &[u8]) {
88 Buffer::reserve(self, src.len());
89 debug_assert!(self.capacity() - self.len() >= src.len());
90 std::ptr::copy_nonoverlapping(src.as_ptr(), self.buf_ptr(), src.len());
91 Buffer::advance(self, src.len())
92 }
93
94 #[inline]
95 fn reserve(&mut self, additional: usize) {
96 debug_assert!(self.len() <= self.capacity());
97 if self.capacity().wrapping_sub(self.len()) < additional {
98 self.reserve(additional);
99 }
100 }
101
102 #[inline]
103 fn freeze(mut self) -> Self::Freeze {
104 self.shrink_to_fit();
105 self
106 }
107
108 #[inline]
109 unsafe fn advance(&mut self, cnt: usize) {
110 self.set_len(self.len() + cnt);
111 }
112
113 #[inline]
114 unsafe fn buf_ptr(&mut self) -> *mut u8 {
115 self.as_mut_ptr().add(self.len())
116 }
117}
118
119impl Buffer for String {
120 type Freeze = String;
121
122 #[inline]
123 fn with_capacity(capacity: usize) -> Self
124 where
125 Self: Sized,
126 {
127 String::with_capacity(capacity)
128 }
129
130 #[inline]
131 fn is_empty(&self) -> bool {
132 self.is_empty()
133 }
134
135 #[inline]
136 fn len(&self) -> usize {
137 self.len()
138 }
139
140 #[inline]
141 unsafe fn extend_from_slice(&mut self, src: &[u8]) {
142 Buffer::reserve(self, src.len());
143 debug_assert!(self.capacity() - self.len() >= src.len());
144 std::ptr::copy_nonoverlapping(src.as_ptr(), self.buf_ptr(), src.len());
145 Buffer::advance(self, src.len())
146 }
147
148 #[inline]
149 fn reserve(&mut self, additional: usize) {
150 debug_assert!(self.len() <= self.capacity());
151 if self.capacity().wrapping_sub(self.len()) < additional {
152 self.reserve(additional);
153 }
154 }
155
156 #[inline]
157 fn freeze(mut self) -> Self::Freeze {
158 self.shrink_to_fit();
159 self
160 }
161
162 #[inline]
163 unsafe fn advance(&mut self, cnt: usize) {
164 let len = self.len() + cnt;
165 self.as_mut_vec().set_len(len);
166 }
167
168 #[inline]
169 unsafe fn buf_ptr(&mut self) -> *mut u8 {
170 self.as_mut_ptr().add(self.len())
171 }
172}
173
174#[cfg(any(feature = "bytes", feature = "ntex-bytes"))]
175macro_rules! implement {
176 ($base:path) => {
177 pub use $base::{Bytes, BytesMut};
178
179 impl Buffer for BytesMut {
180 type Freeze = Bytes;
181
182 #[inline]
183 fn with_capacity(capacity: usize) -> Self
184 where
185 Self: Sized,
186 {
187 BytesMut::with_capacity(capacity)
188 }
189
190 #[inline]
191 fn is_empty(&self) -> bool {
192 self.is_empty()
193 }
194
195 #[inline]
196 fn len(&self) -> usize {
197 self.len()
198 }
199
200 #[inline]
201 unsafe fn extend_from_slice(&mut self, src: &[u8]) {
202 Buffer::reserve(self, src.len());
203 debug_assert!(self.capacity() - self.len() >= src.len());
204 std::ptr::copy_nonoverlapping(src.as_ptr(), Buffer::buf_ptr(self), src.len());
205 Buffer::advance(self, src.len());
206 }
207
208 #[inline(always)]
209 fn reserve(&mut self, additional: usize) {
210 self.reserve(additional);
211 }
212
213 #[inline(always)]
214 fn freeze(self) -> Self::Freeze {
215 self.freeze()
216 }
217
218 #[inline]
219 unsafe fn advance(&mut self, cnt: usize) {
220 let new_len = self.len() + cnt;
221 debug_assert!(
222 new_len <= self.capacity(),
223 "new_len = {}; capacity = {}",
224 new_len,
225 self.capacity()
226 );
227 self.set_len(new_len);
228 }
229
230 #[inline]
231 unsafe fn buf_ptr(&mut self) -> *mut u8 {
232 self.as_mut_ptr().add(self.len())
233 }
234 }
235
236 #[cfg(test)]
237 mod test_bytes {
238 use super::*;
239
240 #[test]
241 fn test() {
242 let e = "Hello world!";
243 let mut buf: BytesMut = Buffer::with_capacity(0);
244 Buffer::extend(&mut buf, e);
245 assert_eq!(e.as_bytes(), &Buffer::freeze(buf)[..]);
246
247 let mut buf: BytesMut = Buffer::with_capacity(124);
248 Buffer::extend(&mut buf, e);
249 assert_eq!(e.as_bytes(), &Buffer::freeze(buf)[..]);
250 }
251 }
252 };
253}
254
255#[cfg(feature = "bytes")]
256pub mod tokio_bytes {
257 use super::*;
258 implement!(bytes);
259}
260
261#[cfg(feature = "ntex-bytes")]
262pub mod ntex {
263 use super::*;
264 implement!(ntex_bytes);
265}
266
267#[cfg(test)]
268mod test {
269 use super::*;
270
271 #[test]
272 fn test() {
273 let e = "Hello world!";
274 let mut buf: Vec<u8> = Buffer::with_capacity(0);
275 Buffer::extend(&mut buf, e);
276 assert_eq!(e.as_bytes(), &Buffer::freeze(buf)[..]);
277
278 let mut buf: Vec<u8> = Buffer::with_capacity(124);
279 Buffer::extend(&mut buf, e);
280 assert_eq!(e.as_bytes(), &Buffer::freeze(buf)[..]);
281
282 let mut buf: Vec<u8> = Buffer::with_capacity(14);
283 Buffer::extend(&mut buf, e);
284 }
285}