sml_rs/
util.rs

1//! utility stuff
2
3use core::{borrow::Borrow, fmt::Debug, ops::Deref};
4
5pub(crate) static CRC_X25: crc::Crc<u16> = crc::Crc::<u16>::new(&crc::CRC_16_IBM_SDLC);
6
7pub(crate) mod private {
8    pub trait Sealed {}
9}
10
11// ===========================================================================
12// ===========================================================================
13//      `Buffer` trait + impls for `VecBuf` and `ArrayBuf`
14// ===========================================================================
15// ===========================================================================
16
17/// Interface for byte vectors.
18///
19/// This train provides is used as an abstraction over different byte vector
20/// implementations. It is implemented for static vectors (`ArrayBuf`)
21/// and (if the `alloc` feature is used) for dynamic vectors (`alloc::Vec<u8>`).
22pub trait Buffer: Default + Deref<Target = [u8]> + private::Sealed {
23    /// Appends a byte to the back of the vector.
24    ///
25    /// Returns `Err` if the vector is full and could not be extended.
26    fn push(&mut self, b: u8) -> Result<(), OutOfMemory>;
27
28    /// Shortens the vector, keeping the first len elements and dropping the rest.
29    fn truncate(&mut self, len: usize);
30
31    /// Clears the vector, removing all values.
32    fn clear(&mut self);
33
34    /// Clones and appends all bytes in a slice to the vector.
35    ///
36    /// Iterates over the slice `other` and appends each byte to this vector. The `other` vector is traversed in-order.
37    fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), OutOfMemory>;
38}
39
40/// Type alias for `alloc::Vec<u8>`
41#[cfg(feature = "alloc")]
42pub type VecBuf = alloc::vec::Vec<u8>;
43
44#[cfg(feature = "alloc")]
45impl Buffer for VecBuf {
46    fn push(&mut self, b: u8) -> Result<(), OutOfMemory> {
47        match self.try_reserve(1) {
48            Ok(()) => {
49                VecBuf::push(self, b);
50                Ok(())
51            }
52            Err(_) => Err(OutOfMemory),
53        }
54    }
55
56    fn truncate(&mut self, len: usize) {
57        VecBuf::truncate(self, len);
58    }
59
60    fn clear(&mut self) {
61        VecBuf::clear(self);
62    }
63
64    fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), OutOfMemory> {
65        match self.try_reserve(other.len()) {
66            Ok(()) => {
67                VecBuf::extend_from_slice(self, other);
68                Ok(())
69            }
70            Err(_) => Err(OutOfMemory),
71        }
72    }
73}
74
75#[cfg(feature = "alloc")]
76impl private::Sealed for VecBuf {}
77
78/// Byte buffer backed by an array.
79pub struct ArrayBuf<const N: usize> {
80    buffer: [u8; N],
81    num_elements: usize,
82}
83
84impl<const N: usize> Default for ArrayBuf<N> {
85    fn default() -> Self {
86        Self {
87            buffer: [0; N],
88            num_elements: 0,
89        }
90    }
91}
92
93impl<const N: usize> Debug for ArrayBuf<N> {
94    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95        (**self).fmt(f)
96    }
97}
98
99impl<const N: usize> PartialEq for ArrayBuf<N> {
100    fn eq(&self, other: &Self) -> bool {
101        **self == **other
102    }
103}
104
105impl<const N: usize> Deref for ArrayBuf<N> {
106    type Target = [u8];
107
108    fn deref(&self) -> &Self::Target {
109        &self.buffer[0..self.num_elements]
110    }
111}
112
113impl<const N: usize> FromIterator<u8> for ArrayBuf<N> {
114    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
115        let mut buf = ArrayBuf::default();
116        for x in iter.into_iter() {
117            buf.push(x).unwrap();
118        }
119        buf
120    }
121}
122
123impl<const N: usize> Buffer for ArrayBuf<N> {
124    fn push(&mut self, b: u8) -> Result<(), OutOfMemory> {
125        if self.num_elements == N {
126            Err(OutOfMemory)
127        } else {
128            self.buffer[self.num_elements] = b;
129            self.num_elements += 1;
130            Ok(())
131        }
132    }
133
134    fn truncate(&mut self, len: usize) {
135        self.num_elements = self.num_elements.min(len);
136    }
137
138    fn clear(&mut self) {
139        self.num_elements = 0;
140    }
141
142    fn extend_from_slice(&mut self, other: &[u8]) -> Result<(), OutOfMemory> {
143        if self.num_elements + other.len() > N {
144            return Err(OutOfMemory);
145        }
146        self.buffer[self.num_elements..][..other.len()].copy_from_slice(other);
147        self.num_elements += other.len();
148        Ok(())
149    }
150}
151
152impl<const N: usize> private::Sealed for ArrayBuf<N> {}
153
154/// Error type indicating that an operation failed due to lack of memory.
155#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
156pub struct OutOfMemory;
157
158// ===========================================================================
159// ===========================================================================
160//      `ByteSource` trait + impls
161// ===========================================================================
162// ===========================================================================
163
164/// Helper trait that allows reading individual bytes
165pub trait ByteSource: private::Sealed {
166    /// Type of errors that can occur while reading bytes
167    type ReadError: ByteSourceErr;
168
169    /// Tries to read a single byte from the source
170    fn read_byte(&mut self) -> Result<u8, Self::ReadError>;
171}
172
173/// Helper trait implemented for Error types of `ByteSource`
174pub trait ByteSourceErr: private::Sealed {
175    /// Returns whether the error is an end of file (EOF) error
176    fn is_eof(&self) -> bool;
177
178    /// Returns whether the error is "would block", which means that reading
179    /// can be successfull again later
180    fn is_would_block(&self) -> bool;
181}
182
183/// Wraps types that implement `std::io::Read` and implements `ByteSource`
184#[cfg(feature = "std")]
185pub struct IoReader<R>
186where
187    R: std::io::Read,
188{
189    inner: R,
190}
191
192#[cfg(feature = "std")]
193impl<R> IoReader<R>
194where
195    R: std::io::Read,
196{
197    pub(crate) fn new(reader: R) -> Self {
198        IoReader { inner: reader }
199    }
200}
201
202#[cfg(feature = "std")]
203impl<R> ByteSource for IoReader<R>
204where
205    R: std::io::Read,
206{
207    type ReadError = std::io::Error;
208
209    fn read_byte(&mut self) -> Result<u8, Self::ReadError> {
210        let mut b = 0u8;
211        self.inner.read_exact(core::slice::from_mut(&mut b))?;
212        Ok(b)
213    }
214}
215
216#[cfg(feature = "std")]
217impl<R> private::Sealed for IoReader<R> where R: std::io::Read {}
218
219#[cfg(feature = "std")]
220impl ByteSourceErr for std::io::Error {
221    fn is_eof(&self) -> bool {
222        matches!(self.kind(), std::io::ErrorKind::UnexpectedEof)
223    }
224
225    fn is_would_block(&self) -> bool {
226        false
227    }
228}
229
230#[cfg(feature = "std")]
231impl private::Sealed for std::io::Error {}
232
233/// Wraps types that implement `embedded_hal::serial::Read<...>` and implements `ByteSource`
234#[cfg(feature = "embedded_hal")]
235pub struct EhReader<R, E>
236where
237    R: embedded_hal::serial::Read<u8, Error = E>,
238{
239    inner: R,
240}
241
242#[cfg(feature = "embedded_hal")]
243impl<R, E> EhReader<R, E>
244where
245    R: embedded_hal::serial::Read<u8, Error = E>,
246{
247    pub(crate) fn new(reader: R) -> Self {
248        EhReader { inner: reader }
249    }
250}
251
252#[cfg(feature = "embedded_hal")]
253impl<R, E> ByteSource for EhReader<R, E>
254where
255    R: embedded_hal::serial::Read<u8, Error = E>,
256{
257    type ReadError = nb::Error<E>;
258
259    fn read_byte(&mut self) -> Result<u8, Self::ReadError> {
260        self.inner.read()
261    }
262}
263
264#[cfg(feature = "embedded_hal")]
265impl<R, E> private::Sealed for EhReader<R, E> where R: embedded_hal::serial::Read<u8, Error = E> {}
266
267#[cfg(feature = "embedded_hal")]
268impl<E> ByteSourceErr for nb::Error<E> {
269    fn is_eof(&self) -> bool {
270        false
271    }
272
273    fn is_would_block(&self) -> bool {
274        matches!(self, nb::Error::WouldBlock)
275    }
276}
277
278#[cfg(feature = "embedded_hal")]
279impl<E> private::Sealed for nb::Error<E> {}
280
281/// Error type indicating that the end of the input has been reached
282#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
283pub struct Eof;
284
285impl ByteSourceErr for Eof {
286    fn is_eof(&self) -> bool {
287        true
288    }
289
290    fn is_would_block(&self) -> bool {
291        false
292    }
293}
294
295impl private::Sealed for Eof {}
296
297/// Wraps byte slices and implements `ByteSource`
298pub struct SliceReader<'i> {
299    inner: &'i [u8],
300    idx: usize,
301}
302
303impl<'i> SliceReader<'i> {
304    pub(crate) fn new(slice: &'i [u8]) -> Self {
305        SliceReader {
306            inner: slice,
307            idx: 0,
308        }
309    }
310}
311
312impl<'i> ByteSource for SliceReader<'i> {
313    type ReadError = Eof;
314
315    fn read_byte(&mut self) -> Result<u8, Self::ReadError> {
316        if self.idx >= self.inner.len() {
317            return Err(Eof);
318        }
319        let b = self.inner[self.idx];
320        self.idx += 1;
321        Ok(b)
322    }
323}
324
325impl<'i> private::Sealed for SliceReader<'i> {}
326
327/// Wraps byte iterators and implements `ByteSource`
328pub struct IterReader<I, B>
329where
330    I: Iterator<Item = B>,
331    B: Borrow<u8>,
332{
333    iter: I,
334}
335
336impl<I, B> IterReader<I, B>
337where
338    I: Iterator<Item = B>,
339    B: Borrow<u8>,
340{
341    pub(crate) fn new(iter: I) -> Self {
342        IterReader { iter }
343    }
344}
345
346impl<I, B> ByteSource for IterReader<I, B>
347where
348    I: Iterator<Item = B>,
349    B: Borrow<u8>,
350{
351    type ReadError = Eof;
352
353    fn read_byte(&mut self) -> Result<u8, Self::ReadError> {
354        match self.iter.next() {
355            Some(x) => Ok(*x.borrow()),
356            None => Err(Eof),
357        }
358    }
359}
360
361impl<I, B> private::Sealed for IterReader<I, B>
362where
363    I: Iterator<Item = B>,
364    B: Borrow<u8>,
365{
366}
367
368// ===========================================================================
369// ===========================================================================
370//      Tests
371// ===========================================================================
372// ===========================================================================
373
374#[cfg(test)]
375mod test_arraybuf {
376    use crate::util::{Buffer, OutOfMemory};
377
378    use super::ArrayBuf;
379
380    #[test]
381    fn test_basic() {
382        let mut buf: ArrayBuf<5> = (0..3).collect();
383        assert_eq!(buf.len(), 3);
384        assert_eq!(buf.push(10), Ok(()));
385        assert_eq!(buf.len(), 4);
386        assert_eq!(buf.push(20), Ok(()));
387        assert_eq!(buf.len(), 5);
388        assert_eq!(buf.push(30), Err(OutOfMemory));
389        assert_eq!(buf.len(), 5);
390        assert_eq!(&*buf, &[0, 1, 2, 10, 20]);
391        buf.truncate(1000);
392        assert_eq!(&*buf, &[0, 1, 2, 10, 20]);
393        buf.truncate(1);
394        assert_eq!(&*buf, &[0]);
395        buf.truncate(0);
396        assert_eq!(&*buf, &[]);
397        assert_eq!(buf.extend_from_slice(&[7, 6, 5, 4, 3]), Ok(()));
398        assert_eq!(&*buf, &[7, 6, 5, 4, 3]);
399        buf.truncate(1);
400        assert_eq!(&*buf, &[7]);
401        assert_eq!(buf.extend_from_slice(&[10, 11]), Ok(()));
402        assert_eq!(&*buf, &[7, 10, 11]);
403        assert_eq!(buf.extend_from_slice(&[25, 26, 27]), Err(OutOfMemory));
404        buf.clear();
405        assert_eq!(&*buf, &[]);
406    }
407
408    #[cfg(feature = "alloc")]
409    #[test]
410    fn test_debug() {
411        use alloc::format;
412        let mut buf: ArrayBuf<5> = (10..13).collect();
413        assert_eq!(&format!("{:?}", buf), "[10, 11, 12]");
414        assert_eq!(&format!("{:x?}", buf), "[a, b, c]");
415        buf.clear();
416        assert_eq!(&format!("{:?}", buf), "[]");
417    }
418
419    #[test]
420    fn test_from_iter() {
421        let buf: ArrayBuf<5> = (0..3).collect();
422        assert_eq!(&*buf, &[0, 1, 2]);
423        let buf: ArrayBuf<3> = (0..3).collect();
424        assert_eq!(&*buf, &[0, 1, 2]);
425    }
426
427    #[test]
428    #[should_panic]
429    fn test_from_panic() {
430        let _: ArrayBuf<2> = (0..3).collect();
431    }
432
433    #[test]
434    fn test_eq() {
435        let mut buf_a: ArrayBuf<5> = (0..3).collect();
436        let mut buf_b: ArrayBuf<5> = (0..3).collect();
437        assert_eq!(buf_a, buf_b);
438        buf_b.push(123).unwrap();
439        assert_ne!(buf_a, buf_b);
440        buf_b.push(199).unwrap();
441        assert_ne!(buf_a, buf_b);
442        buf_a.truncate(3);
443        buf_b.truncate(3);
444        assert_eq!(buf_a, buf_b);
445        buf_a.clear();
446        assert_ne!(buf_a, buf_b);
447        buf_b.clear();
448        assert_eq!(buf_a, buf_b);
449    }
450
451    #[test]
452    fn test_n0() {
453        let mut buf = ArrayBuf::<0>::default();
454        assert_eq!(buf.len(), 0);
455        assert_eq!(buf.push(30), Err(OutOfMemory));
456    }
457}