Skip to main content

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};