1use std::{ops, rc::Rc, sync::Arc};
2
3use super::Slice;
4use crate::buf::slice::SliceMut;
5
6pub unsafe trait IoBuf: Unpin + 'static {
23 fn read_ptr(&self) -> *const u8;
33
34 fn bytes_init(&self) -> usize;
41
42 #[inline]
44 fn as_slice(&self) -> &[u8] {
45 unsafe { core::slice::from_raw_parts(self.read_ptr(), self.bytes_init()) }
46 }
47
48 #[inline]
50 fn slice(self, range: impl ops::RangeBounds<usize>) -> Slice<Self>
51 where
52 Self: Sized,
53 {
54 let (begin, end) = parse_range(range, self.bytes_init());
55 Slice::new(self, begin, end)
56 }
57
58 #[inline]
64 unsafe fn slice_unchecked(self, range: impl ops::RangeBounds<usize>) -> Slice<Self>
65 where
66 Self: Sized,
67 {
68 let (begin, end) = parse_range(range, self.bytes_init());
69 Slice::new_unchecked(self, begin, end)
70 }
71}
72
73unsafe impl IoBuf for Vec<u8> {
74 #[inline]
75 fn read_ptr(&self) -> *const u8 {
76 self.as_ptr()
77 }
78
79 #[inline]
80 fn bytes_init(&self) -> usize {
81 self.len()
82 }
83}
84
85unsafe impl IoBuf for Box<[u8]> {
86 #[inline]
87 fn read_ptr(&self) -> *const u8 {
88 self.as_ptr()
89 }
90
91 #[inline]
92 fn bytes_init(&self) -> usize {
93 self.len()
94 }
95}
96
97unsafe impl IoBuf for &'static [u8] {
98 #[inline]
99 fn read_ptr(&self) -> *const u8 {
100 self.as_ptr()
101 }
102
103 #[inline]
104 fn bytes_init(&self) -> usize {
105 <[u8]>::len(self)
106 }
107}
108
109unsafe impl<const N: usize> IoBuf for Box<[u8; N]> {
110 #[inline]
111 fn read_ptr(&self) -> *const u8 {
112 self.as_ptr()
113 }
114
115 #[inline]
116 fn bytes_init(&self) -> usize {
117 self.len()
118 }
119}
120
121unsafe impl<const N: usize> IoBuf for &'static [u8; N] {
122 #[inline]
123 fn read_ptr(&self) -> *const u8 {
124 self.as_ptr()
125 }
126
127 #[inline]
128 fn bytes_init(&self) -> usize {
129 self.len()
130 }
131}
132
133unsafe impl<const N: usize> IoBuf for &'static mut [u8; N] {
134 #[inline]
135 fn read_ptr(&self) -> *const u8 {
136 self.as_ptr()
137 }
138
139 #[inline]
140 fn bytes_init(&self) -> usize {
141 self.len()
142 }
143}
144
145unsafe impl IoBuf for &'static str {
146 #[inline]
147 fn read_ptr(&self) -> *const u8 {
148 self.as_ptr()
149 }
150
151 #[inline]
152 fn bytes_init(&self) -> usize {
153 <str>::len(self)
154 }
155}
156
157#[cfg(feature = "bytes")]
158unsafe impl IoBuf for bytes::Bytes {
159 #[inline]
160 fn read_ptr(&self) -> *const u8 {
161 self.as_ptr()
162 }
163
164 #[inline]
165 fn bytes_init(&self) -> usize {
166 self.len()
167 }
168}
169
170#[cfg(feature = "bytes")]
171unsafe impl IoBuf for bytes::BytesMut {
172 #[inline]
173 fn read_ptr(&self) -> *const u8 {
174 self.as_ptr()
175 }
176
177 #[inline]
178 fn bytes_init(&self) -> usize {
179 self.len()
180 }
181}
182
183unsafe impl<T> IoBuf for Rc<T>
184where
185 T: IoBuf,
186{
187 #[inline]
188 fn read_ptr(&self) -> *const u8 {
189 <T as IoBuf>::read_ptr(self)
190 }
191
192 #[inline]
193 fn bytes_init(&self) -> usize {
194 <T as IoBuf>::bytes_init(self)
195 }
196}
197
198unsafe impl<T> IoBuf for Arc<T>
199where
200 T: IoBuf,
201{
202 #[inline]
203 fn read_ptr(&self) -> *const u8 {
204 <T as IoBuf>::read_ptr(self)
205 }
206
207 #[inline]
208 fn bytes_init(&self) -> usize {
209 <T as IoBuf>::bytes_init(self)
210 }
211}
212
213unsafe impl<T> IoBuf for std::mem::ManuallyDrop<T>
214where
215 T: IoBuf,
216{
217 fn read_ptr(&self) -> *const u8 {
218 <T as IoBuf>::read_ptr(self)
219 }
220
221 fn bytes_init(&self) -> usize {
222 <T as IoBuf>::bytes_init(self)
223 }
224}
225
226pub unsafe trait IoBufMut: Unpin + 'static {
234 fn write_ptr(&mut self) -> *mut u8;
241
242 fn bytes_total(&mut self) -> usize;
249
250 unsafe fn set_init(&mut self, pos: usize);
260
261 #[inline]
275 fn slice_mut(mut self, range: impl ops::RangeBounds<usize>) -> SliceMut<Self>
276 where
277 Self: Sized,
278 Self: IoBuf,
279 {
280 let (begin, end) = parse_range(range, self.bytes_total());
281 SliceMut::new(self, begin, end)
282 }
283
284 #[inline]
290 unsafe fn slice_mut_unchecked(mut self, range: impl ops::RangeBounds<usize>) -> SliceMut<Self>
291 where
292 Self: Sized,
293 {
294 let (begin, end) = parse_range(range, self.bytes_total());
295 SliceMut::new_unchecked(self, begin, end)
296 }
297}
298
299unsafe impl IoBufMut for Vec<u8> {
300 #[inline]
301 fn write_ptr(&mut self) -> *mut u8 {
302 self.as_mut_ptr()
303 }
304
305 #[inline]
306 fn bytes_total(&mut self) -> usize {
307 self.capacity()
308 }
309
310 #[inline]
311 unsafe fn set_init(&mut self, init_len: usize) {
312 self.set_len(init_len);
313 }
314}
315
316unsafe impl IoBufMut for Box<[u8]> {
317 #[inline]
318 fn write_ptr(&mut self) -> *mut u8 {
319 self.as_mut_ptr()
320 }
321
322 #[inline]
323 fn bytes_total(&mut self) -> usize {
324 self.len()
325 }
326
327 #[inline]
328 unsafe fn set_init(&mut self, _: usize) {}
329}
330
331unsafe impl<const N: usize> IoBufMut for Box<[u8; N]> {
332 #[inline]
333 fn write_ptr(&mut self) -> *mut u8 {
334 self.as_mut_ptr()
335 }
336
337 #[inline]
338 fn bytes_total(&mut self) -> usize {
339 self.len()
340 }
341
342 #[inline]
343 unsafe fn set_init(&mut self, _: usize) {}
344}
345
346unsafe impl<const N: usize> IoBufMut for &'static mut [u8; N] {
347 #[inline]
348 fn write_ptr(&mut self) -> *mut u8 {
349 self.as_mut_ptr()
350 }
351
352 #[inline]
353 fn bytes_total(&mut self) -> usize {
354 self.len()
355 }
356
357 #[inline]
358 unsafe fn set_init(&mut self, _: usize) {}
359}
360
361#[cfg(feature = "bytes")]
362unsafe impl IoBufMut for bytes::BytesMut {
363 #[inline]
364 fn write_ptr(&mut self) -> *mut u8 {
365 self.as_mut_ptr()
366 }
367
368 #[inline]
369 fn bytes_total(&mut self) -> usize {
370 self.capacity()
371 }
372
373 #[inline]
374 unsafe fn set_init(&mut self, init_len: usize) {
375 if self.len() < init_len {
376 self.set_len(init_len);
377 }
378 }
379}
380
381unsafe impl<T> IoBufMut for std::mem::ManuallyDrop<T>
382where
383 T: IoBufMut,
384{
385 fn write_ptr(&mut self) -> *mut u8 {
386 <T as IoBufMut>::write_ptr(self)
387 }
388
389 fn bytes_total(&mut self) -> usize {
390 <T as IoBufMut>::bytes_total(self)
391 }
392
393 unsafe fn set_init(&mut self, pos: usize) {
394 <T as IoBufMut>::set_init(self, pos)
395 }
396}
397
398fn parse_range(range: impl ops::RangeBounds<usize>, end: usize) -> (usize, usize) {
399 use core::ops::Bound;
400
401 let begin = match range.start_bound() {
402 Bound::Included(&n) => n,
403 Bound::Excluded(&n) => n + 1,
404 Bound::Unbounded => 0,
405 };
406
407 let end = match range.end_bound() {
408 Bound::Included(&n) => n.checked_add(1).expect("out of range"),
409 Bound::Excluded(&n) => n,
410 Bound::Unbounded => end,
411 };
412 (begin, end)
413}
414
415#[cfg(test)]
416mod tests {
417 use std::mem::ManuallyDrop;
418
419 use super::*;
420
421 #[test]
422 fn io_buf_vec() {
423 let mut buf = Vec::with_capacity(10);
424 buf.extend_from_slice(b"0123");
425 let ptr = buf.as_mut_ptr();
426
427 assert_eq!(buf.read_ptr(), ptr);
428 assert_eq!(buf.bytes_init(), 4);
429
430 assert_eq!(buf.write_ptr(), ptr);
431 assert_eq!(buf.bytes_total(), 10);
432
433 unsafe { buf.set_init(8) };
434 assert_eq!(buf.bytes_init(), 8);
435 assert_eq!(buf.len(), 8);
436 }
437
438 #[test]
439 fn io_buf_str() {
440 let s = "hello world";
441 let ptr = s.as_ptr();
442
443 assert_eq!(s.read_ptr(), ptr);
444 assert_eq!(s.bytes_init(), 11);
445 }
446
447 #[test]
448 fn io_buf_n() {
449 let mut buf = Box::new([1, 2, 3, 4, 5]);
450 let ptr = buf.as_mut_ptr();
451
452 assert_eq!(buf.read_ptr(), ptr);
453 assert_eq!(buf.bytes_init(), 5);
454 assert_eq!(buf.write_ptr(), ptr);
455 assert_eq!(buf.bytes_total(), 5);
456 }
457
458 #[test]
459 fn io_buf_n_boxed() {
460 let mut buf = Box::new([1, 2, 3, 4, 5]);
461 let ptr = buf.as_mut_ptr();
462
463 assert_eq!(buf.read_ptr(), ptr);
464 assert_eq!(buf.bytes_init(), 5);
465 assert_eq!(buf.write_ptr(), ptr);
466 assert_eq!(buf.bytes_total(), 5);
467 }
468
469 #[test]
470 fn io_buf_n_static() {
471 let buf = &*Box::leak(Box::new([1, 2, 3, 4, 5]));
472 let ptr = buf.as_ptr();
473
474 assert_eq!(buf.read_ptr(), ptr);
475 assert_eq!(buf.bytes_init(), 5);
476 }
477
478 #[test]
479 fn io_buf_n_mut_static() {
480 let mut buf = Box::leak(Box::new([1, 2, 3, 4, 5]));
481 let ptr = buf.as_mut_ptr();
482
483 assert_eq!(buf.read_ptr(), ptr);
484 assert_eq!(buf.bytes_init(), 5);
485 assert_eq!(buf.write_ptr(), ptr);
486 assert_eq!(buf.bytes_total(), 5);
487 }
488
489 #[test]
490 fn io_buf_rc_str() {
491 let s = Rc::new("hello world");
492 let ptr = s.as_ptr();
493
494 assert_eq!(s.read_ptr(), ptr);
495 assert_eq!(s.bytes_init(), 11);
496 }
497
498 #[test]
499 fn io_buf_arc_str() {
500 let s = Arc::new("hello world");
501 let ptr = s.as_ptr();
502
503 assert_eq!(s.read_ptr(), ptr);
504 assert_eq!(s.bytes_init(), 11);
505 }
506
507 #[test]
508 fn io_buf_slice_ref() {
509 let s: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
510 let ptr = s.as_ptr();
511
512 assert_eq!(s.read_ptr(), ptr);
513 assert_eq!(s.bytes_init(), 10);
514 }
515
516 #[test]
517 fn io_buf_slice() {
518 let mut buf = Vec::with_capacity(10);
519 buf.extend_from_slice(b"0123");
520 let ptr = buf.as_mut_ptr();
521
522 let slice = buf.slice(1..3);
523 assert_eq!((slice.begin(), slice.end()), (1, 3));
524 assert_eq!(slice.read_ptr(), unsafe { ptr.add(1) });
525 assert_eq!(slice.bytes_init(), 2);
526 let buf = slice.into_inner();
527
528 let mut slice = buf.slice_mut(1..8);
529 assert_eq!((slice.begin(), slice.end()), (1, 8));
530 assert_eq!(slice.write_ptr(), unsafe { ptr.add(1) });
531 assert_eq!(slice.bytes_total(), 7);
532 unsafe { slice.set_init(5) };
533 assert_eq!(slice.bytes_init(), 5);
534 assert_eq!(slice.into_inner().len(), 6);
535 }
536
537 #[test]
538 fn io_buf_arc_slice() {
539 let mut buf = Vec::with_capacity(10);
540 buf.extend_from_slice(b"0123");
541 let buf = Arc::new(buf);
542 let ptr = buf.as_ptr();
543
544 let slice = buf.slice(1..3);
545 assert_eq!((slice.begin(), slice.end()), (1, 3));
546 assert_eq!(slice.read_ptr(), unsafe { ptr.add(1) });
547 assert_eq!(slice.bytes_init(), 2);
548 let buf = Arc::into_inner(slice.into_inner()).unwrap();
549
550 let mut slice = buf.slice_mut(1..8);
551 assert_eq!((slice.begin(), slice.end()), (1, 8));
552 assert_eq!(slice.bytes_total(), 7);
553 unsafe { slice.set_init(5) };
554 assert_eq!(slice.bytes_init(), 5);
555 assert_eq!(slice.into_inner().len(), 6);
556 }
557
558 #[test]
559 fn io_buf_manually_drop() {
560 let mut buf = Vec::with_capacity(10);
561 buf.extend_from_slice(b"0123");
562 let mut buf = ManuallyDrop::new(buf);
563 let ptr = buf.as_ptr();
564
565 assert_eq!(buf.write_ptr(), ptr as _);
566 assert_eq!(buf.read_ptr(), ptr);
567 assert_eq!(buf.bytes_init(), 4);
568 unsafe { buf.set_init(3) };
569 assert_eq!(buf.bytes_init(), 3);
570 assert_eq!(buf.bytes_total(), 10);
571
572 let slice = buf.slice(1..3);
573 assert_eq!((slice.begin(), slice.end()), (1, 3));
574 assert_eq!(slice.read_ptr(), unsafe { ptr.add(1) });
575 assert_eq!(slice.bytes_init(), 2);
576 let buf = ManuallyDrop::into_inner(slice.into_inner());
577
578 let mut slice = buf.slice_mut(1..8);
579 assert_eq!((slice.begin(), slice.end()), (1, 8));
580 assert_eq!(slice.bytes_total(), 7);
581 unsafe { slice.set_init(5) };
582 assert_eq!(slice.bytes_init(), 5);
583 assert_eq!(slice.into_inner().len(), 6);
584 }
585}