embassy_sync/
ring_buffer.rs
1use core::ops::Range;
2
3pub struct RingBuffer<const N: usize> {
4 start: usize,
5 end: usize,
6 full: bool,
7}
8
9impl<const N: usize> RingBuffer<N> {
10 pub const fn new() -> Self {
11 Self {
12 start: 0,
13 end: 0,
14 full: false,
15 }
16 }
17
18 pub fn push_buf(&mut self) -> Range<usize> {
19 if self.is_full() {
20 trace!(" ringbuf: push_buf full");
21 return 0..0;
22 }
23
24 let n = if self.start <= self.end {
25 N - self.end
26 } else {
27 self.start - self.end
28 };
29
30 trace!(" ringbuf: push_buf {:?}..{:?}", self.end, self.end + n);
31 self.end..self.end + n
32 }
33
34 pub fn push(&mut self, n: usize) {
35 trace!(" ringbuf: push {:?}", n);
36 if n == 0 {
37 return;
38 }
39
40 self.end = self.wrap(self.end + n);
41 self.full = self.start == self.end;
42 }
43
44 pub fn pop_buf(&mut self) -> Range<usize> {
45 if self.is_empty() {
46 trace!(" ringbuf: pop_buf empty");
47 return 0..0;
48 }
49
50 let n = if self.end <= self.start {
51 N - self.start
52 } else {
53 self.end - self.start
54 };
55
56 trace!(" ringbuf: pop_buf {:?}..{:?}", self.start, self.start + n);
57 self.start..self.start + n
58 }
59
60 pub fn pop(&mut self, n: usize) {
61 trace!(" ringbuf: pop {:?}", n);
62 if n == 0 {
63 return;
64 }
65
66 self.start = self.wrap(self.start + n);
67 self.full = false;
68 }
69
70 pub fn is_full(&self) -> bool {
71 self.full
72 }
73
74 pub fn is_empty(&self) -> bool {
75 self.start == self.end && !self.full
76 }
77
78 #[allow(unused)]
79 pub fn len(&self) -> usize {
80 if self.is_empty() {
81 0
82 } else if self.start < self.end {
83 self.end - self.start
84 } else {
85 N + self.end - self.start
86 }
87 }
88
89 pub fn clear(&mut self) {
90 self.start = 0;
91 self.end = 0;
92 self.full = false;
93 }
94
95 fn wrap(&self, n: usize) -> usize {
96 assert!(n <= N);
97 if n == N {
98 0
99 } else {
100 n
101 }
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn push_pop() {
111 let mut rb: RingBuffer<4> = RingBuffer::new();
112 let buf = rb.push_buf();
113 assert_eq!(0..4, buf);
114 rb.push(4);
115
116 let buf = rb.pop_buf();
117 assert_eq!(0..4, buf);
118 rb.pop(1);
119
120 let buf = rb.pop_buf();
121 assert_eq!(1..4, buf);
122 rb.pop(1);
123
124 let buf = rb.pop_buf();
125 assert_eq!(2..4, buf);
126 rb.pop(1);
127
128 let buf = rb.pop_buf();
129 assert_eq!(3..4, buf);
130 rb.pop(1);
131
132 let buf = rb.pop_buf();
133 assert_eq!(0..0, buf);
134
135 let buf = rb.push_buf();
136 assert_eq!(0..4, buf);
137 }
138}