1pub struct DescriptorRing<D, const N: usize> {
12 descriptors: [D; N],
14 current: usize,
16}
17
18impl<D, const N: usize> DescriptorRing<D, N> {
19 #[must_use]
21 pub const fn new(descriptors: [D; N]) -> Self {
22 Self {
23 descriptors,
24 current: 0,
25 }
26 }
27
28 #[inline(always)]
30 #[must_use]
31 pub const fn len(&self) -> usize {
32 N
33 }
34
35 #[inline(always)]
37 #[must_use]
38 pub const fn is_empty(&self) -> bool {
39 N == 0
40 }
41
42 #[inline(always)]
44 #[must_use]
45 pub const fn current_index(&self) -> usize {
46 self.current
47 }
48
49 #[inline(always)]
51 pub fn advance(&mut self) {
52 self.current = (self.current + 1) % N;
53 }
54
55 #[inline(always)]
57 pub fn advance_by(&mut self, count: usize) {
58 self.current = (self.current + count) % N;
59 }
60
61 #[inline(always)]
63 pub fn reset(&mut self) {
64 self.current = 0;
65 }
66
67 #[inline(always)]
69 pub fn current(&self) -> &D {
70 &self.descriptors[self.current]
71 }
72
73 #[inline(always)]
75 pub fn current_mut(&mut self) -> &mut D {
76 &mut self.descriptors[self.current]
77 }
78
79 #[inline(always)]
81 pub fn get(&self, index: usize) -> &D {
82 &self.descriptors[index % N]
83 }
84
85 #[inline(always)]
87 pub fn get_mut(&mut self, index: usize) -> &mut D {
88 &mut self.descriptors[index % N]
89 }
90
91 #[inline(always)]
93 pub fn base_addr(&self) -> *const D {
94 self.descriptors.as_ptr()
95 }
96
97 pub fn iter(&self) -> impl Iterator<Item = &D> {
99 self.descriptors.iter()
100 }
101
102 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut D> {
104 self.descriptors.iter_mut()
105 }
106}
107
108#[cfg(test)]
113mod tests {
114 use super::*;
115
116 #[test]
117 fn ring_len() {
118 let ring = DescriptorRing::new([0u32; 8]);
119 assert_eq!(ring.len(), 8);
120 assert!(!ring.is_empty());
121 }
122
123 #[test]
124 fn ring_advance_wraps() {
125 let mut ring = DescriptorRing::new([0u32; 4]);
126 assert_eq!(ring.current_index(), 0);
127 ring.advance();
128 assert_eq!(ring.current_index(), 1);
129 ring.advance();
130 assert_eq!(ring.current_index(), 2);
131 ring.advance();
132 assert_eq!(ring.current_index(), 3);
133 ring.advance();
134 assert_eq!(ring.current_index(), 0); }
136
137 #[test]
138 fn ring_current_changes_after_advance() {
139 let mut ring = DescriptorRing::new([10u32, 20, 30]);
140 assert_eq!(*ring.current(), 10);
141 ring.advance();
142 assert_eq!(*ring.current(), 20);
143 ring.advance();
144 assert_eq!(*ring.current(), 30);
145 }
146
147 #[test]
148 fn ring_reset() {
149 let mut ring = DescriptorRing::new([0u32; 4]);
150 ring.advance();
151 ring.advance();
152 assert_eq!(ring.current_index(), 2);
153 ring.reset();
154 assert_eq!(ring.current_index(), 0);
155 }
156
157 #[test]
158 fn ring_base_addr() {
159 let ring = DescriptorRing::new([10u32, 20, 30]);
160 let ptr = ring.base_addr();
161 assert!(!ptr.is_null());
162 unsafe {
164 assert_eq!(*ptr, 10);
165 }
166 }
167
168 #[test]
169 fn ring_get_by_index() {
170 let ring = DescriptorRing::new([10u32, 20, 30, 40]);
171 assert_eq!(*ring.get(0), 10);
172 assert_eq!(*ring.get(1), 20);
173 assert_eq!(*ring.get(3), 40);
174 }
175
176 #[test]
177 fn ring_get_wraps() {
178 let ring = DescriptorRing::new([10u32, 20, 30, 40]);
179 assert_eq!(*ring.get(4), 10); assert_eq!(*ring.get(5), 20);
181 }
182
183 #[test]
184 fn ring_get_mut_modifies() {
185 let mut ring = DescriptorRing::new([10u32, 20, 30]);
186 *ring.get_mut(1) = 999;
187 assert_eq!(*ring.get(1), 999);
188 }
189
190 #[test]
191 fn ring_current_mut_modifies() {
192 let mut ring = DescriptorRing::new([10u32, 20, 30]);
193 *ring.current_mut() = 42;
194 assert_eq!(*ring.current(), 42);
195 }
196
197 #[test]
198 fn ring_iter() {
199 let ring = DescriptorRing::new([1u32, 2, 3, 4]);
200 let mut iter = ring.iter();
201 assert_eq!(iter.next(), Some(&1));
202 assert_eq!(iter.next(), Some(&2));
203 assert_eq!(iter.next(), Some(&3));
204 assert_eq!(iter.next(), Some(&4));
205 assert_eq!(iter.next(), None);
206 }
207
208 #[test]
209 fn ring_iter_mut() {
210 let mut ring = DescriptorRing::new([1u32, 2, 3, 4]);
211 for val in ring.iter_mut() {
212 *val *= 10;
213 }
214 assert_eq!(*ring.get(0), 10);
215 assert_eq!(*ring.get(1), 20);
216 assert_eq!(*ring.get(2), 30);
217 assert_eq!(*ring.get(3), 40);
218 }
219
220 #[test]
221 fn ring_single_element() {
222 let mut ring = DescriptorRing::new([42u32]);
223 assert_eq!(ring.len(), 1);
224 assert_eq!(*ring.current(), 42);
225 ring.advance();
226 assert_eq!(ring.current_index(), 0); }
228
229 #[test]
230 fn ring_wraparound_stress() {
231 let mut ring = DescriptorRing::new([0u32; 7]);
232 for i in 0..100 {
233 assert_eq!(ring.current_index(), i % 7);
234 ring.advance();
235 }
236 }
237}