embytes_buffer/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3use thiserror::Error;
4
5mod write;
6pub use write::*;
7
8
9mod read;
10pub use read::*;
11
12#[cfg(feature = "serde")]
13pub mod json;
14
15
16
17/// Error enum 
18#[derive(Error, Debug, PartialEq)]
19#[cfg_attr(feature = "defmt", derive(defmt::Format))]
20pub enum BufferError {
21
22    #[error("Error writing to buffer: no remaining capacity")]
23    NoCapacity,
24
25    #[error("The provided slice to read from or write to has a len = 0")]
26    ProvidedSliceEmpty,
27
28    #[error("Error reading from buffer: no remaining data")]
29    NoData,
30
31    #[cfg(feature = "serde")]
32    #[error("Error while deserializing JSON")]
33    JsonDeserialize(serde_json_core::de::Error)
34}
35
36///
37/// Trait that allows to create a reader and a writer for a buffer.
38/// See [`BufferReader`] adn [`BufferWriter`]
39///
40pub trait ReadWrite {
41    fn create_reader<'a>(&'a mut self) -> impl BufferReader + 'a;
42    fn create_writer<'a>(&'a mut self) -> impl BufferWriter + 'a;
43}
44
45
46#[derive(Debug)]
47pub struct Buffer<T: AsMut<[u8]> + AsRef<[u8]>> {
48    pub(crate) source: T,
49    pub(crate) write_position: usize,
50    pub(crate) read_position: usize,
51}
52
53/// Creates a new [`Buffer`] that is backed by an owned [`u8`] array with size `N`
54pub fn new_stack_buffer<const N: usize>() -> Buffer<[u8; N]> {
55    Buffer::<[u8; N]> {
56        source: [0; N],
57        read_position: 0,
58        write_position: 0,
59    }
60}
61
62#[cfg(feature = "defmt")]
63impl <T: AsMut<[u8]> + AsRef<[u8]>> defmt::Format for Buffer<T> {
64    fn format(&self, fmt: defmt::Formatter) {
65        defmt::write!(fmt, 
66            "Buffer(len = {}, cap = {}, rem_cap = {})",
67            self.remaining_len(),
68            self.capacity(),
69            self.remaining_capacity()
70        );
71    }
72}
73
74impl <T: AsMut<[u8]> + AsRef<[u8]>> Buffer<T> {
75
76    /// Create a new buffer from any source 
77    /// 
78    /// # Example
79    /// 
80    /// ```rust
81    ///     use buffer::Buffer;
82    /// 
83    ///     let mut bytes = [0; 1024];
84    ///     let mut buffer = Buffer::new(&mut bytes);
85    /// ```
86    pub fn new(source: T) -> Self {
87        Self {
88            source,
89            read_position: 0,
90            write_position: 0,
91        }
92    }
93
94    /// Reset the buffer to its initial state
95    pub fn reset(&mut self) {
96        self.read_position = 0;
97        self.write_position = 0;
98    }
99
100    /// Returns the length of the undelying buffer
101    pub fn capacity(&self) -> usize {
102        self.source.as_ref().len()
103    }
104
105    /// Returns the remaining space that can be written
106    /// This method does not perform a [`Buffer::shift`]
107    pub fn remaining_capacity(&self) -> usize {
108        self.capacity() - self.write_position
109    }
110
111    /// returns if there is remaining 
112    /// is equal to `Buffer::remaining_capacity() > 0`
113    pub fn has_remaining_capacity(&self) -> bool {
114        self.capacity() > self.write_position
115    }
116
117    /// Returns the remaining bayes to read
118    pub fn remaining_len(&self) -> usize {
119        self.write_position - self.read_position
120    }
121
122    pub fn has_remaining_len(&self) -> bool {
123        self.write_position > self.read_position
124    }
125
126    /// Returns true if the read position is > 0
127    pub fn has_dead_capacity(&self) -> bool {
128        self.read_position > 0
129    }
130
131    /// Shifts the content of the source left to reuse space of read bytes.
132    pub fn shift(&mut self) {
133        self.source.as_mut().rotate_left(self.read_position);
134        self.write_position -= self.read_position;
135        self.read_position = 0;
136    }
137
138    /// Performa s [`Buffer::shift`] if there is no remianing capacity and 
139    /// returns if there is remainig capacity afterwards
140    pub fn ensure_remaining_capacity(&mut self) -> bool {
141        if ! self.has_remaining_capacity() {
142            self.shift();
143        }
144
145        self.has_remaining_capacity()
146    }
147
148    /// Base function for implementing writers like [`embedded_io::Write`]
149    /// Returns the number of bytes writen to the buffer from the provided slice
150    /// 
151    /// # Errors
152    /// 
153    /// [`BufferError::ProvidedSliceEmpty`] if the provided slice is empty
154    /// [`BufferError::NoCapacity`] if the buffer has no capacity after calling [`Buffer::shift`]
155    pub(crate) fn write_base(&mut self, buf: &[u8]) -> Result<usize, BufferError> {
156        if buf.is_empty() {
157            return Err(BufferError::ProvidedSliceEmpty);
158        }
159
160        if ! self.has_remaining_capacity() && self.has_dead_capacity() {
161            self.shift();
162        }
163        
164        let cap = self.remaining_capacity();
165        if cap == 0 {
166            return Err(BufferError::NoCapacity);
167        }
168
169        let tgt = self.source.as_mut();
170        let tgt = &mut tgt[self.write_position..];
171        
172        if cap < buf.len() {
173            tgt.copy_from_slice(&buf[0..cap]);
174            self.write_position += cap;
175            Ok(cap)
176        } else {
177            let tgt = &mut tgt[0..buf.len()];
178            tgt.copy_from_slice(buf);
179            self.write_position += buf.len();
180            Ok(buf.len())
181        }
182    }
183
184    /// Base function for implementing readers like [`embedded_io::Read`]
185    /// Returns the number of bytes read from the buffer to the provided slice
186    /// 
187    /// # Errors
188    /// 
189    /// [`BufferError::ProvidedSliceEmpty`] if the provided slice is empty
190    /// [`BufferError::NoData`] if there ae no bytes to read
191    pub(crate) fn read_base(&mut self, buf: &mut[u8]) -> Result<usize, BufferError> {
192        if buf.is_empty() {
193            return Err(BufferError::ProvidedSliceEmpty);
194        }
195
196        let src = self.source.as_ref();
197        let src = &src[self.read_position..self.write_position];
198
199        if src.is_empty() {
200            return Err(BufferError::NoData);
201        }
202        else if src.len() > buf.len() {
203            buf.copy_from_slice(&src[0..buf.len()]);
204            self.read_position += buf.len();
205            Ok(buf.len())
206        } else {
207            let buf = &mut buf[0..src.len()];
208            buf.copy_from_slice(src);
209            self.read_position += src.len();
210
211            Ok(src.len())
212        }
213    }
214
215    pub fn create_reader_with_max(&mut self, max_bytes: usize) -> Reader<'_, T> {
216        Reader::new_with_max(self, max_bytes)
217    }
218
219    /// Returns a slice containing the readable data
220    pub fn data(&self) -> &[u8] {
221        let src = self.source.as_ref();
222        &src[self.read_position..self.write_position]
223    }
224
225    /// Skips `n` readable bytes
226    /// 
227    /// # Errors
228    /// 
229    /// [`BufferError::NoData`] if n < self.remaining_len()
230    pub fn skip(&mut self, n: usize) -> Result<(), BufferError> {
231        if self.remaining_len() >= n {
232            self.read_position += n;
233            Ok(())
234        } else {
235            Err(BufferError::NoData)
236        }
237    }
238
239    /// Appends the provided slice to the buffer a a whole
240    /// 
241    /// # Error
242    /// 
243    /// [`BufferError::NoCapacity`] if `buf.len() > self.remaining_capacity()`
244    pub fn push(&mut self, buf: &[u8]) -> Result<(), BufferError> {
245        if self.remaining_capacity() < buf.len() && self.has_dead_capacity() {
246            self.shift();
247        }
248        
249        if self.remaining_capacity() >= buf.len() {
250            let tgt = self.source.as_mut();
251            let tgt = &mut tgt[self.write_position..];
252            let tgt = &mut tgt[0..buf.len()];
253            tgt.copy_from_slice(buf);
254            self.write_position += buf.len();
255            Ok(())
256        } else {
257            Err(BufferError::NoCapacity)
258        }
259    }
260
261}
262
263impl <T: AsMut<[u8]> + AsRef<[u8]>> ReadWrite for Buffer<T> {
264    fn create_reader<'a>(&'a mut self) -> impl BufferReader + 'a {
265        Reader::new(self)
266    }
267
268    fn create_writer<'a>(&'a mut self) -> impl BufferWriter + 'a {
269        self.shift();
270        Write::new(self)
271
272    }
273}
274
275#[cfg(feature = "std")]
276impl <T: AsMut<[u8]> + AsRef<[u8]>> std::io::Write for Buffer<T> {
277
278    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
279        use std::io::ErrorKind;
280        match self.write_base(buf) {
281            Ok(n) => Ok(n),
282            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
283            Err(BufferError::NoCapacity) => Err(ErrorKind::WouldBlock.into()),
284            Err(e) => {
285                panic!("unexpected error writing to buffer: {}", e);
286            }
287        }
288    }
289
290    fn flush(&mut self) -> std::io::Result<()> {
291        Ok(())
292    }
293}
294
295#[cfg(feature = "std")]
296impl <T: AsMut<[u8]> + AsRef<[u8]>> std::io::Read for Buffer<T> {
297    
298    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
299        use std::io::ErrorKind;
300
301        match self.read_base(buf) {
302            Ok(n) => Ok(n),
303            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
304            Err(BufferError::NoData) => Err(ErrorKind::WouldBlock.into()),
305            Err(e) => {
306                panic!("unexpected error reading from buffer: {}", e);
307            }
308        }
309    }
310}
311
312#[cfg(feature = "embedded")]
313impl <T: AsMut<[u8]> + AsRef<[u8]>> embedded_io::ErrorType for Buffer<T> {
314    type Error = embedded_io::ErrorKind;
315}
316
317#[cfg(feature = "embedded")]
318impl <T: AsMut<[u8]> + AsRef<[u8]>> embedded_io::Write for Buffer<T> {
319    
320    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
321        use embedded_io::ErrorKind;
322
323        match self.write_base(buf) {
324            Ok(n) => Ok(n),
325            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
326            Err(BufferError::NoCapacity) => Err(ErrorKind::Other),
327            Err(e) => {
328                panic!("unexpected error writing to buffer: {}", e);
329            }
330        }
331    }
332
333    fn flush(&mut self) -> Result<(), Self::Error> {
334        Ok(())
335    }
336}
337
338#[cfg(feature = "embedded")]
339impl <T: AsMut<[u8]> + AsRef<[u8]>> embedded_io::Read for Buffer<T> {
340    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
341        use embedded_io::ErrorKind;
342
343        match self.read_base(buf) {
344            Ok(n) => Ok(n),
345            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
346            Err(BufferError::NoData) => Err(ErrorKind::Other),
347            Err(e) => {
348                panic!("unexpected error reading from buffer: {}", e);
349            }
350        }
351    }
352}
353
354// Old clone impl, throw awai if workspace compiles without error
355/* 
356impl <const N: usize> Clone for Buffer<[u8; N]> {
357    fn clone(&self) -> Self {
358        Self { 
359            source: self.source.clone(), 
360            write_position: self.write_position.clone(), 
361            read_position: self.read_position.clone() 
362        }
363    }
364}
365*/
366
367impl <T: AsMut<[u8]> + AsRef<[u8]> + Clone> Clone for Buffer<T> {
368    fn clone(&self) -> Self {
369        Self { 
370            source: self.source.clone(), 
371            write_position: self.write_position, 
372            read_position: self.read_position
373        }
374    }
375}
376
377#[cfg(test)]
378mod tests {
379
380    use crate::{new_stack_buffer, Buffer, BufferError};
381
382    #[test]
383    fn test_std_write_high_cap() {
384        let mut b = [0u8; 8];
385        let mut buf = Buffer::new(&mut b);
386
387        let n = buf.write_base(&[3, 4, 5]).unwrap();
388        assert_eq!(n, 3);
389
390        assert_eq!(buf.read_position, 0);
391        assert_eq!(buf.write_position, 3);
392        drop(buf);
393
394        assert_eq!(&b, &[3, 4, 5, 0, 0, 0, 0, 0])
395    }
396
397    #[test]
398    fn test_std_write_low_cap() {
399        let mut b = [0u8; 4];
400        let mut buf = Buffer::new(&mut b);
401
402        let n = buf.write_base(&[1, 2, 3, 4, 5, 6]).unwrap();
403
404        assert_eq!(n, 4);
405
406        assert_eq!(buf.read_position, 0);
407        assert_eq!(buf.write_position, 4);
408        drop(buf);
409
410        assert_eq!(&b, &[1, 2, 3, 4])
411    }
412
413    #[test]
414    fn test_shift() {
415        let mut b = [0, 1, 2, 3, 4, 5, 6, 7];
416        let mut buf = Buffer::new(&mut b);
417        buf.read_position = 4;
418        buf.write_position = 8;
419
420        buf.shift();
421
422        assert_eq!(buf.read_position, 0);
423        assert_eq!(buf.write_position, 4);
424
425        drop(buf);
426        assert_eq!(&b[0..4], &[4, 5, 6, 7]);
427    }
428
429    #[test]
430    fn test_write_dead_cap() {
431        let mut b = [0u8; 8];
432        let mut buf = Buffer::new(&mut b);
433
434        // Write the buffer full
435        let n = buf.write_base(&[1, 2, 3, 4, 5, 6, 7, 8]).unwrap();
436        assert_eq!(n, 8);
437
438        // Read half
439        let mut tgt = [0u8; 4];
440        let n = buf.read_base(&mut tgt[..]).unwrap();
441        assert_eq!(n, 4);
442        assert_eq!(&tgt, &[1, 2, 3, 4]);
443        assert_eq!(buf.read_position, 4);
444        assert_eq!(buf.write_position, 8);
445
446        // Now 4 Bytes write should be ok
447        let n = buf.write_base(&[10, 20, 30, 40]).unwrap();
448        assert_eq!(n, 4);
449        assert_eq!(buf.read_position, 0);
450        assert_eq!(buf.write_position, 8);
451
452        drop(buf);
453        assert_eq!(&b, &[5, 6, 7, 8, 10, 20, 30, 40]);
454
455    }
456
457    #[test]
458    fn test_multi_write() {
459
460        let mut b = [0u8; 4];
461        let mut buf = Buffer::new(&mut b);
462
463        buf.write_base(&[0]).unwrap();
464        buf.write_base(&[1]).unwrap();
465        buf.write_base(&[2]).unwrap();
466        buf.write_base(&[3]).unwrap();
467
468        drop(buf);
469        assert_eq!(&b, &[0, 1, 2, 3]);
470    }
471
472    #[test]
473    fn test_stack_buffer() {
474
475        let mut buf = new_stack_buffer::<4>();
476
477        buf.write_base(&[1, 2, 3, 4]).unwrap();
478
479    }
480
481    #[test]
482    fn test_skip_success() {
483
484        let mut b = [0u8; 4];
485        let mut buf = Buffer::new(&mut b);
486
487        buf.write_base(&[4, 4, 4, 4]).unwrap();
488        assert_eq!(buf.read_position, 0);
489        assert_eq!(buf.write_position, 4);
490
491        buf.skip(2).unwrap();
492        assert_eq!(buf.read_position, 2);
493        assert_eq!(buf.write_position, 4);
494    }
495
496    #[test]
497    fn test_skip_fail() {
498
499        let mut b = [0u8; 8];
500        let mut buf = Buffer::new(&mut b);
501
502        buf.write_base(&[4, 4, 4, 4]).unwrap();
503        assert_eq!(buf.read_position, 0);
504        assert_eq!(buf.write_position, 4);
505
506        let res = buf.skip(5);
507        assert_eq!(res, Err(BufferError::NoData));
508    }
509}