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    /// This error is returned if there is not enaugh remaining space
23    #[error("Error writing to buffer: no remaining capacity")]
24    NoCapacity,
25
26    /// A provided slice wa empty
27    /// Is used for trait implementations like [`embedded_io::Read`], [`embedded_io::Write`], [`std::io::Read`], [`std::io::Write`]
28    #[error("The provided slice to read from or write to has a len = 0")]
29    ProvidedSliceEmpty,
30
31    /// If you try to read data from an empty buffer this errror is returned
32    #[error("Error reading from buffer: no remaining data")]
33    NoData,
34
35
36    #[cfg(feature = "serde")]
37    #[error("Error while deserializing JSON")]
38    JsonDeserialize(serde_json_core::de::Error)
39}
40
41
42/// Trait that allows to create a reader and a writer for a buffer.
43/// See [`BufferReader`] adn [`BufferWriter`]
44///
45pub trait ReadWrite {
46    /// Creates a reader to read from the buffer
47    fn create_reader<'a>(&'a mut self) -> impl BufferReader + 'a;
48
49    /// Creates a writer to write to the buffer
50    fn create_writer<'a>(&'a mut self) -> impl BufferWriter + 'a;
51}
52
53/// A buffer that allows reading and writuing bytes [`u8`] from / to an underlying generic source
54#[derive(Debug)]
55pub struct Buffer<T: AsMut<[u8]> + AsRef<[u8]>> {
56    pub(crate) source: T,
57    pub(crate) write_position: usize,
58    pub(crate) read_position: usize,
59}
60
61/// Creates a new [`Buffer`] that is backed by an owned [`u8`] array with size `N`
62pub fn new_stack_buffer<const N: usize>() -> Buffer<[u8; N]> {
63    Buffer::<[u8; N]> {
64        source: [0; N],
65        read_position: 0,
66        write_position: 0,
67    }
68}
69
70#[cfg(feature = "defmt")]
71impl <T: AsMut<[u8]> + AsRef<[u8]>> defmt::Format for Buffer<T> {
72    fn format(&self, fmt: defmt::Formatter) {
73        defmt::write!(fmt, 
74            "Buffer(len = {}, cap = {}, rem_cap = {})",
75            self.remaining_len(),
76            self.capacity(),
77            self.remaining_capacity()
78        );
79    }
80}
81
82impl <T: AsMut<[u8]> + AsRef<[u8]>> Buffer<T> {
83
84    /// Create a new buffer from any source 
85    /// 
86    /// # Example
87    /// 
88    /// ```rust
89    ///     use embytes_buffer::Buffer;
90    /// 
91    ///     let mut bytes = [0; 1024];
92    ///     let mut buffer = Buffer::new(&mut bytes);
93    /// ```
94    pub fn new(source: T) -> Self {
95        Self {
96            source,
97            read_position: 0,
98            write_position: 0,
99        }
100    }
101
102    /// Reset the buffer to its initial state
103    pub fn reset(&mut self) {
104        self.read_position = 0;
105        self.write_position = 0;
106    }
107
108    /// Returns the length of the undelying buffer
109    pub fn capacity(&self) -> usize {
110        self.source.as_ref().len()
111    }
112
113    /// Returns the remaining space that can be written to. 
114    /// This method does not perform a [`Buffer::shift`]
115    pub fn remaining_capacity(&self) -> usize {
116        self.capacity() - self.write_position
117    }
118
119    /// returns `true` if there is remaining capacity to write to. 
120    /// is equal to [`Buffer::remaining_capacity`] ` > 0`
121    pub fn has_remaining_capacity(&self) -> bool {
122        self.capacity() > self.write_position
123    }
124
125    /// Returns the remaining bytes to read
126    pub fn remaining_len(&self) -> usize {
127        self.write_position - self.read_position
128    }
129
130    /// returns `true` if there are remainng bytes to read. 
131    pub fn has_remaining_len(&self) -> bool {
132        self.write_position > self.read_position
133    }
134
135    /// Returns `true` if there is dead capacity. 
136    /// Dead capacity occures when bytes are read from a buffer.
137    /// Dead capacity can be regained by using [`Buffer::shift`]
138    pub fn has_dead_capacity(&self) -> bool {
139        self.read_position > 0
140    }
141
142    /// Shifts the content of the source left to reuse space of read bytes. 
143    /// See also [`Buffer::has_dead_capacity`]
144    pub fn shift(&mut self) {
145        self.source.as_mut().rotate_left(self.read_position);
146        self.write_position -= self.read_position;
147        self.read_position = 0;
148    }
149
150    /// Performa s [`Buffer::shift`] if there is no remianing capacity and 
151    /// returns `true` if there is remainig capacity afterwards
152    pub fn ensure_remaining_capacity(&mut self) -> bool {
153        if ! self.has_remaining_capacity() {
154            self.shift();
155        }
156
157        self.has_remaining_capacity()
158    }
159
160    /// Base function for implementing writers like [`embedded_io::Write`]
161    /// Returns the number of bytes writen to the buffer from the provided slice
162    /// 
163    /// # Errors
164    /// 
165    /// [`BufferError::ProvidedSliceEmpty`] if the provided slice is empty
166    /// [`BufferError::NoCapacity`] if the buffer has no capacity after calling [`Buffer::shift`]
167    pub(crate) fn write_base(&mut self, buf: &[u8]) -> Result<usize, BufferError> {
168        if buf.is_empty() {
169            return Err(BufferError::ProvidedSliceEmpty);
170        }
171
172        if ! self.has_remaining_capacity() && self.has_dead_capacity() {
173            self.shift();
174        }
175        
176        let cap = self.remaining_capacity();
177        if cap == 0 {
178            return Err(BufferError::NoCapacity);
179        }
180
181        let tgt = self.source.as_mut();
182        let tgt = &mut tgt[self.write_position..];
183        
184        if cap < buf.len() {
185            tgt.copy_from_slice(&buf[0..cap]);
186            self.write_position += cap;
187            Ok(cap)
188        } else {
189            let tgt = &mut tgt[0..buf.len()];
190            tgt.copy_from_slice(buf);
191            self.write_position += buf.len();
192            Ok(buf.len())
193        }
194    }
195
196    /// Base function for implementing readers like [`embedded_io::Read`]
197    /// Returns the number of bytes read from the buffer to the provided slice
198    /// 
199    /// # Errors
200    /// 
201    /// [`BufferError::ProvidedSliceEmpty`] if the provided slice is empty
202    /// [`BufferError::NoData`] if there ae no bytes to read
203    pub(crate) fn read_base(&mut self, buf: &mut[u8]) -> Result<usize, BufferError> {
204        if buf.is_empty() {
205            return Err(BufferError::ProvidedSliceEmpty);
206        }
207
208        let src = self.source.as_ref();
209        let src = &src[self.read_position..self.write_position];
210
211        if src.is_empty() {
212            return Err(BufferError::NoData);
213        }
214        else if src.len() > buf.len() {
215            buf.copy_from_slice(&src[0..buf.len()]);
216            self.read_position += buf.len();
217            Ok(buf.len())
218        } else {
219            let buf = &mut buf[0..src.len()];
220            buf.copy_from_slice(src);
221            self.read_position += src.len();
222
223            Ok(src.len())
224        }
225    }
226
227    /// Creates a reader that ready at most `max_bytes`
228    pub fn create_reader_with_max(&mut self, max_bytes: usize) -> Reader<'_, T> {
229        Reader::new_with_max(self, max_bytes)
230    }
231
232    /// Returns a slice containing the readable data
233    pub fn data(&self) -> &[u8] {
234        let src = self.source.as_ref();
235        &src[self.read_position..self.write_position]
236    }
237
238    /// Skips `n` readable bytes
239    /// 
240    /// # Errors
241    /// 
242    /// [`BufferError::NoData`] if `n < self.remaining_len()`
243    pub fn skip(&mut self, n: usize) -> Result<(), BufferError> {
244        if self.remaining_len() >= n {
245            self.read_position += n;
246            Ok(())
247        } else {
248            Err(BufferError::NoData)
249        }
250    }
251
252    /// Appends the provided slice to the buffer a a whole
253    /// 
254    /// # Error
255    /// 
256    /// [`BufferError::NoCapacity`] if `buf.len() > self.remaining_capacity()`
257    pub fn push(&mut self, buf: &[u8]) -> Result<(), BufferError> {
258        if self.remaining_capacity() < buf.len() && self.has_dead_capacity() {
259            self.shift();
260        }
261        
262        if self.remaining_capacity() >= buf.len() {
263            let tgt = self.source.as_mut();
264            let tgt = &mut tgt[self.write_position..];
265            let tgt = &mut tgt[0..buf.len()];
266            tgt.copy_from_slice(buf);
267            self.write_position += buf.len();
268            Ok(())
269        } else {
270            Err(BufferError::NoCapacity)
271        }
272    }
273
274}
275
276impl <T: AsMut<[u8]> + AsRef<[u8]>> ReadWrite for Buffer<T> {
277    fn create_reader<'a>(&'a mut self) -> impl BufferReader + 'a {
278        Reader::new(self)
279    }
280
281    fn create_writer<'a>(&'a mut self) -> impl BufferWriter + 'a {
282        self.shift();
283        Write::new(self)
284
285    }
286}
287
288#[cfg(feature = "std")]
289impl <T: AsMut<[u8]> + AsRef<[u8]>> std::io::Write for Buffer<T> {
290
291    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
292        use std::io::ErrorKind;
293        match self.write_base(buf) {
294            Ok(n) => Ok(n),
295            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
296            Err(BufferError::NoCapacity) => Err(ErrorKind::WouldBlock.into()),
297            Err(e) => {
298                panic!("unexpected error writing to buffer: {}", e);
299            }
300        }
301    }
302
303    fn flush(&mut self) -> std::io::Result<()> {
304        Ok(())
305    }
306}
307
308#[cfg(feature = "std")]
309impl <T: AsMut<[u8]> + AsRef<[u8]>> std::io::Read for Buffer<T> {
310    
311    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
312        use std::io::ErrorKind;
313
314        match self.read_base(buf) {
315            Ok(n) => Ok(n),
316            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
317            Err(BufferError::NoData) => Err(ErrorKind::WouldBlock.into()),
318            Err(e) => {
319                panic!("unexpected error reading from buffer: {}", e);
320            }
321        }
322    }
323}
324
325#[cfg(feature = "embedded")]
326impl <T: AsMut<[u8]> + AsRef<[u8]>> embedded_io::ErrorType for Buffer<T> {
327    type Error = embedded_io::ErrorKind;
328}
329
330#[cfg(feature = "embedded")]
331impl <T: AsMut<[u8]> + AsRef<[u8]>> embedded_io::Write for Buffer<T> {
332    
333    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
334        use embedded_io::ErrorKind;
335
336        match self.write_base(buf) {
337            Ok(n) => Ok(n),
338            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
339            Err(BufferError::NoCapacity) => Err(ErrorKind::Other),
340            Err(e) => {
341                panic!("unexpected error writing to buffer: {}", e);
342            }
343        }
344    }
345
346    fn flush(&mut self) -> Result<(), Self::Error> {
347        Ok(())
348    }
349}
350
351#[cfg(feature = "embedded")]
352impl <T: AsMut<[u8]> + AsRef<[u8]>> embedded_io::Read for Buffer<T> {
353    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
354        use embedded_io::ErrorKind;
355
356        match self.read_base(buf) {
357            Ok(n) => Ok(n),
358            Err(BufferError::ProvidedSliceEmpty) => Ok(0),
359            Err(BufferError::NoData) => Err(ErrorKind::Other),
360            Err(e) => {
361                panic!("unexpected error reading from buffer: {}", e);
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}