1 use crate::RingBuffer;
2 use alloc::rc::Rc;
3 use core::mem::MaybeUninit;
4 
5 #[test]
push()6 fn push() {
7     let cap = 2;
8     let buf = RingBuffer::<i32>::new(cap);
9     let (mut prod, mut cons) = buf.split();
10 
11     let vs_20 = (123, 456);
12     let push_fn_20 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
13         assert_eq!(left.len(), 2);
14         assert_eq!(right.len(), 0);
15         left[0] = MaybeUninit::new(vs_20.0);
16         left[1] = MaybeUninit::new(vs_20.1);
17         2
18     };
19 
20     assert_eq!(unsafe { prod.push_access(push_fn_20) }, 2);
21 
22     assert_eq!(cons.pop().unwrap(), vs_20.0);
23     assert_eq!(cons.pop().unwrap(), vs_20.1);
24     assert_eq!(cons.pop(), None);
25 
26     let vs_11 = (123, 456);
27     let push_fn_11 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
28         assert_eq!(left.len(), 1);
29         assert_eq!(right.len(), 1);
30         left[0] = MaybeUninit::new(vs_11.0);
31         right[0] = MaybeUninit::new(vs_11.1);
32         2
33     };
34 
35     assert_eq!(unsafe { prod.push_access(push_fn_11) }, 2);
36 
37     assert_eq!(cons.pop().unwrap(), vs_11.0);
38     assert_eq!(cons.pop().unwrap(), vs_11.1);
39     assert_eq!(cons.pop(), None);
40 }
41 
42 #[test]
pop_full()43 fn pop_full() {
44     let cap = 2;
45     let buf = RingBuffer::<i32>::new(cap);
46     let (_, mut cons) = buf.split();
47 
48     let dummy_fn = |_l: &mut [MaybeUninit<i32>], _r: &mut [MaybeUninit<i32>]| -> usize { 0 };
49     assert_eq!(unsafe { cons.pop_access(dummy_fn) }, 0);
50 }
51 
52 #[test]
pop_empty()53 fn pop_empty() {
54     let cap = 2;
55     let buf = RingBuffer::<i32>::new(cap);
56     let (_, mut cons) = buf.split();
57 
58     let dummy_fn = |_l: &mut [MaybeUninit<i32>], _r: &mut [MaybeUninit<i32>]| -> usize { 0 };
59     assert_eq!(unsafe { cons.pop_access(dummy_fn) }, 0);
60 }
61 
62 #[test]
pop()63 fn pop() {
64     let cap = 2;
65     let buf = RingBuffer::<i32>::new(cap);
66     let (mut prod, mut cons) = buf.split();
67 
68     let vs_20 = (123, 456);
69 
70     assert_eq!(prod.push(vs_20.0), Ok(()));
71     assert_eq!(prod.push(vs_20.1), Ok(()));
72     assert_eq!(prod.push(0), Err(0));
73 
74     let pop_fn_20 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
75         unsafe {
76             assert_eq!(left.len(), 2);
77             assert_eq!(right.len(), 0);
78             assert_eq!(left[0].assume_init(), vs_20.0);
79             assert_eq!(left[1].assume_init(), vs_20.1);
80             2
81         }
82     };
83 
84     assert_eq!(unsafe { cons.pop_access(pop_fn_20) }, 2);
85 
86     let vs_11 = (123, 456);
87 
88     assert_eq!(prod.push(vs_11.0), Ok(()));
89     assert_eq!(prod.push(vs_11.1), Ok(()));
90     assert_eq!(prod.push(0), Err(0));
91 
92     let pop_fn_11 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
93         unsafe {
94             assert_eq!(left.len(), 1);
95             assert_eq!(right.len(), 1);
96             assert_eq!(left[0].assume_init(), vs_11.0);
97             assert_eq!(right[0].assume_init(), vs_11.1);
98             2
99         }
100     };
101 
102     assert_eq!(unsafe { cons.pop_access(pop_fn_11) }, 2);
103 }
104 
105 #[test]
push_return()106 fn push_return() {
107     let cap = 2;
108     let buf = RingBuffer::<i32>::new(cap);
109     let (mut prod, mut cons) = buf.split();
110 
111     let push_fn_0 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
112         assert_eq!(left.len(), 2);
113         assert_eq!(right.len(), 0);
114         0
115     };
116 
117     assert_eq!(unsafe { prod.push_access(push_fn_0) }, 0);
118 
119     let push_fn_1 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
120         assert_eq!(left.len(), 2);
121         assert_eq!(right.len(), 0);
122         left[0] = MaybeUninit::new(12);
123         1
124     };
125 
126     assert_eq!(unsafe { prod.push_access(push_fn_1) }, 1);
127 
128     let push_fn_2 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
129         assert_eq!(left.len(), 1);
130         assert_eq!(right.len(), 0);
131         left[0] = MaybeUninit::new(34);
132         1
133     };
134 
135     assert_eq!(unsafe { prod.push_access(push_fn_2) }, 1);
136 
137     assert_eq!(cons.pop().unwrap(), 12);
138     assert_eq!(cons.pop().unwrap(), 34);
139     assert_eq!(cons.pop(), None);
140 }
141 
142 #[test]
pop_return()143 fn pop_return() {
144     let cap = 2;
145     let buf = RingBuffer::<i32>::new(cap);
146     let (mut prod, mut cons) = buf.split();
147 
148     assert_eq!(prod.push(12), Ok(()));
149     assert_eq!(prod.push(34), Ok(()));
150     assert_eq!(prod.push(0), Err(0));
151 
152     let pop_fn_0 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
153         assert_eq!(left.len(), 2);
154         assert_eq!(right.len(), 0);
155         0
156     };
157 
158     assert_eq!(unsafe { cons.pop_access(pop_fn_0) }, 0);
159 
160     let pop_fn_1 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
161         unsafe {
162             assert_eq!(left.len(), 2);
163             assert_eq!(right.len(), 0);
164             assert_eq!(left[0].assume_init(), 12);
165             1
166         }
167     };
168 
169     assert_eq!(unsafe { cons.pop_access(pop_fn_1) }, 1);
170 
171     let pop_fn_2 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
172         unsafe {
173             assert_eq!(left.len(), 1);
174             assert_eq!(right.len(), 0);
175             assert_eq!(left[0].assume_init(), 34);
176             1
177         }
178     };
179 
180     assert_eq!(unsafe { cons.pop_access(pop_fn_2) }, 1);
181 }
182 
183 #[test]
push_pop()184 fn push_pop() {
185     let cap = 2;
186     let buf = RingBuffer::<i32>::new(cap);
187     let (mut prod, mut cons) = buf.split();
188 
189     let vs_20 = (123, 456);
190     let push_fn_20 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
191         assert_eq!(left.len(), 2);
192         assert_eq!(right.len(), 0);
193         left[0] = MaybeUninit::new(vs_20.0);
194         left[1] = MaybeUninit::new(vs_20.1);
195         2
196     };
197 
198     assert_eq!(unsafe { prod.push_access(push_fn_20) }, 2);
199 
200     let pop_fn_20 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
201         unsafe {
202             assert_eq!(left.len(), 2);
203             assert_eq!(right.len(), 0);
204             assert_eq!(left[0].assume_init(), vs_20.0);
205             assert_eq!(left[1].assume_init(), vs_20.1);
206             2
207         }
208     };
209 
210     assert_eq!(unsafe { cons.pop_access(pop_fn_20) }, 2);
211 
212     let vs_11 = (123, 456);
213     let push_fn_11 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
214         assert_eq!(left.len(), 1);
215         assert_eq!(right.len(), 1);
216         left[0] = MaybeUninit::new(vs_11.0);
217         right[0] = MaybeUninit::new(vs_11.1);
218         2
219     };
220 
221     assert_eq!(unsafe { prod.push_access(push_fn_11) }, 2);
222 
223     let pop_fn_11 = |left: &mut [MaybeUninit<i32>], right: &mut [MaybeUninit<i32>]| -> usize {
224         unsafe {
225             assert_eq!(left.len(), 1);
226             assert_eq!(right.len(), 1);
227             assert_eq!(left[0].assume_init(), vs_11.0);
228             assert_eq!(right[0].assume_init(), vs_11.1);
229             2
230         }
231     };
232 
233     assert_eq!(unsafe { cons.pop_access(pop_fn_11) }, 2);
234 }
235 
236 #[test]
discard()237 fn discard() {
238     // Initialize ringbuffer, prod and cons
239     let rb = RingBuffer::<i8>::new(10);
240     let (mut prod, mut cons) = rb.split();
241     let mut i = 0;
242 
243     // Fill the buffer
244     for _ in 0..10 {
245         prod.push(i).unwrap();
246         i += 1;
247     }
248 
249     // Pop in the middle of the buffer
250     assert_eq!(cons.discard(5), 5);
251 
252     // Make sure changes are taken into account
253     assert_eq!(cons.pop().unwrap(), 5);
254 
255     // Fill the buffer again
256     for _ in 0..5 {
257         prod.push(i).unwrap();
258         i += 1;
259     }
260 
261     assert_eq!(cons.discard(6), 6);
262     assert_eq!(cons.pop().unwrap(), 12);
263 
264     // Fill the buffer again
265     for _ in 0..7 {
266         prod.push(i).unwrap();
267         i += 1;
268     }
269 
270     // Ask too much, delete the max number of elements
271     assert_eq!(cons.discard(10), 9);
272 
273     // Try to remove more than possible
274     assert_eq!(cons.discard(1), 0);
275 
276     // Make sure it is still usable
277     assert_eq!(cons.pop(), None);
278     assert_eq!(prod.push(0), Ok(()));
279     assert_eq!(cons.pop(), Some(0));
280 }
281 
282 #[test]
discard_drop()283 fn discard_drop() {
284     let rc = Rc::<()>::new(());
285 
286     static N: usize = 10;
287 
288     let rb = RingBuffer::<Rc<()>>::new(N);
289     let (mut prod, mut cons) = rb.split();
290 
291     for _ in 0..N {
292         prod.push(rc.clone()).unwrap();
293     }
294 
295     assert_eq!(cons.len(), N);
296     assert_eq!(Rc::strong_count(&rc), N + 1);
297 
298     assert_eq!(cons.discard(N), N);
299 
300     // Check ring buffer is empty
301     assert_eq!(cons.len(), 0);
302     // Check that items are dropped
303     assert_eq!(Rc::strong_count(&rc), 1);
304 }
305