1#[cfg(feature = "allocator_api")]
2use std::alloc::Allocator;
3use std::{error::Error, fmt::Display, mem::MaybeUninit, ops::RangeBounds, rc::Rc, sync::Arc};
4
5use crate::*;
6
7pub trait IoBuf: 'static {
13 fn as_init(&self) -> &[u8];
15
16 fn buf_len(&self) -> usize {
18 self.as_init().len()
19 }
20
21 fn buf_ptr(&self) -> *const u8 {
23 self.as_init().as_ptr()
24 }
25
26 fn is_empty(&self) -> bool {
28 self.buf_len() == 0
29 }
30
31 fn slice(self, range: impl std::ops::RangeBounds<usize>) -> Slice<Self>
50 where
51 Self: Sized,
52 {
53 use std::ops::Bound;
54
55 let begin = match range.start_bound() {
56 Bound::Included(&n) => n,
57 Bound::Excluded(&n) => n + 1,
58 Bound::Unbounded => 0,
59 };
60
61 let end = match range.end_bound() {
62 Bound::Included(&n) => Some(n.checked_add(1).expect("out of range")),
63 Bound::Excluded(&n) => Some(n),
64 Bound::Unbounded => None,
65 };
66
67 assert!(begin <= self.buf_len());
68
69 if let Some(end) = end {
70 assert!(begin <= end);
71 }
72
73 unsafe { Slice::new(self, begin, end) }
75 }
76
77 fn into_reader(self) -> Reader<Self>
80 where
81 Self: Sized,
82 {
83 Reader::new(self)
84 }
85
86 fn as_reader(&self) -> ReaderRef<'_, Self> {
89 ReaderRef::new(self)
90 }
91}
92
93impl<B: IoBuf + ?Sized> IoBuf for &'static B {
94 fn as_init(&self) -> &[u8] {
95 (**self).as_init()
96 }
97}
98
99impl<B: IoBuf + ?Sized> IoBuf for &'static mut B {
100 fn as_init(&self) -> &[u8] {
101 (**self).as_init()
102 }
103}
104
105impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
106 for t_alloc!(Box, B, A)
107{
108 fn as_init(&self) -> &[u8] {
109 (**self).as_init()
110 }
111}
112
113impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
114 for t_alloc!(Rc, B, A)
115{
116 fn as_init(&self) -> &[u8] {
117 (**self).as_init()
118 }
119}
120
121impl IoBuf for [u8] {
122 fn as_init(&self) -> &[u8] {
123 self
124 }
125}
126
127impl<const N: usize> IoBuf for [u8; N] {
128 fn as_init(&self) -> &[u8] {
129 self
130 }
131}
132
133impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf for t_alloc!(Vec, u8, A) {
134 fn as_init(&self) -> &[u8] {
135 self
136 }
137}
138
139impl IoBuf for str {
140 fn as_init(&self) -> &[u8] {
141 self.as_bytes()
142 }
143}
144
145impl IoBuf for String {
146 fn as_init(&self) -> &[u8] {
147 self.as_bytes()
148 }
149}
150
151impl<B: IoBuf + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf
152 for t_alloc!(Arc, B, A)
153{
154 fn as_init(&self) -> &[u8] {
155 (**self).as_init()
156 }
157}
158
159#[cfg(feature = "bytes")]
160impl IoBuf for bytes::Bytes {
161 fn as_init(&self) -> &[u8] {
162 self
163 }
164}
165
166#[cfg(feature = "bytes")]
167impl IoBuf for bytes::BytesMut {
168 fn as_init(&self) -> &[u8] {
169 self
170 }
171}
172
173#[cfg(feature = "read_buf")]
174impl IoBuf for std::io::BorrowedBuf<'static> {
175 fn as_init(&self) -> &[u8] {
176 self.filled()
177 }
178}
179
180#[cfg(feature = "arrayvec")]
181impl<const N: usize> IoBuf for arrayvec::ArrayVec<u8, N> {
182 fn as_init(&self) -> &[u8] {
183 self
184 }
185}
186
187#[cfg(feature = "smallvec")]
188impl<const N: usize> IoBuf for smallvec::SmallVec<[u8; N]>
189where
190 [u8; N]: smallvec::Array<Item = u8>,
191{
192 fn as_init(&self) -> &[u8] {
193 self
194 }
195}
196
197#[must_use]
199#[derive(Debug)]
200pub enum ReserveError {
201 NotSupported,
203
204 ReserveFailed(Box<dyn Error + Send + Sync>),
208}
209
210impl ReserveError {
211 pub fn is_not_supported(&self) -> bool {
215 matches!(self, ReserveError::NotSupported)
216 }
217}
218
219impl Display for ReserveError {
220 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
221 match self {
222 ReserveError::NotSupported => write!(f, "reservation is not supported"),
223 ReserveError::ReserveFailed(src) => write!(f, "reservation failed: {src}"),
224 }
225 }
226}
227
228impl Error for ReserveError {
229 fn source(&self) -> Option<&(dyn Error + 'static)> {
230 match self {
231 ReserveError::ReserveFailed(src) => Some(src.as_ref()),
232 _ => None,
233 }
234 }
235}
236
237impl From<ReserveError> for std::io::Error {
238 fn from(value: ReserveError) -> Self {
239 match value {
240 ReserveError::NotSupported => {
241 std::io::Error::new(std::io::ErrorKind::Unsupported, "reservation not supported")
242 }
243 ReserveError::ReserveFailed(src) => {
244 std::io::Error::new(std::io::ErrorKind::OutOfMemory, src)
245 }
246 }
247 }
248}
249
250#[must_use]
252#[derive(Debug)]
253pub enum ReserveExactError {
254 NotSupported,
256
257 ReserveFailed(Box<dyn Error + Send + Sync>),
261
262 ExactSizeMismatch {
264 expected: usize,
266
267 reserved: usize,
269 },
270}
271
272impl ReserveExactError {
273 pub fn is_not_supported(&self) -> bool {
277 matches!(self, ReserveExactError::NotSupported)
278 }
279}
280
281impl Display for ReserveExactError {
282 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283 match self {
284 ReserveExactError::NotSupported => write!(f, "reservation is not supported"),
285 ReserveExactError::ReserveFailed(src) => write!(f, "reservation failed: {src}"),
286 ReserveExactError::ExactSizeMismatch { reserved, expected } => {
287 write!(
288 f,
289 "reserved size mismatch: expected {}, reserved {}",
290 expected, reserved
291 )
292 }
293 }
294 }
295}
296
297impl From<ReserveError> for ReserveExactError {
298 fn from(err: ReserveError) -> Self {
299 match err {
300 ReserveError::NotSupported => ReserveExactError::NotSupported,
301 ReserveError::ReserveFailed(src) => ReserveExactError::ReserveFailed(src),
302 }
303 }
304}
305
306impl Error for ReserveExactError {
307 fn source(&self) -> Option<&(dyn Error + 'static)> {
308 match self {
309 ReserveExactError::ReserveFailed(src) => Some(src.as_ref()),
310 _ => None,
311 }
312 }
313}
314
315impl From<ReserveExactError> for std::io::Error {
316 fn from(value: ReserveExactError) -> Self {
317 match value {
318 ReserveExactError::NotSupported => {
319 std::io::Error::new(std::io::ErrorKind::Unsupported, "reservation not supported")
320 }
321 ReserveExactError::ReserveFailed(src) => {
322 std::io::Error::new(std::io::ErrorKind::OutOfMemory, src)
323 }
324 ReserveExactError::ExactSizeMismatch { expected, reserved } => std::io::Error::other(
325 format!("reserved size mismatch: expected {expected}, reserved {reserved}",),
326 ),
327 }
328 }
329}
330
331#[cfg(feature = "smallvec")]
332mod smallvec_err {
333 use std::{error::Error, fmt::Display};
334
335 use smallvec::CollectionAllocErr;
336
337 #[derive(Debug)]
338 pub(super) struct SmallVecErr(pub CollectionAllocErr);
339
340 impl Display for SmallVecErr {
341 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
342 write!(f, "SmallVec allocation error: {}", self.0)
343 }
344 }
345
346 impl Error for SmallVecErr {}
347}
348
349pub trait IoBufMut: IoBuf + SetLen {
356 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>];
359
360 fn buf_capacity(&mut self) -> usize {
363 self.as_uninit().len()
364 }
365
366 fn buf_mut_ptr(&mut self) -> *mut MaybeUninit<u8> {
368 self.as_uninit().as_mut_ptr()
369 }
370
371 fn as_mut_slice(&mut self) -> &mut [u8] {
374 let len = (*self).buf_len();
375 let ptr = (*self).buf_mut_ptr();
376 unsafe { std::slice::from_raw_parts_mut(ptr as *mut u8, len) }
381 }
382
383 fn extend_from_slice(&mut self, src: &[u8]) -> Result<(), ReserveError> {
392 let len = src.len();
393 let init = (*self).buf_len();
394 self.reserve(len)?;
395 let ptr = self.buf_mut_ptr().wrapping_add(init);
396
397 unsafe {
398 std::ptr::copy_nonoverlapping(src.as_ptr() as _, ptr, len);
404
405 self.advance_to(init + len);
407 }
408
409 Ok(())
410 }
411
412 fn copy_within<R>(&mut self, src: R, dest: usize)
423 where
424 R: RangeBounds<usize>,
425 {
426 self.as_uninit().copy_within(src, dest);
427 }
428
429 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
443 let init = (*self).buf_len();
444 if len <= self.buf_capacity() - init {
445 return Ok(());
446 }
447 Err(ReserveError::NotSupported)
448 }
449
450 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
460 self.reserve(len)?;
461 Ok(())
462 }
463
464 fn uninit(self) -> Uninit<Self>
485 where
486 Self: Sized,
487 {
488 Uninit::new(self)
489 }
490
491 fn into_writer(self) -> Writer<Self>
494 where
495 Self: Sized,
496 {
497 Writer::new(self)
498 }
499
500 fn as_writer(&mut self) -> WriterRef<'_, Self> {
503 WriterRef::new(self)
504 }
505
506 fn is_filled(&mut self) -> bool {
508 let len = (*self).as_init().len();
509 let cap = (*self).buf_capacity();
510 len == cap
511 }
512}
513
514impl<B: IoBufMut + ?Sized> IoBufMut for &'static mut B {
515 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
516 (**self).as_uninit()
517 }
518
519 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
520 (**self).reserve(len)
521 }
522
523 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
524 (**self).reserve_exact(len)
525 }
526}
527
528impl<B: IoBufMut + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut
529 for t_alloc!(Box, B, A)
530{
531 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
532 (**self).as_uninit()
533 }
534
535 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
536 (**self).reserve(len)
537 }
538
539 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
540 (**self).reserve_exact(len)
541 }
542}
543
544impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut for t_alloc!(Vec, u8, A) {
545 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
546 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
547 let cap = self.capacity();
548 unsafe { std::slice::from_raw_parts_mut(ptr, cap) }
550 }
551
552 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
553 if let Err(e) = Vec::try_reserve(self, len) {
554 return Err(ReserveError::ReserveFailed(Box::new(e)));
555 }
556
557 Ok(())
558 }
559
560 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
561 if self.capacity() - self.len() >= len {
562 return Ok(());
563 }
564
565 if let Err(e) = Vec::try_reserve_exact(self, len) {
566 return Err(ReserveExactError::ReserveFailed(Box::new(e)));
567 }
568
569 if self.capacity() - self.len() != len {
570 return Err(ReserveExactError::ExactSizeMismatch {
571 reserved: self.capacity() - self.len(),
572 expected: len,
573 });
574 }
575 Ok(())
576 }
577}
578
579impl IoBufMut for [u8] {
580 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
581 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
582 let len = self.len();
583 unsafe { std::slice::from_raw_parts_mut(ptr, len) }
585 }
586}
587
588impl<const N: usize> IoBufMut for [u8; N] {
589 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
590 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
591 unsafe { std::slice::from_raw_parts_mut(ptr, N) }
593 }
594}
595
596#[cfg(feature = "bytes")]
597impl IoBufMut for bytes::BytesMut {
598 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
599 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
600 let cap = self.capacity();
601 unsafe { std::slice::from_raw_parts_mut(ptr, cap) }
603 }
604
605 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
606 bytes::BytesMut::reserve(self, len);
607 Ok(())
608 }
609
610 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
611 if self.capacity() - self.len() >= len {
612 return Ok(());
613 }
614
615 bytes::BytesMut::reserve(self, len);
616
617 if self.capacity() - self.len() != len {
618 Err(ReserveExactError::ExactSizeMismatch {
619 reserved: self.capacity() - self.len(),
620 expected: len,
621 })
622 } else {
623 Ok(())
624 }
625 }
626}
627
628#[cfg(feature = "read_buf")]
629impl IoBufMut for std::io::BorrowedBuf<'static> {
630 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
631 let total_cap = self.capacity();
632
633 unsafe {
636 let filled_ptr = self.filled().as_ptr() as *mut MaybeUninit<u8>;
637 std::slice::from_raw_parts_mut(filled_ptr, total_cap)
638 }
639 }
640}
641
642#[cfg(feature = "arrayvec")]
643impl<const N: usize> IoBufMut for arrayvec::ArrayVec<u8, N> {
644 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
645 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
646 unsafe { std::slice::from_raw_parts_mut(ptr, N) }
648 }
649}
650
651#[cfg(feature = "smallvec")]
652impl<const N: usize> IoBufMut for smallvec::SmallVec<[u8; N]>
653where
654 [u8; N]: smallvec::Array<Item = u8>,
655{
656 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
657 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
658 let cap = self.capacity();
659 unsafe { std::slice::from_raw_parts_mut(ptr, cap) }
661 }
662
663 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
664 if let Err(e) = smallvec::SmallVec::try_reserve(self, len) {
665 return Err(ReserveError::ReserveFailed(Box::new(
666 smallvec_err::SmallVecErr(e),
667 )));
668 }
669 Ok(())
670 }
671
672 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
673 if self.capacity() - self.len() >= len {
674 return Ok(());
675 }
676
677 if let Err(e) = smallvec::SmallVec::try_reserve_exact(self, len) {
678 return Err(ReserveExactError::ReserveFailed(Box::new(
679 smallvec_err::SmallVecErr(e),
680 )));
681 }
682
683 if self.capacity() - self.len() != len {
684 return Err(ReserveExactError::ExactSizeMismatch {
685 reserved: self.capacity() - self.len(),
686 expected: len,
687 });
688 }
689 Ok(())
690 }
691}
692
693pub trait SetLen {
695 unsafe fn set_len(&mut self, len: usize);
702
703 unsafe fn advance(&mut self, len: usize)
710 where
711 Self: IoBuf,
712 {
713 let current_len = (*self).buf_len();
714 let new_len = current_len.checked_add(len).expect("length overflow");
715 unsafe { self.set_len(new_len) };
716 }
717
718 unsafe fn advance_to(&mut self, len: usize)
726 where
727 Self: IoBuf,
728 {
729 let current_len = (*self).buf_len();
730 if len > current_len {
731 unsafe { self.set_len(len) };
732 }
733 }
734
735 unsafe fn advance_vec_to(&mut self, len: usize)
743 where
744 Self: IoVectoredBuf,
745 {
746 let current_len = (*self).total_len();
747 if len > current_len {
748 unsafe { self.set_len(len) };
749 }
750 }
751
752 fn clear(&mut self)
755 where
756 Self: IoBuf,
757 {
758 unsafe { self.set_len(0) };
760 }
761}
762
763impl<B: SetLen + ?Sized> SetLen for &'static mut B {
764 unsafe fn set_len(&mut self, len: usize) {
765 unsafe { (**self).set_len(len) }
766 }
767}
768
769impl<B: SetLen + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetLen
770 for t_alloc!(Box, B, A)
771{
772 unsafe fn set_len(&mut self, len: usize) {
773 unsafe { (**self).set_len(len) }
774 }
775}
776
777impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> SetLen for t_alloc!(Vec, u8, A) {
778 unsafe fn set_len(&mut self, len: usize) {
779 unsafe { self.set_len(len) };
780 }
781}
782
783impl SetLen for [u8] {
784 unsafe fn set_len(&mut self, len: usize) {
785 debug_assert!(len <= self.len());
786 }
787}
788
789impl<const N: usize> SetLen for [u8; N] {
790 unsafe fn set_len(&mut self, len: usize) {
791 debug_assert!(len <= N);
792 }
793}
794
795#[cfg(feature = "bytes")]
796impl SetLen for bytes::BytesMut {
797 unsafe fn set_len(&mut self, len: usize) {
798 unsafe { self.set_len(len) };
799 }
800}
801
802#[cfg(feature = "read_buf")]
803impl SetLen for std::io::BorrowedBuf<'static> {
804 unsafe fn set_len(&mut self, len: usize) {
805 debug_assert!(self.capacity() >= len);
806
807 self.clear().unfilled().advance(len);
809 }
810}
811
812#[cfg(feature = "arrayvec")]
813impl<const N: usize> SetLen for arrayvec::ArrayVec<u8, N> {
814 unsafe fn set_len(&mut self, len: usize) {
815 if (**self).buf_len() < len {
816 unsafe { self.set_len(len) };
817 }
818 }
819}
820
821#[cfg(feature = "smallvec")]
822impl<const N: usize> SetLen for smallvec::SmallVec<[u8; N]>
823where
824 [u8; N]: smallvec::Array<Item = u8>,
825{
826 unsafe fn set_len(&mut self, len: usize) {
827 if (**self).buf_len() < len {
828 unsafe { self.set_len(len) };
829 }
830 }
831}
832
833impl<T: IoBufMut> SetLen for [T] {
834 unsafe fn set_len(&mut self, len: usize) {
835 unsafe { default_set_len(self.iter_mut(), len) }
836 }
837}
838
839impl<T: IoBufMut, const N: usize> SetLen for [T; N] {
840 unsafe fn set_len(&mut self, len: usize) {
841 unsafe { default_set_len(self.iter_mut(), len) }
842 }
843}
844
845impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetLen
846 for t_alloc!(Vec, T, A)
847{
848 unsafe fn set_len(&mut self, len: usize) {
849 unsafe { default_set_len(self.iter_mut(), len) }
850 }
851}
852
853#[cfg(feature = "arrayvec")]
854impl<T: IoBufMut, const N: usize> SetLen for arrayvec::ArrayVec<T, N> {
855 unsafe fn set_len(&mut self, len: usize) {
856 unsafe { default_set_len(self.iter_mut(), len) }
857 }
858}
859
860#[cfg(feature = "smallvec")]
861impl<T: IoBufMut, const N: usize> SetLen for smallvec::SmallVec<[T; N]>
862where
863 [T; N]: smallvec::Array<Item = T>,
864{
865 unsafe fn set_len(&mut self, len: usize) {
866 unsafe { default_set_len(self.iter_mut(), len) }
867 }
868}
869
870unsafe fn default_set_len<'a, B: IoBufMut>(
876 iter: impl IntoIterator<Item = &'a mut B>,
877 mut len: usize,
878) {
879 let mut iter = iter.into_iter();
880 while len > 0 {
881 let Some(curr) = iter.next() else { return };
882 let sub = (*curr).buf_capacity().min(len);
883 unsafe { curr.set_len(sub) };
884 len -= sub;
885 }
886}
887
888#[cfg(test)]
889mod test {
890 use crate::IoBufMut;
891
892 #[test]
893 fn test_vec_reserve() {
894 let mut buf = Vec::new();
895 IoBufMut::reserve(&mut buf, 10).unwrap();
896 assert!(buf.capacity() >= 10);
897
898 let mut buf = Vec::new();
899 IoBufMut::reserve_exact(&mut buf, 10).unwrap();
900 assert!(buf.capacity() == 10);
901
902 let mut buf = Box::new(Vec::new());
903 IoBufMut::reserve_exact(&mut buf, 10).unwrap();
904 assert!(buf.capacity() == 10);
905 }
906
907 #[test]
908 #[cfg(feature = "bytes")]
909 fn test_bytes_reserve() {
910 let mut buf = bytes::BytesMut::new();
911 IoBufMut::reserve(&mut buf, 10).unwrap();
912 assert!(buf.capacity() >= 10);
913 }
914
915 #[test]
916 #[cfg(feature = "smallvec")]
917 fn test_smallvec_reserve() {
918 let mut buf = smallvec::SmallVec::<[u8; 8]>::new();
919 IoBufMut::reserve(&mut buf, 10).unwrap();
920 assert!(buf.capacity() >= 10);
921 }
922
923 #[test]
924 fn test_other_reserve() {
925 let mut buf = [1, 1, 4, 5, 1, 4];
926 let res = IoBufMut::reserve(&mut buf, 10);
927 assert!(res.is_err_and(|x| x.is_not_supported()));
928 assert!(buf.buf_capacity() == 6);
929 }
930
931 #[test]
932 fn test_extend() {
933 let mut buf = Vec::from(b"hello");
934 IoBufMut::extend_from_slice(&mut buf, b" world").unwrap();
935 assert_eq!(buf.as_slice(), b"hello world");
936
937 let mut buf = [];
938 let res = IoBufMut::extend_from_slice(&mut buf, b" ");
939 assert!(res.is_err_and(|x| x.is_not_supported()));
940 }
941}