Skip to main content

git_zero_core/
io.rs

1use crate::{Error, Result};
2
3/// A sink that writes every byte or returns an error. Errors may leave partial output.
4pub trait Write {
5    fn write_all(&mut self, bytes: &[u8]) -> Result<()>;
6}
7
8pub struct SliceWriter<'a> {
9    buffer: &'a mut [u8],
10    length: usize,
11}
12
13impl<'a> SliceWriter<'a> {
14    pub fn new(buffer: &'a mut [u8]) -> Self {
15        Self { buffer, length: 0 }
16    }
17
18    pub fn as_bytes(&self) -> &[u8] {
19        &self.buffer[..self.length]
20    }
21
22    pub fn len(&self) -> usize {
23        self.length
24    }
25
26    pub fn is_empty(&self) -> bool {
27        self.length == 0
28    }
29
30    pub fn finish(self) -> &'a [u8] {
31        &self.buffer[..self.length]
32    }
33}
34
35impl Write for SliceWriter<'_> {
36    fn write_all(&mut self, bytes: &[u8]) -> Result<()> {
37        let end = self
38            .length
39            .checked_add(bytes.len())
40            .ok_or(Error::BufferTooSmall)?;
41        let destination = self
42            .buffer
43            .get_mut(self.length..end)
44            .ok_or(Error::BufferTooSmall)?;
45        destination.copy_from_slice(bytes);
46        self.length = end;
47        Ok(())
48    }
49}
50
51impl core::fmt::Write for SliceWriter<'_> {
52    fn write_str(&mut self, value: &str) -> core::fmt::Result {
53        self.write_all(value.as_bytes())
54            .map_err(|_| core::fmt::Error)
55    }
56}