Skip to main content

wincode/io/
cursor.rs

1use super::*;
2#[cfg(feature = "alloc")]
3use {alloc::vec::Vec, core::slice::from_raw_parts_mut};
4
5/// `Cursor` wraps an in-memory buffer, providing [`Reader`] and [`Writer`] functionality
6/// for types implementing <code>[AsRef]<\[u8]></code>.
7///
8/// This can be especially useful for wrapping [`Reader`]s and [`Writer`]s that are consumed by
9/// reading or writing like `&[u8]` or `&mut [MaybeUninit<u8>]`, making them reusable.
10///
11/// # Examples
12///
13/// Using `Cursor` to write to a `MaybeUninit<[u8; N]>`.
14///
15/// ```
16/// # use rand::random;
17/// # use core::mem::MaybeUninit;
18/// use wincode::io::{Cursor, Reader, Writer};
19///
20/// fn rand_bytes() -> [u8; 8] {
21///     random::<u64>().to_le_bytes()
22/// }
23///
24/// let mut data = MaybeUninit::<[u8; 8]>::uninit();
25///
26/// let mut cursor = Cursor::new(&mut data);
27/// let bytes = rand_bytes();
28/// cursor.write(&bytes).unwrap();
29/// assert_eq!(unsafe { data.assume_init() }, bytes);
30///
31/// // We can write over the same buffer multiple times with a new Cursor.
32/// let mut cursor = Cursor::new(&mut data);
33/// let bytes = rand_bytes();
34/// cursor.write(&bytes).unwrap();
35/// assert_eq!(unsafe { data.assume_init() }, bytes);
36/// ```
37///
38/// Using `Cursor` to write to a `Vec`'s spare capacity.
39///
40/// ```
41/// # #[cfg(feature = "alloc")] {
42/// # use rand::random;
43/// use wincode::io::{Cursor, Reader, Writer};
44///
45/// # fn rand_bytes() -> [u8; 8] {
46/// #     random::<u64>().to_le_bytes()
47/// # }
48/// let mut data = Vec::with_capacity(8);
49///
50/// let mut cursor = Cursor::new(&mut data);
51/// let bytes = rand_bytes();
52/// cursor.write(&bytes).unwrap();
53/// assert_eq!(data, bytes);
54///
55/// // We can write over the same buffer multiple times with a new Cursor.
56/// let mut cursor = Cursor::new(&mut data);
57/// let bytes = rand_bytes();
58/// cursor.write(&bytes).unwrap();
59/// assert_eq!(data, bytes);
60/// # }
61/// ```
62pub struct Cursor<T> {
63    inner: T,
64    pos: usize,
65}
66
67impl<T> Cursor<T> {
68    pub const fn new(inner: T) -> Self {
69        Self { inner, pos: 0 }
70    }
71
72    /// Creates a new cursor at the given position.
73    pub const fn new_at(inner: T, pos: usize) -> Self {
74        Self { inner, pos }
75    }
76
77    /// Sets the position of the cursor.
78    pub const fn set_position(&mut self, pos: usize) {
79        self.pos = pos;
80    }
81
82    /// Consumes the cursor and returns the inner value.
83    pub fn into_inner(self) -> T {
84        self.inner
85    }
86
87    /// Returns the current position of the cursor.
88    pub const fn position(&self) -> usize {
89        self.pos
90    }
91}
92
93impl<T> Cursor<T>
94where
95    T: AsRef<[u8]>,
96{
97    /// Returns a slice of the remaining bytes in the cursor.
98    #[inline]
99    fn cur_slice(&self) -> &[u8] {
100        let slice = self.inner.as_ref();
101        &slice[self.pos.min(slice.len())..]
102    }
103
104    /// Returns the number of bytes remaining in the cursor.
105    #[inline]
106    fn cur_len(&self) -> usize {
107        self.inner.as_ref().len().saturating_sub(self.pos)
108    }
109
110    /// Split the cursor at `mid` and consume the left slice.
111    #[inline]
112    fn consume_slice_checked(&mut self, mid: usize) -> ReadResult<&[u8]> {
113        let slice = self.inner.as_ref();
114        let cur = &slice[self.pos.min(slice.len())..];
115        let Some(left) = cur.get(..mid) else {
116            return Err(read_size_limit(mid));
117        };
118        // SAFETY: We just created a slice of `pos..pos + mid` bytes from the cursor, so `pos + mid` is valid.
119        self.pos = unsafe { self.pos.unchecked_add(mid) };
120        Ok(left)
121    }
122}
123
124impl<'a, T> Reader<'a> for Cursor<T>
125where
126    T: AsRef<[u8]>,
127{
128    type Trusted<'b>
129        = TrustedSliceReader<'a, 'b>
130    where
131        Self: 'b;
132
133    #[inline]
134    fn fill_buf(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
135        let src = self.cur_slice();
136        Ok(&src[..n_bytes.min(src.len())])
137    }
138
139    #[inline]
140    fn fill_exact(&mut self, n_bytes: usize) -> ReadResult<&[u8]> {
141        let Some(src) = self.cur_slice().get(..n_bytes) else {
142            return Err(read_size_limit(n_bytes));
143        };
144        Ok(src)
145    }
146
147    #[inline]
148    unsafe fn consume_unchecked(&mut self, amt: usize) {
149        self.pos = unsafe { self.pos.unchecked_add(amt) };
150    }
151
152    fn consume(&mut self, amt: usize) -> ReadResult<()> {
153        if self.cur_len() < amt {
154            return Err(read_size_limit(amt));
155        }
156        // SAFETY: We just checked that `cur_len() >= amt`.
157        unsafe { self.consume_unchecked(amt) };
158        Ok(())
159    }
160
161    #[inline]
162    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> ReadResult<Self::Trusted<'_>> {
163        Ok(TrustedSliceReader::new(
164            self.consume_slice_checked(n_bytes)?,
165        ))
166    }
167}
168
169/// Helper functions for writing to `Cursor<&mut [MaybeUninit<u8>]>` and `Cursor<&mut MaybeUninit<[u8; N]>>`.
170mod uninit_slice {
171    use super::*;
172
173    /// Get a mutable slice of the remaining bytes in the cursor.
174    #[inline]
175    pub(super) fn cur_slice_mut(
176        inner: &mut [MaybeUninit<u8>],
177        pos: usize,
178    ) -> &mut [MaybeUninit<u8>] {
179        let len = inner.len();
180        &mut inner[pos.min(len)..]
181    }
182
183    /// Get a mutable slice of `len` bytes from the cursor at the current position,
184    /// returning an error if the slice does not have at least `len` bytes remaining.
185    #[inline]
186    pub(super) fn get_slice_mut_checked(
187        inner: &mut [MaybeUninit<u8>],
188        pos: usize,
189        len: usize,
190    ) -> WriteResult<&mut [MaybeUninit<u8>]> {
191        let Some(dst) = cur_slice_mut(inner, pos).get_mut(..len) else {
192            return Err(write_size_limit(len));
193        };
194        Ok(dst)
195    }
196
197    /// Write `src` to the cursor at the current position and advance the position by `src.len()`.
198    pub(super) fn write(
199        inner: &mut [MaybeUninit<u8>],
200        pos: &mut usize,
201        src: &[u8],
202    ) -> WriteResult<()> {
203        let len = src.len();
204        let dst = get_slice_mut_checked(inner, *pos, len)?;
205        // SAFETY: dst is a valid slice of `len` bytes.
206        unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), len) };
207        // SAFETY: We just wrote `len` bytes to the slice of `pos..pos + len`, so `pos + len` is valid.
208        *pos = unsafe { pos.unchecked_add(len) };
209        Ok(())
210    }
211
212    #[inline]
213    pub(super) fn as_trusted_for<'a>(
214        inner: &'a mut [MaybeUninit<u8>],
215        pos: &mut usize,
216        n_bytes: usize,
217    ) -> WriteResult<TrustedSliceWriter<'a>> {
218        let dst = get_slice_mut_checked(inner, *pos, n_bytes)?;
219        // SAFETY: We just created a slice of `pos..pos + n_bytes`, so `pos + n_bytes` is valid.
220        *pos = unsafe { pos.unchecked_add(n_bytes) };
221        Ok(TrustedSliceWriter::new(dst))
222    }
223}
224
225impl Writer for Cursor<&mut [MaybeUninit<u8>]> {
226    type Trusted<'b>
227        = TrustedSliceWriter<'b>
228    where
229        Self: 'b;
230
231    #[inline]
232    fn write(&mut self, src: &[u8]) -> WriteResult<()> {
233        uninit_slice::write(self.inner, &mut self.pos, src)
234    }
235
236    #[inline]
237    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
238        uninit_slice::as_trusted_for(self.inner, &mut self.pos, n_bytes)
239    }
240}
241
242impl<const N: usize> Cursor<&mut MaybeUninit<[u8; N]>> {
243    #[inline(always)]
244    // `core::mem::transpose` is not yet stabilized.
245    pub(super) const fn transpose(inner: &mut MaybeUninit<[u8; N]>) -> &mut [MaybeUninit<u8>; N] {
246        // SAFETY: MaybeUninit<[u8; N]> is equivalent to [MaybeUninit<u8>; N].
247        unsafe { transmute::<&mut MaybeUninit<[u8; N]>, &mut [MaybeUninit<u8>; N]>(inner) }
248    }
249}
250
251impl<const N: usize> Writer for Cursor<&mut MaybeUninit<[u8; N]>> {
252    type Trusted<'b>
253        = TrustedSliceWriter<'b>
254    where
255        Self: 'b;
256
257    #[inline]
258    fn write(&mut self, src: &[u8]) -> WriteResult<()> {
259        uninit_slice::write(Self::transpose(self.inner), &mut self.pos, src)
260    }
261
262    #[inline]
263    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
264        uninit_slice::as_trusted_for(Self::transpose(self.inner), &mut self.pos, n_bytes)
265    }
266}
267
268/// Helper functions for writing to `Cursor<&mut Vec<u8>>` and `Cursor<Vec<u8>>`.
269#[cfg(feature = "alloc")]
270mod vec {
271    use super::*;
272
273    /// Grow the vector if necessary to accommodate the given `needed` bytes.
274    ///
275    /// Note this differs from [`Vec::reserve`] in that it reserves relative to the cursor's
276    /// current position, rather than the initialized length of the vector. The `Cursor<Vec<u8>>`
277    /// implementation overwrites existing elements of the vector, so growing relative to length
278    /// would unnecessarily over-allocate memory.
279    ///
280    /// # Panics
281    ///
282    /// Panics if the new capacity exceeds `isize::MAX` _bytes_.
283    #[inline]
284    pub(super) fn maybe_grow(inner: &mut Vec<u8>, pos: usize, needed: usize) -> WriteResult<()> {
285        let Some(required) = pos.checked_add(needed) else {
286            return Err(write_size_limit(needed));
287        };
288        if required > inner.capacity() {
289            grow(inner, required);
290        }
291        #[cold]
292        fn grow(inner: &mut Vec<u8>, required: usize) {
293            // SAFETY: We just checked that `required > inner.capacity()` (which is greater than
294            // or equal to `inner.len()`), so this will not underflow.
295            let additional = unsafe { required.unchecked_sub(inner.len()) };
296            inner.reserve(additional);
297        }
298        Ok(())
299    }
300
301    /// Add `len` to the cursor's position and update the length of the vector if necessary.
302    ///
303    /// # SAFETY:
304    /// - Must be called after a successful write to the vector.
305    pub(super) unsafe fn add_len(inner: &mut Vec<u8>, pos: &mut usize, len: usize) {
306        // SAFETY: We just wrote `len` bytes to the vector, so `pos + len` is valid.
307        let next_pos = unsafe { pos.unchecked_add(len) };
308
309        // If pos exceeds the length of the vector, we just wrote to uninitialized capacity,
310        // which is now initialized.
311        if next_pos > inner.len() {
312            unsafe {
313                inner.set_len(next_pos);
314            }
315        }
316        *pos = next_pos;
317    }
318
319    /// Write `src` to the vector at the current position and advance the position by `src.len()`.
320    pub(super) fn write(inner: &mut Vec<u8>, pos: &mut usize, src: &[u8]) -> WriteResult<()> {
321        maybe_grow(inner, *pos, src.len())?;
322        // SAFETY: We just ensured at least `pos + src.len()` capacity is available.
323        unsafe { ptr::copy_nonoverlapping(src.as_ptr(), inner.as_mut_ptr().add(*pos), src.len()) };
324        // SAFETY: We just wrote `src.len()` bytes to the vector.
325        unsafe { add_len(inner, pos, src.len()) };
326        Ok(())
327    }
328
329    /// Advance the position by `n_bytes` and return a [`TrustedSliceWriter`] that can elide bounds
330    /// checking within that `n_bytes` window.
331    #[inline]
332    pub(super) fn as_trusted_for<'a>(
333        inner: &'a mut Vec<u8>,
334        pos: &'a mut usize,
335        n_bytes: usize,
336    ) -> WriteResult<TrustedVecWriter<'a>> {
337        maybe_grow(inner, *pos, n_bytes)?;
338        let buf = unsafe {
339            from_raw_parts_mut(
340                inner.as_mut_ptr().cast::<MaybeUninit<u8>>(),
341                inner.capacity(),
342            )
343        };
344        Ok(TrustedVecWriter::new(buf, pos))
345    }
346
347    #[inline]
348    pub(super) fn finish(inner: &mut Vec<u8>, pos: &mut usize) {
349        if *pos > inner.len() {
350            unsafe {
351                inner.set_len(*pos);
352            }
353        }
354    }
355}
356
357/// Trusted writer for `Cursor<&mut Vec<u8>>` or `Cursor<Vec<u8>>` that continues
358/// overwriting the vector's memory.
359///
360/// Generally this should not be constructed directly, but rather by calling [`Writer::as_trusted_for`]
361/// on a trusted [`Writer`]. This will ensure that the safety invariants are upheld.
362///
363/// Note that this does *not* update the length of the vector, as it only contains a reference to the
364/// vector's memory via `&mut [MaybeUninit<u8>]`, but it will update the _position_ of the cursor.
365/// Vec implementations will synchronize the length and position on subsequent writes or when the
366/// writer is finished. Benchmarks showed a roughly 2x performance improvement using this method
367/// rather than taking a `&mut Vec<u8>` directly.
368///
369/// # Safety
370///
371/// - This will _not_ grow the vector, as it assumes the caller has already reserved enough capacity.
372///   The `inner` buffer must have sufficient capacity for all writes. It is UB if this is not upheld.
373#[cfg(feature = "alloc")]
374pub struct TrustedVecWriter<'a> {
375    inner: &'a mut [MaybeUninit<u8>],
376    pos: &'a mut usize,
377}
378
379#[cfg(feature = "alloc")]
380impl<'a> TrustedVecWriter<'a> {
381    pub fn new(inner: &'a mut [MaybeUninit<u8>], pos: &'a mut usize) -> Self {
382        Self { inner, pos }
383    }
384}
385
386#[cfg(feature = "alloc")]
387impl<'a> Writer for TrustedVecWriter<'a> {
388    type Trusted<'b>
389        = TrustedVecWriter<'b>
390    where
391        Self: 'b;
392
393    fn write(&mut self, src: &[u8]) -> WriteResult<()> {
394        // SAFETY: Creator of this writer ensures we have sufficient capacity for all writes.
395        unsafe {
396            ptr::copy_nonoverlapping(
397                src.as_ptr().cast(),
398                self.inner.as_mut_ptr().add(*self.pos),
399                src.len(),
400            )
401        };
402
403        *self.pos = unsafe { self.pos.unchecked_add(src.len()) };
404        Ok(())
405    }
406
407    #[inline]
408    unsafe fn as_trusted_for(&mut self, _n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
409        Ok(TrustedVecWriter::new(self.inner, self.pos))
410    }
411}
412
413/// Writer implementation for `&mut Vec<u8>` that overwrites the underlying vector's memory.
414/// The vector will grow as needed.
415///
416/// # Examples
417///
418/// Overwriting an existing vector.
419/// ```
420/// # #[cfg(feature = "alloc")] {
421/// # use wincode::io::{Cursor, Writer};
422/// let mut vec = vec![0; 3];
423/// let mut cursor = Cursor::new(&mut vec);
424/// let bytes = [1, 2, 3, 4];
425/// cursor.write(&bytes).unwrap();
426/// assert_eq!(&vec, &[1, 2, 3, 4]);
427/// # }
428/// ```
429///
430/// Growing a vector.
431/// ```
432/// # #[cfg(feature = "alloc")] {
433/// # use wincode::io::{Cursor, Writer};
434/// let mut vec = vec![];
435/// let mut cursor = Cursor::new(&mut vec);
436/// let bytes = [1, 2, 3];
437/// cursor.write(&bytes).unwrap();
438/// assert_eq!(&vec, &[1, 2, 3]);
439/// # }
440/// ```
441#[cfg(feature = "alloc")]
442impl Writer for Cursor<&mut Vec<u8>> {
443    type Trusted<'b>
444        = TrustedVecWriter<'b>
445    where
446        Self: 'b;
447
448    #[inline]
449    fn write(&mut self, src: &[u8]) -> WriteResult<()> {
450        vec::write(self.inner, &mut self.pos, src)
451    }
452
453    #[inline]
454    fn finish(&mut self) -> WriteResult<()> {
455        vec::finish(self.inner, &mut self.pos);
456        Ok(())
457    }
458
459    #[inline]
460    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
461        vec::as_trusted_for(self.inner, &mut self.pos, n_bytes)
462    }
463}
464
465/// Writer implementation for `Vec<u8>` that overwrites the underlying vector's memory.
466/// The vector will grow as needed.
467/// # Examples
468///
469/// Overwriting an existing vector.
470/// ```
471/// # #[cfg(feature = "alloc")] {
472/// # use wincode::io::{Cursor, Writer};
473/// let mut cursor = Cursor::new(vec![0; 3]);
474/// let bytes = [1, 2, 3, 4];
475/// cursor.write(&bytes).unwrap();
476/// assert_eq!(cursor.into_inner(), &[1, 2, 3, 4]);
477/// # }
478/// ```
479///
480/// Growing a vector.
481/// ```
482/// # #[cfg(feature = "alloc")] {
483/// # use wincode::io::{Cursor, Writer};
484/// let mut cursor = Cursor::new(vec![]);
485/// let bytes = [1, 2, 3];
486/// cursor.write(&bytes).unwrap();
487/// assert_eq!(cursor.into_inner(), &[1, 2, 3]);
488/// # }
489/// ```
490#[cfg(feature = "alloc")]
491impl Writer for Cursor<Vec<u8>> {
492    type Trusted<'b>
493        = TrustedVecWriter<'b>
494    where
495        Self: 'b;
496
497    #[inline]
498    fn write(&mut self, src: &[u8]) -> WriteResult<()> {
499        vec::write(&mut self.inner, &mut self.pos, src)
500    }
501
502    #[inline]
503    fn finish(&mut self) -> WriteResult<()> {
504        vec::finish(&mut self.inner, &mut self.pos);
505        Ok(())
506    }
507
508    #[inline]
509    unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<Self::Trusted<'_>> {
510        vec::as_trusted_for(&mut self.inner, &mut self.pos, n_bytes)
511    }
512}
513
514#[cfg(all(test, feature = "alloc"))]
515mod tests {
516    #![allow(clippy::arithmetic_side_effects)]
517    use {super::*, crate::proptest_config::proptest_cfg, alloc::vec, proptest::prelude::*};
518
519    proptest! {
520        #![proptest_config(proptest_cfg())]
521
522        #[test]
523        fn cursor_read_no_panic_no_ub_check(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
524            let mut cursor = Cursor::new_at(&bytes, pos);
525            let buf = cursor.fill_buf(bytes.len()).unwrap();
526            if pos > bytes.len() {
527                // fill-buf should return an empty slice if the position
528                // is greater than the length of the bytes.
529                prop_assert_eq!(buf, &[]);
530            } else {
531                prop_assert_eq!(buf, &bytes[pos..]);
532            }
533
534            let res = cursor.fill_exact(bytes.len());
535            if pos > bytes.len() && !bytes.is_empty() {
536                prop_assert!(matches!(res, Err(ReadError::ReadSizeLimit(x)) if x == bytes.len()));
537            } else {
538                prop_assert_eq!(res.unwrap(), &bytes[pos.min(bytes.len())..]);
539            }
540        }
541
542        #[test]
543        fn cursor_zero_len_ops_ok(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
544            let mut cursor = Cursor::new_at(&bytes, pos);
545            let start = cursor.position();
546
547            // fill_exact(0) is always Ok and does not advance.
548            let fe = cursor.fill_exact(0).unwrap();
549            prop_assert_eq!(fe.len(), 0);
550            prop_assert_eq!(cursor.position(), start);
551
552            // consume(0) is always Ok and does not advance.
553            prop_assert!(cursor.consume(0).is_ok());
554            prop_assert_eq!(cursor.position(), start);
555
556            // as_trusted_for(0) is always Ok and does not advance.
557            let start2 = cursor.position();
558            let mut trusted = unsafe { <Cursor<_> as Reader>::as_trusted_for(&mut cursor, 0) }.unwrap();
559            // Trusted reader on a 0-window should behave like EOF for >0, but allow zero-length reads.
560            prop_assert_eq!(trusted.fill_buf(1).unwrap(), &[]);
561            prop_assert_eq!(trusted.fill_exact(0).unwrap().len(), 0);
562            prop_assert_eq!(cursor.position(), start2);
563        }
564
565        #[test]
566        fn cursor_as_trusted_for_remaining_advances_to_len(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
567            // Clamp pos to be within [0, len] so the request is valid.
568            let len = bytes.len();
569            let pos = if len == 0 { 0 } else { pos % (len + 1) };
570            let mut cursor = Cursor::new_at(&bytes, pos);
571            let remaining = len.saturating_sub(pos);
572
573            let _trusted = unsafe { <Cursor<_> as Reader>::as_trusted_for(&mut cursor, remaining) }.unwrap();
574            // After consuming the exact remaining, position should be exactly len.
575            prop_assert_eq!(cursor.position(), len);
576        }
577
578        #[test]
579        fn cursor_extremal_pos_max_zero_len_ok(bytes in any::<Vec<u8>>()) {
580            let mut cursor = Cursor::new_at(&bytes, usize::MAX);
581            // With extremal position, fill_buf should be empty and peek should error.
582            prop_assert_eq!(cursor.fill_buf(1).unwrap(), &[]);
583            prop_assert!(matches!(cursor.peek(), Err(ReadError::ReadSizeLimit(1))));
584
585            // Zero-length ops still succeed and do not advance.
586            let start = cursor.position();
587            prop_assert!(cursor.fill_exact(0).is_ok());
588            prop_assert!(cursor.consume(0).is_ok());
589            let _trusted = unsafe { <Cursor<_> as Reader>::as_trusted_for(&mut cursor, 0) }.unwrap();
590            prop_assert_eq!(cursor.position(), start);
591        }
592
593        #[test]
594        fn uninit_slice_write_no_panic_no_ub_check(bytes in any::<Vec<u8>>(), pos in any::<usize>()) {
595            let mut output: Vec<u8> = Vec::with_capacity(bytes.len());
596            let mut cursor = Cursor::new_at(output.spare_capacity_mut(), pos);
597            let res = cursor.write(&bytes);
598            if pos > bytes.len() && !bytes.is_empty() {
599                prop_assert!(matches!(res, Err(WriteError::WriteSizeLimit(x)) if x == bytes.len()));
600            } else if pos == 0 {
601                prop_assert_eq!(output, bytes);
602            }
603        }
604
605        #[test]
606        fn vec_write_no_panic_no_ub_check(bytes in any::<Vec<u8>>(), pos in any::<u16>()) {
607            let pos = pos as usize;
608            let mut output: Vec<u8> = Vec::new();
609            let mut cursor = Cursor::new_at(&mut output, pos);
610            // Vec impl grows, so it should be valid to write to any position within memory limits.
611            cursor.write(&bytes).unwrap();
612            prop_assert_eq!(&output[pos..], &bytes);
613        }
614
615        #[test]
616        fn cursor_write_vec_new(bytes in any::<Vec<u8>>()) {
617            let mut cursor = Cursor::new(Vec::new());
618            cursor.write(&bytes).unwrap();
619            prop_assert_eq!(&cursor.inner, &bytes);
620
621            let mut vec = Vec::with_capacity(bytes.len());
622            let mut cursor = Cursor::new(vec.spare_capacity_mut());
623            cursor.write(&bytes).unwrap();
624            unsafe { vec.set_len(bytes.len()) };
625            prop_assert_eq!(&vec, &bytes);
626        }
627
628        #[test]
629        fn cursor_write_existing_vec(bytes in any::<Vec<u8>>()) {
630            let mut cursor = Cursor::new(vec![0; bytes.len()]);
631            cursor.write(&bytes).unwrap();
632            prop_assert_eq!(&cursor.inner, &bytes);
633        }
634
635        #[test]
636        fn cursor_write_existing_grow_vec(bytes in any::<Vec<u8>>()) {
637            let mut cursor = Cursor::new(vec![0; bytes.len() / 2]);
638            cursor.write(&bytes).unwrap();
639            prop_assert_eq!(&cursor.inner, &bytes);
640        }
641
642        #[test]
643        fn cursor_write_partial_vec(bytes in any::<Vec<u8>>()) {
644            let mut cursor = Cursor::new(vec![1; bytes.len()]);
645            let half = bytes.len() - bytes.len() / 2;
646            cursor.write(&bytes[..half]).unwrap();
647            prop_assert_eq!(&cursor.inner[..half], &bytes[..half]);
648            // Remaining bytes are untouched
649            prop_assert_eq!(&cursor.inner[half..], &vec![1; bytes.len() - half]);
650            cursor.write(&bytes[half..]).unwrap();
651            prop_assert_eq!(&cursor.inner, &bytes);
652        }
653
654        #[test]
655        fn cursor_write_trusted_vec(bytes in any::<Vec<u8>>()) {
656            let mut cursor = Cursor::new(vec![1; bytes.len()]);
657            let half = bytes.len() - bytes.len() / 2;
658            cursor.write(&bytes[..half]).unwrap();
659            unsafe { <Cursor<_> as Writer>::as_trusted_for(&mut cursor, bytes.len() - half) }
660                .unwrap()
661                .write(&bytes[half..])
662                .unwrap();
663            cursor.finish().unwrap();
664            prop_assert_eq!(&cursor.inner, &bytes);
665        }
666
667        #[test]
668        fn cursor_write_trusted_grow_vec(bytes in any::<Vec<u8>>()) {
669            let mut cursor = Cursor::new(vec![1; bytes.len() / 2]);
670            let half = bytes.len() - bytes.len() / 2;
671            cursor.write(&bytes[..half]).unwrap();
672            unsafe { <Cursor<_> as Writer>::as_trusted_for(&mut cursor, bytes.len() - half) }
673                .unwrap()
674                .write(&bytes[half..])
675                .unwrap();
676            cursor.finish().unwrap();
677            prop_assert_eq!(&cursor.inner, &bytes);
678        }
679
680        #[test]
681        fn cursor_write_trusted_oversized_vec(bytes in any::<Vec<u8>>()) {
682            let mut cursor = Cursor::new(vec![1; bytes.len() * 2]);
683            let half = bytes.len() - bytes.len() / 2;
684            cursor.write(&bytes[..half]).unwrap();
685            unsafe { <Cursor<_> as Writer>::as_trusted_for(&mut cursor, bytes.len() - half) }
686                .unwrap()
687                .write(&bytes[half..])
688                .unwrap();
689            cursor.finish().unwrap();
690            prop_assert_eq!(&cursor.inner[..bytes.len()], &bytes);
691            // Remaining bytes are untouched
692            prop_assert_eq!(&cursor.inner[bytes.len()..], &vec![1; bytes.len()]);
693        }
694    }
695}