rt_ring/lib.rs
1mod shared;
2
3use shared::Shared;
4use std::sync::Arc;
5
6/// Creates a new SPSC ring buffer with the given capacity.
7///
8/// Capacity is rounded up to the next power of two.
9/// Returns a `(Producer, Consumer)` pair.
10///
11/// # Panics
12///
13/// Panics if `capacity` is zero.
14///
15/// # Examples
16///
17/// ```
18/// let (p, c) = rt_ring::new(4);
19/// p.push(1.0);
20/// p.push(2.0);
21/// assert_eq!(c.pop(), Some(1.0));
22/// assert_eq!(c.pop(), Some(2.0));
23/// assert_eq!(c.pop(), None);
24/// ```
25pub fn new(capacity: usize) -> (Producer, Consumer) {
26 let shared = Arc::new(Shared::new(capacity));
27 (
28 Producer {
29 shared: Arc::clone(&shared),
30 },
31 Consumer { shared },
32 )
33}
34
35/// The producer half of the ring buffer. Not `Clone` — enforces single-producer.
36pub struct Producer {
37 shared: Arc<Shared>,
38}
39
40impl Producer {
41 /// Push a sample into the buffer. If the buffer is full, the oldest sample
42 /// is overwritten.
43 ///
44 /// # Examples
45 ///
46 /// ```
47 /// let (p, c) = rt_ring::new(4);
48 /// p.push(0.5);
49 /// assert_eq!(c.pop(), Some(0.5));
50 /// ```
51 pub fn push(&self, sample: f32) {
52 self.shared.push(sample);
53 }
54
55 /// Push a slice of samples into the buffer. Samples that cause overflow
56 /// overwrite the oldest data.
57 ///
58 /// # Examples
59 ///
60 /// ```
61 /// let (p, c) = rt_ring::new(4);
62 /// p.push_slice(&[1.0, 2.0, 3.0]);
63 /// let mut buf = [0.0f32; 3];
64 /// let n = c.pop_slice(&mut buf);
65 /// assert_eq!(n, 3);
66 /// assert_eq!(&buf, &[1.0, 2.0, 3.0]);
67 /// ```
68 pub fn push_slice(&self, samples: &[f32]) {
69 self.shared.push_slice(samples);
70 }
71
72 /// Returns the number of samples currently available for reading.
73 ///
74 /// # Examples
75 ///
76 /// ```
77 /// let (p, c) = rt_ring::new(4);
78 /// assert_eq!(p.available(), 0);
79 /// p.push(1.0);
80 /// p.push(2.0);
81 /// assert_eq!(p.available(), 2);
82 /// c.pop();
83 /// assert_eq!(p.available(), 1);
84 /// ```
85 pub fn available(&self) -> usize {
86 self.shared.available()
87 }
88
89 /// Returns the buffer capacity (always a power of two).
90 ///
91 /// # Examples
92 ///
93 /// ```
94 /// let (p, _c) = rt_ring::new(5);
95 /// assert_eq!(p.capacity(), 8); // rounded up to next power of two
96 /// ```
97 pub fn capacity(&self) -> usize {
98 self.shared.capacity()
99 }
100
101 /// Returns the total number of samples that were overwritten since creation.
102 ///
103 /// Equivalent to [`Consumer::overwrite_count`] — both read the same atomic counter.
104 ///
105 /// # Examples
106 ///
107 /// ```
108 /// let (p, c) = rt_ring::new(4);
109 /// for i in 0..10 {
110 /// p.push(i as f32);
111 /// }
112 /// assert_eq!(p.overwrite_count(), 6);
113 /// assert_eq!(p.overwrite_count(), c.overwrite_count());
114 /// ```
115 pub fn overwrite_count(&self) -> u64 {
116 self.shared.overwrite_count()
117 }
118}
119
120/// The consumer half of the ring buffer. Not `Clone` — enforces single-consumer.
121pub struct Consumer {
122 shared: Arc<Shared>,
123}
124
125impl Consumer {
126 /// Pop the oldest sample from the buffer, or `None` if empty.
127 pub fn pop(&self) -> Option<f32> {
128 self.shared.pop()
129 }
130
131 /// Pop up to `buf.len()` samples into `buf`. Returns the number of samples read.
132 ///
133 /// # Examples
134 ///
135 /// ```
136 /// let (p, c) = rt_ring::new(4);
137 /// p.push_slice(&[10.0, 20.0, 30.0]);
138 /// let mut buf = [0.0f32; 4];
139 /// let n = c.pop_slice(&mut buf);
140 /// assert_eq!(n, 3);
141 /// assert_eq!(&buf[..n], &[10.0, 20.0, 30.0]);
142 /// ```
143 pub fn pop_slice(&self, buf: &mut [f32]) -> usize {
144 self.shared.pop_slice(buf)
145 }
146
147 /// Returns the number of samples currently available for reading.
148 ///
149 /// # Examples
150 ///
151 /// ```
152 /// let (p, c) = rt_ring::new(4);
153 /// assert_eq!(c.available(), 0);
154 /// p.push(1.0);
155 /// assert_eq!(c.available(), 1);
156 /// ```
157 pub fn available(&self) -> usize {
158 self.shared.available()
159 }
160
161 /// Returns the total number of samples that were overwritten since creation.
162 ///
163 /// # Examples
164 ///
165 /// ```
166 /// let (p, c) = rt_ring::new(4);
167 /// for i in 0..10 {
168 /// p.push(i as f32);
169 /// }
170 /// assert_eq!(c.overwrite_count(), 6);
171 /// ```
172 pub fn overwrite_count(&self) -> u64 {
173 self.shared.overwrite_count()
174 }
175
176 /// Returns the buffer capacity (always a power of two).
177 ///
178 /// # Examples
179 ///
180 /// ```
181 /// let (_p, c) = rt_ring::new(3);
182 /// assert_eq!(c.capacity(), 4); // rounded up to next power of two
183 /// ```
184 pub fn capacity(&self) -> usize {
185 self.shared.capacity()
186 }
187}
188
189// Safety assertions: Producer and Consumer are Send (via Arc<Shared>), but not Clone.
190// This is automatically derived — no manual unsafe impl needed.
191// We add static assertions to catch regressions.
192fn _assert_send<T: Send>() {}
193const _: () = {
194 let _ = _assert_send::<Producer>;
195 let _ = _assert_send::<Consumer>;
196};