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#[cfg(feature = "memmap2")]
198impl IoBuf for memmap2::Mmap {
199 fn as_init(&self) -> &[u8] {
200 self
201 }
202}
203
204#[cfg(feature = "memmap2")]
205impl IoBuf for memmap2::MmapMut {
206 fn as_init(&self) -> &[u8] {
207 self
208 }
209}
210
211#[must_use]
213#[derive(Debug)]
214pub enum ReserveError {
215 NotSupported,
217
218 ReserveFailed(Box<dyn Error + Send + Sync>),
222}
223
224impl ReserveError {
225 pub fn is_not_supported(&self) -> bool {
229 matches!(self, ReserveError::NotSupported)
230 }
231}
232
233impl Display for ReserveError {
234 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235 match self {
236 ReserveError::NotSupported => write!(f, "reservation is not supported"),
237 ReserveError::ReserveFailed(src) => write!(f, "reservation failed: {src}"),
238 }
239 }
240}
241
242impl Error for ReserveError {
243 fn source(&self) -> Option<&(dyn Error + 'static)> {
244 match self {
245 ReserveError::ReserveFailed(src) => Some(src.as_ref()),
246 _ => None,
247 }
248 }
249}
250
251impl From<ReserveError> for std::io::Error {
252 fn from(value: ReserveError) -> Self {
253 match value {
254 ReserveError::NotSupported => {
255 std::io::Error::new(std::io::ErrorKind::Unsupported, "reservation not supported")
256 }
257 ReserveError::ReserveFailed(src) => {
258 std::io::Error::new(std::io::ErrorKind::OutOfMemory, src)
259 }
260 }
261 }
262}
263
264#[must_use]
266#[derive(Debug)]
267pub enum ReserveExactError {
268 NotSupported,
270
271 ReserveFailed(Box<dyn Error + Send + Sync>),
275
276 ExactSizeMismatch {
278 expected: usize,
280
281 reserved: usize,
283 },
284}
285
286impl ReserveExactError {
287 pub fn is_not_supported(&self) -> bool {
291 matches!(self, ReserveExactError::NotSupported)
292 }
293}
294
295impl Display for ReserveExactError {
296 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
297 match self {
298 ReserveExactError::NotSupported => write!(f, "reservation is not supported"),
299 ReserveExactError::ReserveFailed(src) => write!(f, "reservation failed: {src}"),
300 ReserveExactError::ExactSizeMismatch { reserved, expected } => {
301 write!(
302 f,
303 "reserved size mismatch: expected {}, reserved {}",
304 expected, reserved
305 )
306 }
307 }
308 }
309}
310
311impl From<ReserveError> for ReserveExactError {
312 fn from(err: ReserveError) -> Self {
313 match err {
314 ReserveError::NotSupported => ReserveExactError::NotSupported,
315 ReserveError::ReserveFailed(src) => ReserveExactError::ReserveFailed(src),
316 }
317 }
318}
319
320impl Error for ReserveExactError {
321 fn source(&self) -> Option<&(dyn Error + 'static)> {
322 match self {
323 ReserveExactError::ReserveFailed(src) => Some(src.as_ref()),
324 _ => None,
325 }
326 }
327}
328
329impl From<ReserveExactError> for std::io::Error {
330 fn from(value: ReserveExactError) -> Self {
331 match value {
332 ReserveExactError::NotSupported => {
333 std::io::Error::new(std::io::ErrorKind::Unsupported, "reservation not supported")
334 }
335 ReserveExactError::ReserveFailed(src) => {
336 std::io::Error::new(std::io::ErrorKind::OutOfMemory, src)
337 }
338 ReserveExactError::ExactSizeMismatch { expected, reserved } => std::io::Error::other(
339 format!("reserved size mismatch: expected {expected}, reserved {reserved}",),
340 ),
341 }
342 }
343}
344
345#[cfg(feature = "smallvec")]
346mod smallvec_err {
347 use std::{error::Error, fmt::Display};
348
349 use smallvec::CollectionAllocErr;
350
351 #[derive(Debug)]
352 pub(super) struct SmallVecErr(pub CollectionAllocErr);
353
354 impl Display for SmallVecErr {
355 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
356 write!(f, "SmallVec allocation error: {}", self.0)
357 }
358 }
359
360 impl Error for SmallVecErr {}
361}
362
363pub trait IoBufMut: IoBuf + SetLen {
370 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>];
373
374 fn ensure_init(&mut self) -> &mut [u8] {
380 let len = (*self).buf_len();
381 let slice = self.as_uninit();
382 slice[len..].fill(MaybeUninit::new(0));
383 unsafe { slice.assume_init_mut() }
384 }
385
386 fn buf_capacity(&mut self) -> usize {
389 self.as_uninit().len()
390 }
391
392 fn buf_mut_ptr(&mut self) -> *mut MaybeUninit<u8> {
394 self.as_uninit().as_mut_ptr()
395 }
396
397 fn as_mut_slice(&mut self) -> &mut [u8] {
400 let len = (*self).buf_len();
401 let ptr = (*self).buf_mut_ptr();
402 unsafe { std::slice::from_raw_parts_mut(ptr as *mut u8, len) }
407 }
408
409 fn extend_from_slice(&mut self, src: &[u8]) -> Result<(), ReserveError> {
418 let len = src.len();
419 let init = (*self).buf_len();
420 self.reserve(len)?;
421 let ptr = self.buf_mut_ptr().wrapping_add(init);
422
423 unsafe {
424 std::ptr::copy_nonoverlapping(src.as_ptr() as _, ptr, len);
430
431 self.advance_to(init + len);
433 }
434
435 Ok(())
436 }
437
438 fn copy_within<R>(&mut self, src: R, dest: usize)
449 where
450 R: RangeBounds<usize>,
451 {
452 self.as_uninit().copy_within(src, dest);
453 }
454
455 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
469 let init = (*self).buf_len();
470 if len <= self.buf_capacity() - init {
471 return Ok(());
472 }
473 Err(ReserveError::NotSupported)
474 }
475
476 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
486 self.reserve(len)?;
487 Ok(())
488 }
489
490 fn uninit(self) -> Uninit<Self>
511 where
512 Self: Sized,
513 {
514 Uninit::new(self)
515 }
516
517 fn into_writer(self) -> Writer<Self>
520 where
521 Self: Sized,
522 {
523 Writer::new(self)
524 }
525
526 fn as_writer(&mut self) -> WriterRef<'_, Self> {
529 WriterRef::new(self)
530 }
531
532 fn is_filled(&mut self) -> bool {
534 let len = (*self).as_init().len();
535 let cap = (*self).buf_capacity();
536 len == cap
537 }
538}
539
540impl<B: IoBufMut + ?Sized> IoBufMut for &'static mut B {
541 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
542 (**self).as_uninit()
543 }
544
545 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
546 (**self).reserve(len)
547 }
548
549 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
550 (**self).reserve_exact(len)
551 }
552}
553
554impl<B: IoBufMut + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut
555 for t_alloc!(Box, B, A)
556{
557 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
558 (**self).as_uninit()
559 }
560
561 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
562 (**self).reserve(len)
563 }
564
565 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
566 (**self).reserve_exact(len)
567 }
568}
569
570impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut for t_alloc!(Vec, u8, A) {
571 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
572 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
573 let cap = self.capacity();
574 unsafe { std::slice::from_raw_parts_mut(ptr, cap) }
576 }
577
578 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
579 if let Err(e) = Vec::try_reserve(self, len) {
580 return Err(ReserveError::ReserveFailed(Box::new(e)));
581 }
582
583 Ok(())
584 }
585
586 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
587 if self.capacity() - self.len() >= len {
588 return Ok(());
589 }
590
591 if let Err(e) = Vec::try_reserve_exact(self, len) {
592 return Err(ReserveExactError::ReserveFailed(Box::new(e)));
593 }
594
595 if self.capacity() - self.len() != len {
596 return Err(ReserveExactError::ExactSizeMismatch {
597 reserved: self.capacity() - self.len(),
598 expected: len,
599 });
600 }
601 Ok(())
602 }
603}
604
605impl IoBufMut for [u8] {
606 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
607 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
608 let len = self.len();
609 unsafe { std::slice::from_raw_parts_mut(ptr, len) }
611 }
612}
613
614impl<const N: usize> IoBufMut for [u8; N] {
615 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
616 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
617 unsafe { std::slice::from_raw_parts_mut(ptr, N) }
619 }
620}
621
622#[cfg(feature = "bytes")]
623impl IoBufMut for bytes::BytesMut {
624 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
625 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
626 let cap = self.capacity();
627 unsafe { std::slice::from_raw_parts_mut(ptr, cap) }
629 }
630
631 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
632 bytes::BytesMut::reserve(self, len);
633 Ok(())
634 }
635
636 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
637 if self.capacity() - self.len() >= len {
638 return Ok(());
639 }
640
641 bytes::BytesMut::reserve(self, len);
642
643 if self.capacity() - self.len() != len {
644 Err(ReserveExactError::ExactSizeMismatch {
645 reserved: self.capacity() - self.len(),
646 expected: len,
647 })
648 } else {
649 Ok(())
650 }
651 }
652}
653
654#[cfg(feature = "read_buf")]
655impl IoBufMut for std::io::BorrowedBuf<'static> {
656 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
657 let total_cap = self.capacity();
658
659 unsafe {
662 let filled_ptr = self.filled().as_ptr() as *mut MaybeUninit<u8>;
663 std::slice::from_raw_parts_mut(filled_ptr, total_cap)
664 }
665 }
666}
667
668#[cfg(feature = "arrayvec")]
669impl<const N: usize> IoBufMut for arrayvec::ArrayVec<u8, N> {
670 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
671 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
672 unsafe { std::slice::from_raw_parts_mut(ptr, N) }
674 }
675}
676
677#[cfg(feature = "smallvec")]
678impl<const N: usize> IoBufMut for smallvec::SmallVec<[u8; N]>
679where
680 [u8; N]: smallvec::Array<Item = u8>,
681{
682 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
683 let ptr = self.as_mut_ptr() as *mut MaybeUninit<u8>;
684 let cap = self.capacity();
685 unsafe { std::slice::from_raw_parts_mut(ptr, cap) }
687 }
688
689 fn reserve(&mut self, len: usize) -> Result<(), ReserveError> {
690 if let Err(e) = smallvec::SmallVec::try_reserve(self, len) {
691 return Err(ReserveError::ReserveFailed(Box::new(
692 smallvec_err::SmallVecErr(e),
693 )));
694 }
695 Ok(())
696 }
697
698 fn reserve_exact(&mut self, len: usize) -> Result<(), ReserveExactError> {
699 if self.capacity() - self.len() >= len {
700 return Ok(());
701 }
702
703 if let Err(e) = smallvec::SmallVec::try_reserve_exact(self, len) {
704 return Err(ReserveExactError::ReserveFailed(Box::new(
705 smallvec_err::SmallVecErr(e),
706 )));
707 }
708
709 if self.capacity() - self.len() != len {
710 return Err(ReserveExactError::ExactSizeMismatch {
711 reserved: self.capacity() - self.len(),
712 expected: len,
713 });
714 }
715 Ok(())
716 }
717}
718
719#[cfg(feature = "memmap2")]
720impl IoBufMut for memmap2::MmapMut {
721 fn as_uninit(&mut self) -> &mut [MaybeUninit<u8>] {
722 unsafe { std::mem::transmute(self.as_mut_slice()) }
724 }
725}
726
727pub trait SetLen {
729 unsafe fn set_len(&mut self, len: usize);
736
737 unsafe fn advance(&mut self, len: usize)
744 where
745 Self: IoBuf,
746 {
747 let current_len = (*self).buf_len();
748 let new_len = current_len.checked_add(len).expect("length overflow");
749 unsafe { self.set_len(new_len) };
750 }
751
752 unsafe fn advance_to(&mut self, len: usize)
760 where
761 Self: IoBuf,
762 {
763 let current_len = (*self).buf_len();
764 if len > current_len {
765 unsafe { self.set_len(len) };
766 }
767 }
768
769 unsafe fn advance_vec_to(&mut self, len: usize)
777 where
778 Self: IoVectoredBuf,
779 {
780 let current_len = (*self).total_len();
781 if len > current_len {
782 unsafe { self.set_len(len) };
783 }
784 }
785
786 fn clear(&mut self)
789 where
790 Self: IoBuf,
791 {
792 unsafe { self.set_len(0) };
794 }
795}
796
797impl<B: SetLen + ?Sized> SetLen for &'static mut B {
798 unsafe fn set_len(&mut self, len: usize) {
799 unsafe { (**self).set_len(len) }
800 }
801}
802
803impl<B: SetLen + ?Sized, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetLen
804 for t_alloc!(Box, B, A)
805{
806 unsafe fn set_len(&mut self, len: usize) {
807 unsafe { (**self).set_len(len) }
808 }
809}
810
811impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> SetLen for t_alloc!(Vec, u8, A) {
812 unsafe fn set_len(&mut self, len: usize) {
813 unsafe { self.set_len(len) };
814 }
815}
816
817impl SetLen for [u8] {
818 unsafe fn set_len(&mut self, len: usize) {
819 debug_assert!(len <= self.len());
820 }
821}
822
823impl<const N: usize> SetLen for [u8; N] {
824 unsafe fn set_len(&mut self, len: usize) {
825 debug_assert!(len <= N);
826 }
827}
828
829#[cfg(feature = "bytes")]
830impl SetLen for bytes::BytesMut {
831 unsafe fn set_len(&mut self, len: usize) {
832 unsafe { self.set_len(len) };
833 }
834}
835
836#[cfg(feature = "read_buf")]
837impl SetLen for std::io::BorrowedBuf<'static> {
838 unsafe fn set_len(&mut self, len: usize) {
839 debug_assert!(self.capacity() >= len);
840
841 #[allow(unused_unsafe)]
843 unsafe {
844 self.clear().unfilled().advance(len)
845 };
846 }
847}
848
849#[cfg(feature = "arrayvec")]
850impl<const N: usize> SetLen for arrayvec::ArrayVec<u8, N> {
851 unsafe fn set_len(&mut self, len: usize) {
852 if (**self).buf_len() < len {
853 unsafe { self.set_len(len) };
854 }
855 }
856}
857
858#[cfg(feature = "smallvec")]
859impl<const N: usize> SetLen for smallvec::SmallVec<[u8; N]>
860where
861 [u8; N]: smallvec::Array<Item = u8>,
862{
863 unsafe fn set_len(&mut self, len: usize) {
864 if (**self).buf_len() < len {
865 unsafe { self.set_len(len) };
866 }
867 }
868}
869
870#[cfg(feature = "memmap2")]
871impl SetLen for memmap2::MmapMut {
872 unsafe fn set_len(&mut self, len: usize) {
873 debug_assert!(len <= self.len())
874 }
875}
876
877impl<T: IoBufMut> SetLen for [T] {
878 unsafe fn set_len(&mut self, len: usize) {
879 unsafe { default_set_len(self.iter_mut(), len) }
880 }
881}
882
883impl<T: IoBufMut, const N: usize> SetLen for [T; N] {
884 unsafe fn set_len(&mut self, len: usize) {
885 unsafe { default_set_len(self.iter_mut(), len) }
886 }
887}
888
889impl<T: IoBufMut, #[cfg(feature = "allocator_api")] A: Allocator + 'static> SetLen
890 for t_alloc!(Vec, T, A)
891{
892 unsafe fn set_len(&mut self, len: usize) {
893 unsafe { default_set_len(self.iter_mut(), len) }
894 }
895}
896
897#[cfg(feature = "arrayvec")]
898impl<T: IoBufMut, const N: usize> SetLen for arrayvec::ArrayVec<T, N> {
899 unsafe fn set_len(&mut self, len: usize) {
900 unsafe { default_set_len(self.iter_mut(), len) }
901 }
902}
903
904#[cfg(feature = "smallvec")]
905impl<T: IoBufMut, const N: usize> SetLen for smallvec::SmallVec<[T; N]>
906where
907 [T; N]: smallvec::Array<Item = T>,
908{
909 unsafe fn set_len(&mut self, len: usize) {
910 unsafe { default_set_len(self.iter_mut(), len) }
911 }
912}
913
914unsafe fn default_set_len<'a, B: IoBufMut>(
920 iter: impl IntoIterator<Item = &'a mut B>,
921 mut len: usize,
922) {
923 let mut iter = iter.into_iter();
924 while len > 0 {
925 let Some(curr) = iter.next() else { return };
926 let sub = (*curr).buf_capacity().min(len);
927 unsafe { curr.set_len(sub) };
928 len -= sub;
929 }
930}
931
932#[cfg(test)]
933mod test {
934 use crate::IoBufMut;
935
936 #[test]
937 fn test_vec_reserve() {
938 let mut buf = Vec::new();
939 IoBufMut::reserve(&mut buf, 10).unwrap();
940 assert!(buf.capacity() >= 10);
941
942 let mut buf = Vec::new();
943 IoBufMut::reserve_exact(&mut buf, 10).unwrap();
944 assert!(buf.capacity() == 10);
945
946 let mut buf = Box::new(Vec::new());
947 IoBufMut::reserve_exact(&mut buf, 10).unwrap();
948 assert!(buf.capacity() == 10);
949 }
950
951 #[test]
952 #[cfg(feature = "bytes")]
953 fn test_bytes_reserve() {
954 let mut buf = bytes::BytesMut::new();
955 IoBufMut::reserve(&mut buf, 10).unwrap();
956 assert!(buf.capacity() >= 10);
957 }
958
959 #[test]
960 #[cfg(feature = "smallvec")]
961 fn test_smallvec_reserve() {
962 let mut buf = smallvec::SmallVec::<[u8; 8]>::new();
963 IoBufMut::reserve(&mut buf, 10).unwrap();
964 assert!(buf.capacity() >= 10);
965 }
966
967 #[test]
968 #[cfg(feature = "memmap2")]
969 fn tests_memmap2() {
970 use std::{
971 fs::{OpenOptions, remove_file},
972 io::{Seek, SeekFrom, Write},
973 };
974
975 use memmap2::MmapOptions;
976
977 use super::*;
978
979 let path = std::env::temp_dir().join("compio_buf_mmap_mut_test");
980
981 let mut file = OpenOptions::new()
982 .read(true)
983 .write(true)
984 .create(true)
985 .truncate(true)
986 .open(&path)
987 .unwrap();
988 let data = b"hello memmap2";
989 file.write_all(data).unwrap();
990 file.flush().unwrap();
991 file.seek(SeekFrom::Start(0)).unwrap();
992 let mmap = unsafe { MmapOptions::new().map(&file).unwrap() };
993
994 let uninit_slice = mmap.as_init();
995 assert_eq!(uninit_slice, data);
996
997 remove_file(path).unwrap();
998 }
999
1000 #[test]
1001 fn test_other_reserve() {
1002 let mut buf = [1, 1, 4, 5, 1, 4];
1003 let res = IoBufMut::reserve(&mut buf, 10);
1004 assert!(res.is_err_and(|x| x.is_not_supported()));
1005 assert!(buf.buf_capacity() == 6);
1006 }
1007
1008 #[test]
1009 fn test_extend() {
1010 let mut buf = Vec::from(b"hello");
1011 IoBufMut::extend_from_slice(&mut buf, b" world").unwrap();
1012 assert_eq!(buf.as_slice(), b"hello world");
1013
1014 let mut buf = [];
1015 let res = IoBufMut::extend_from_slice(&mut buf, b" ");
1016 assert!(res.is_err_and(|x| x.is_not_supported()));
1017 }
1018}