messagepack_core/
io.rs

1//! Minimal write abstraction used by encoders.
2
3/// Minimal `Write`‑like trait used by encoders to avoid committing to a
4/// specific I/O model.
5pub trait IoWrite {
6    /// Error type produced by the writer.
7    type Error: core::error::Error;
8    /// Write all bytes from `buf`.
9    fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
10}
11
12/// `SliceWriter` Error
13#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
14pub enum WError {
15    /// buffer is full
16    BufferFull,
17}
18
19impl core::fmt::Display for WError {
20    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
21        match self {
22            WError::BufferFull => write!(f, "Buffer is full"),
23        }
24    }
25}
26
27impl core::error::Error for WError {}
28
29/// Simple writer that writes into a mutable byte slice.
30pub struct SliceWriter<'a> {
31    buf: &'a mut [u8],
32    cursor: usize,
33}
34
35impl<'a> SliceWriter<'a> {
36    /// Create a new writer over the given buffer.
37    pub fn from_slice(buf: &'a mut [u8]) -> Self {
38        Self { buf, cursor: 0 }
39    }
40
41    fn len(&self) -> usize {
42        self.buf.len() - self.cursor
43    }
44}
45
46impl IoWrite for SliceWriter<'_> {
47    type Error = WError;
48
49    fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
50        if self.len() >= buf.len() {
51            let to = &mut self.buf[self.cursor..self.cursor + buf.len()];
52            to.copy_from_slice(buf);
53            self.cursor += buf.len();
54            Ok(())
55        } else {
56            Err(WError::BufferFull)
57        }
58    }
59}
60
61#[cfg(any(test, feature = "std"))]
62impl<W> IoWrite for W
63where
64    W: std::io::Write,
65{
66    type Error = std::io::Error;
67
68    fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
69        self.write_all(buf)
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    #[should_panic]
79    fn buffer_full() {
80        let buf: &mut [u8] = &mut [0u8];
81        let mut writer = SliceWriter::from_slice(buf);
82        writer.write(&[1, 2]).unwrap();
83    }
84}