stm32f1_hal/common/
ringbuf.rs

1pub use rtrb::{
2    Consumer, Producer, RingBuffer,
3    chunks::{ReadChunk, WriteChunkUninit},
4};
5
6pub trait ProducerExt<T> {
7    fn get_write_chunk_uninit(&mut self) -> Option<WriteChunkUninit<'_, T>>;
8    fn push_slice(&mut self, buf: &[T]) -> Option<usize>;
9}
10impl<T: Copy> ProducerExt<T> for Producer<T> {
11    fn get_write_chunk_uninit(&mut self) -> Option<WriteChunkUninit<'_, T>> {
12        let n = self.slots();
13        if n > 0 {
14            if let Ok(chunk) = self.write_chunk_uninit(n) {
15                return Some(chunk);
16            }
17        }
18        None
19    }
20
21    fn push_slice(&mut self, buf: &[T]) -> Option<usize> {
22        let mut size = self.slots();
23        if size > 0 {
24            let buf = if size >= buf.len() {
25                size = buf.len();
26                buf
27            } else {
28                &buf[..size]
29            };
30
31            let mut chunk = self.write_chunk_uninit(size).unwrap();
32            let (c1, c2) = chunk.get_mut_slices();
33
34            if c1.len() == size {
35                c1.copy_from_slice(buf);
36            } else {
37                let (b1, b2) = buf.split_at(c1.len());
38                c1.copy_from_slice(b1);
39                c2.copy_from_slice(b2);
40            };
41            unsafe {
42                chunk.commit_all();
43            }
44            Some(size)
45        } else {
46            None
47        }
48    }
49}
50
51pub trait WriteChunkExt<T> {
52    fn get_mut_slice(&mut self) -> &mut [T];
53    fn get_mut_slices(&mut self) -> (&mut [T], &mut [T]);
54}
55impl<T: Copy> WriteChunkExt<T> for WriteChunkUninit<'_, T> {
56    #[inline]
57    fn get_mut_slice(&mut self) -> &mut [T] {
58        let (buf, _) = self.as_mut_slices();
59        unsafe {
60            let dst_ptr = buf.as_mut_ptr().cast();
61            core::slice::from_raw_parts_mut(dst_ptr, buf.len())
62        }
63    }
64
65    #[inline]
66    fn get_mut_slices(&mut self) -> (&mut [T], &mut [T]) {
67        let (a, b) = self.as_mut_slices();
68        unsafe {
69            (
70                core::slice::from_raw_parts_mut(a.as_mut_ptr().cast(), a.len()),
71                core::slice::from_raw_parts_mut(b.as_mut_ptr().cast(), b.len()),
72            )
73        }
74    }
75}
76
77pub trait ConsumerExt<T> {
78    fn get_read_chunk(&mut self) -> Option<ReadChunk<'_, T>>;
79    fn pop_slice(&mut self, elems: &mut [T]) -> Option<usize>;
80}
81impl<T: Copy> ConsumerExt<T> for Consumer<T> {
82    fn get_read_chunk(&mut self) -> Option<ReadChunk<'_, T>> {
83        let n = self.slots();
84        if n > 0 {
85            if let Ok(chunk) = self.read_chunk(n) {
86                return Some(chunk);
87            }
88        }
89        None
90    }
91
92    fn pop_slice(&mut self, buf: &mut [T]) -> Option<usize> {
93        let mut size = self.slots();
94        if size > 0 {
95            let buf = if size >= buf.len() {
96                size = buf.len();
97                buf
98            } else {
99                &mut buf[..size]
100            };
101
102            let chunk = self.read_chunk(size).unwrap();
103            let (c1, c2) = chunk.as_slices();
104
105            if c1.len() == size {
106                buf.copy_from_slice(c1);
107            } else {
108                let (b1, b2) = buf.split_at_mut(c1.len());
109                b1.copy_from_slice(c1);
110                b2.copy_from_slice(c2);
111            };
112            chunk.commit_all();
113            Some(size)
114        } else {
115            None
116        }
117    }
118}
119
120pub trait ReadChunkExt<T> {
121    fn get_slice(&self) -> &[T];
122}
123impl<T: Copy> ReadChunkExt<T> for ReadChunk<'_, T> {
124    #[inline]
125    fn get_slice(&self) -> &[T] {
126        let (buf, _) = self.as_slices();
127        buf
128    }
129}