ringbuf/
transfer.rs

1use crate::{consumer::Consumer, producer::Producer};
2
3/// Moves at most `count` items from the `src` consumer to the `dst` producer.
4///
5/// Consumer and producer may be of different buffers as well as of the same one.
6/// `count` is the number of items being moved, if `None` - as much as possible items will be moved.
7///
8/// Returns number of items been moved.
9pub fn transfer<T, C: Consumer<Item = T>, P: Producer<Item = T>>(src: &mut C, dst: &mut P, count: Option<usize>) -> usize {
10    let (src_left, src_right) = src.occupied_slices();
11    let (dst_left, dst_right) = dst.vacant_slices_mut();
12    let src_iter = src_left.iter().chain(src_right.iter());
13    let dst_iter = dst_left.iter_mut().chain(dst_right.iter_mut());
14
15    let mut actual_count = 0;
16    for (src_elem, dst_place) in src_iter.zip(dst_iter) {
17        if let Some(count) = count {
18            if actual_count >= count {
19                break;
20            }
21        }
22        unsafe { dst_place.write(src_elem.as_ptr().read()) };
23        actual_count += 1;
24    }
25    unsafe { src.advance_read_index(actual_count) };
26    unsafe { dst.advance_write_index(actual_count) };
27    actual_count
28}