1#![no_std]
13#![cfg_attr(not(test), forbid(unsafe_code))]
14#![cfg_attr(docsrs, feature(doc_cfg))]
15
16#[cfg(feature = "std")]
17extern crate std;
18
19#[cfg(all(feature = "alloc",not(feature = "std")))]
20extern crate alloc;
21
22use core::fmt;
23
24mod foreign;
25
26pub type SerResult<T> = Result<T, SerError>;
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
30#[non_exhaustive]
31pub enum SerError {
32 BufferFull,
34}
35
36impl fmt::Display for SerError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 SerError::BufferFull => f.write_str("buffer is full"),
40 }
41 }
42}
43
44impl core::error::Error for SerError {}
45
46pub trait SerWrite {
48 type Error;
50 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
54 #[inline]
58 fn write_byte(&mut self, byte: u8) -> Result<(), Self::Error> {
59 self.write(core::slice::from_ref(&byte))
60 }
61 #[inline]
65 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
66 self.write(s.as_bytes())
67 }
68}
69
70impl<T: SerWrite> SerWrite for &'_ mut T {
71 type Error = T::Error;
72
73 #[inline(always)]
74 fn write(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
75 (*self).write(buf)
76 }
77
78 #[inline(always)]
79 fn write_byte(&mut self, byte: u8) -> Result<(), Self::Error> {
80 (*self).write_byte(byte)
81 }
82
83 #[inline(always)]
84 fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
85 (*self).write_str(s)
86 }
87}
88
89#[derive(Debug, PartialEq)]
91pub struct SliceWriter<'a> {
92 pub buf: &'a mut [u8],
93 pub len: usize
94}
95
96impl<'a> AsRef<[u8]> for SliceWriter<'a> {
97 fn as_ref(&self) -> &[u8] {
99 &self.buf[..self.len]
100 }
101}
102
103impl<'a> AsMut<[u8]> for SliceWriter<'a> {
104 fn as_mut(&mut self) -> &mut [u8] {
106 &mut self.buf[..self.len]
107 }
108}
109
110impl<'a> SliceWriter<'a> {
111 pub fn new(buf: &'a mut [u8]) -> Self {
113 SliceWriter { buf, len: 0 }
114 }
115 pub fn len(&self) -> usize {
117 self.len
118 }
119 pub fn is_empty(&self) -> bool {
121 self.len == 0
122 }
123 pub fn capacity(&self) -> usize {
125 self.buf.len()
126 }
127 pub fn rem_capacity(&self) -> usize {
129 self.buf.len() - self.len
130 }
131 pub fn clear(&mut self) {
133 self.len = 0;
134 }
135 pub fn split(self) -> (&'a mut[u8], Self) {
141 let (res, buf) = self.buf.split_at_mut(self.len);
142 (res, Self { buf, len: 0 })
143 }
144}
145
146impl SerWrite for SliceWriter<'_> {
147 type Error = SerError;
148
149 fn write(&mut self, buf: &[u8]) -> SerResult<()> {
150 let end = self.len + buf.len();
151 match self.buf.get_mut(self.len..end) {
152 Some(chunk) => {
153 chunk.copy_from_slice(buf);
154 self.len = end;
155 Ok(())
156 }
157 None => Err(SerError::BufferFull)
158 }
159 }
160}
161
162impl<'a> fmt::Write for SliceWriter<'a> {
163 fn write_str(&mut self, s: &str) -> fmt::Result {
164 SerWrite::write_str(self, s).map_err(|_| fmt::Error)
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use core::fmt::Write;
171 use super::*;
172
173 #[test]
174 fn test_ser_error() {
175 #[cfg(feature = "std")]
176 {
177 assert_eq!(std::format!("{}", SerError::BufferFull), "buffer is full");
178 }
179 let mut buf = [0u8;0];
180 let mut writer = SliceWriter::new(&mut buf);
181 assert_eq!(write!(writer, "!"), Err(fmt::Error));
182 }
183
184 #[test]
185 fn test_slice_writer() {
186 let mut buf = [0u8;22];
187 let mut writer = SliceWriter::new(&mut buf);
188 assert_eq!(writer.capacity(), 22);
189 assert_eq!(writer.rem_capacity(), 22);
190 assert_eq!(writer.len(), 0);
191 assert_eq!(writer.is_empty(), true);
192 writer.write(b"Hello World!").unwrap();
193 assert_eq!(writer.rem_capacity(), 10);
194 assert_eq!(writer.len(), 12);
195 assert_eq!(writer.is_empty(), false);
196 writer.write_byte(b' ').unwrap();
197 assert_eq!(writer.rem_capacity(), 9);
198 assert_eq!(writer.len(), 13);
199 assert_eq!(writer.is_empty(), false);
200 SerWrite::write_str(&mut writer, "Good Bye!").unwrap();
201 let expected = b"Hello World! Good Bye!";
202 assert_eq!(writer.as_ref(), expected);
203 assert_eq!(writer.as_mut(), expected);
204 assert_eq!(writer.capacity(), 22);
205 assert_eq!(writer.rem_capacity(), 0);
206 assert_eq!(writer.is_empty(), false);
207 assert_eq!(writer.len(), 22);
208 let (head, mut writer) = writer.split();
209 assert_eq!(head, expected);
210 assert_eq!(writer.write_byte(b' ').unwrap_err(), SerError::BufferFull);
211 }
212}