use crate::{ConstWriterAdapter, ConstWrite, ConstWriterAdapterCreate};
extern crate alloc;
use alloc::vec::Vec;
pub struct VecWriterAdapter<'a> {
vec: &'a mut Vec<u8>,
ptr: *mut u8
}
unsafe impl<'a> ConstWriterAdapterCreate<'a, Vec<u8>> for VecWriterAdapter<'a> {
unsafe fn new<const N: usize>(buff: &'a mut Vec<u8>) -> Self {
buff.reserve(N);
let ptr = core::mem::transmute(buff.as_mut_ptr().add(buff.len()));
Self {
vec: buff,
ptr
}
}
}
impl<'a> ConstWriterAdapter for VecWriterAdapter<'a> {
unsafe fn write<const N: usize>(mut self, value: &[u8; N]) -> Self {
core::ptr::copy_nonoverlapping(value.as_ptr(), self.ptr, N);
self.ptr = self.ptr.add(N);
self
}
unsafe fn grow<const M: usize>(mut self) -> Self {
let written_bytes = self.ptr.offset_from(self.vec.as_ptr()) as usize;
self.vec.reserve(written_bytes + M);
self.ptr = core::mem::transmute::<_, *mut u8>(self.vec.as_mut_ptr()).add(written_bytes);
self
}
}
impl<'a> Drop for VecWriterAdapter<'a> {
fn drop(&mut self) {
unsafe {
let new_len = self.ptr.offset_from(self.vec.as_ptr()) as usize;
self.vec.set_len(new_len);
}
}
}
impl<'a> ConstWrite<'a, VecWriterAdapter<'a>> for Vec<u8> {}
#[cfg(test)]
mod tests {
extern crate test;
use test::Bencher;
use crate::ConstWrite;
extern crate alloc;
use alloc::{vec, vec::Vec};
#[test]
fn vec_write_le() {
let mut vec = vec![];
vec.const_writer::<31>()
.write_u8_le(0x01)
.write_u16_le(0x0203)
.write_u32_le(0x04050607)
.write_u64_le(0x08090A0B0C0D0E0F)
.write_u128_le(0x101112131415161718191A1B1C1D1E1F);
assert_eq!(&vec, &[
0x01,
0x03, 0x02,
0x07, 0x06, 0x05, 0x04,
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
]);
}
#[test]
fn vec_write_be() {
let mut vec = vec![];
vec.const_writer::<31>()
.write_u8_be(0x01)
.write_u16_be(0x0203)
.write_u32_be(0x04050607)
.write_u64_be(0x08090A0B0C0D0E0F)
.write_u128_be(0x101112131415161718191A1B1C1D1E1F);
assert_eq!(&vec, &[
0x01,
0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
]);
}
#[test]
fn vec_write_grow() {
let mut vec = vec![];
vec.const_writer::<5>()
.write_u32_le(123)
.write_u8_le(1)
.convert::<10>()
.write_u32_le(124)
.write_u8_le(24).remaining();
assert_eq!(&vec, &[123, 0, 0, 0, 1, 124, 0, 0, 0, 24]);
}
#[bench]
fn bench_bytes_vec(b: &mut Bencher) {
use bytes::BufMut;
b.iter(|| {
let mut vec = Vec::with_capacity(31);
vec.put_u8(0x01);
vec.put_u16(0x0203);
vec.put_u32(0x04050607);
vec.put_u64(0x08090A0B0C0D0E0F);
vec.put_u128(0x101112131415161718191A1B1C1D1E1F);
assert_eq!(vec.len(), 31);
});
}
#[bench]
fn bench_const_writer_vec(b: &mut Bencher) {
b.iter(|| {
let mut vec = Vec::with_capacity(31);
vec.const_writer::<31>()
.write_u8_be(0x01)
.write_u16_be(0x0203)
.write_u32_be(0x04050607)
.write_u64_be(0x08090A0B0C0D0E0F)
.write_u128_be(0x101112131415161718191A1B1C1D1E1F);
assert_eq!(vec.len(), 31);
});
}
}