use {super::*, alloc::vec::Vec, slice::SliceMutUnchecked};
impl Writer for Vec<u8> {
#[inline]
fn write(&mut self, src: &[u8]) -> WriteResult<()> {
self.extend_from_slice(src);
Ok(())
}
#[inline]
unsafe fn as_trusted_for(&mut self, n_bytes: usize) -> WriteResult<impl Writer> {
let cur_len = self.len();
self.reserve(n_bytes);
#[allow(clippy::uninit_vec)]
unsafe {
self.set_len(cur_len.unchecked_add(n_bytes))
};
let slice = unsafe {
from_raw_parts_mut(
self.as_mut_ptr().cast::<MaybeUninit<u8>>().add(cur_len),
n_bytes,
)
};
Ok(unsafe { SliceMutUnchecked::new(slice) })
}
}
#[cfg(all(test, feature = "alloc"))]
mod tests {
#![allow(clippy::arithmetic_side_effects)]
use {super::*, crate::proptest_config::proptest_cfg, alloc::vec, proptest::prelude::*};
proptest! {
#![proptest_config(proptest_cfg())]
#[test]
fn vec_writer_write_new(bytes in proptest::collection::vec(any::<u8>(), 0..=100)) {
let mut vec = Vec::new();
vec.write(&bytes).unwrap();
prop_assert_eq!(vec, bytes);
}
#[test]
fn vec_writer_write_existing(bytes in proptest::collection::vec(any::<u8>(), 0..=100)) {
let mut vec = vec![0; 5];
vec.write(&bytes).unwrap();
prop_assert_eq!(&vec[..5], &[0; 5]);
prop_assert_eq!(&vec[5..], bytes);
}
#[test]
fn vec_writer_trusted(bytes in proptest::collection::vec(any::<u8>(), 0..=100)) {
let mut vec = Vec::new();
let half = bytes.len() / 2;
let quarter = half / 2;
vec.write(&bytes[..half]).unwrap();
{
let mut t1 = unsafe { vec.as_trusted_for(bytes.len() - half) }.unwrap();
t1
.write(&bytes[half..half + quarter])
.unwrap();
let mut t2 = unsafe { t1.as_trusted_for(quarter) }.unwrap();
t2.write(&bytes[half + quarter..]).unwrap();
}
prop_assert_eq!(vec, bytes);
}
#[test]
fn vec_writer_trusted_existing(bytes in proptest::collection::vec(any::<u8>(), 0..=100)) {
let mut vec = vec![0; 5];
let half = bytes.len() / 2;
let quarter = half / 2;
vec.write(&bytes[..half]).unwrap();
{
let mut t1 = unsafe { vec.as_trusted_for(bytes.len() - half) }.unwrap();
t1
.write(&bytes[half..half + quarter])
.unwrap();
let mut t2 = unsafe { t1.as_trusted_for(quarter) }.unwrap();
t2.write(&bytes[half + quarter..]).unwrap();
}
prop_assert_eq!(&vec[..5], &[0; 5]);
prop_assert_eq!(&vec[5..], bytes);
}
#[test]
fn test_writer_write_from_t(int in any::<u64>()) {
let mut writer = Vec::new();
unsafe { writer.write_t(&int).unwrap() };
prop_assert_eq!(writer, int.to_le_bytes());
}
#[test]
fn test_writer_write_slice_t(ints in proptest::collection::vec(any::<u64>(), 0..=100)) {
let bytes = ints.iter().flat_map(|int| int.to_le_bytes()).collect::<Vec<u8>>();
let mut writer = Vec::new();
unsafe { writer.write_slice_t(&ints).unwrap() };
prop_assert_eq!(writer, bytes);
}
}
}