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#[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
36pub 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
53pub 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 pub fn new(source: T) -> Self {
87 Self {
88 source,
89 read_position: 0,
90 write_position: 0,
91 }
92 }
93
94 pub fn reset(&mut self) {
96 self.read_position = 0;
97 self.write_position = 0;
98 }
99
100 pub fn capacity(&self) -> usize {
102 self.source.as_ref().len()
103 }
104
105 pub fn remaining_capacity(&self) -> usize {
108 self.capacity() - self.write_position
109 }
110
111 pub fn has_remaining_capacity(&self) -> bool {
114 self.capacity() > self.write_position
115 }
116
117 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 pub fn has_dead_capacity(&self) -> bool {
128 self.read_position > 0
129 }
130
131 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 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 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 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 pub fn data(&self) -> &[u8] {
221 let src = self.source.as_ref();
222 &src[self.read_position..self.write_position]
223 }
224
225 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 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
354impl <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 let n = buf.write_base(&[1, 2, 3, 4, 5, 6, 7, 8]).unwrap();
436 assert_eq!(n, 8);
437
438 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 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}