1pub trait IoWrite {
6 type Error: core::error::Error;
8 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
10}
11
12#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
14pub enum WError {
15 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
29pub struct SliceWriter<'a> {
31 buf: &'a mut [u8],
32 cursor: usize,
33}
34
35impl<'a> SliceWriter<'a> {
36 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}