typhoon_utility/bytes/
writer.rs1use typhoon_errors::ErrorCode;
2
3pub struct MaybeUninitWriter<'a> {
4 buffer: &'a mut [core::mem::MaybeUninit<u8>],
5 position: usize,
6}
7
8impl<'a> MaybeUninitWriter<'a> {
9 #[inline(always)]
10 pub fn new(buffer: &'a mut [core::mem::MaybeUninit<u8>], position: usize) -> Self {
11 Self { buffer, position }
12 }
13
14 #[inline(always)]
15 pub fn initialized(&self) -> &[u8] {
16 unsafe { core::slice::from_raw_parts(self.buffer.as_ptr() as *const u8, self.position) }
17 }
18
19 #[inline(always)]
20 pub fn write_bytes(&mut self, data: &[u8]) -> Result<usize, ErrorCode> {
21 let available = self.buffer.len().saturating_sub(self.position);
22 let to_write = data.len().min(available);
23
24 if to_write == 0 {
25 return Err(ErrorCode::BufferFull);
26 }
27
28 unsafe {
30 let dst_ptr = self.buffer.as_mut_ptr().add(self.position);
31 core::ptr::copy_nonoverlapping(data.as_ptr(), dst_ptr as _, to_write);
32 }
33
34 self.position += to_write;
35
36 Ok(to_write)
37 }
38}
39
40#[cfg(feature = "borsh")]
41impl borsh::io::Write for MaybeUninitWriter<'_> {
42 fn write(&mut self, data: &[u8]) -> borsh::io::Result<usize> {
43 self.write_bytes(data)
44 .map_err(|_| borsh::io::Error::new(borsh::io::ErrorKind::WriteZero, "Buffer full"))
45 }
46
47 fn flush(&mut self) -> borsh::io::Result<()> {
48 Ok(())
49 }
50}