#![deny(missing_debug_implementations, missing_docs)]
#![no_std]
#[cfg(test)]
extern crate std;
extern crate alloc;
mod inserter;
mod remover;
#[cfg(test)]
pub mod proputils;
use alloc::vec::Vec;
pub use inserter::Inserter;
pub use remover::Remover;
pub mod prelude {
pub use super::{InsertSliceClone, InsertSliceCopy, ScanMut};
}
pub trait ScanMut<T> {
fn multi_insert<I>(&mut self, iter: I)
where
I: IntoIterator<Item = (usize, T)>,
I::IntoIter: ExactSizeIterator;
fn multi_remove<I, F>(&mut self, iter: I, sink: F)
where
I: IntoIterator<Item = usize>,
F: FnMut(T);
fn insert_all<I>(&mut self, index: usize, items: I)
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator + DoubleEndedIterator;
fn insert_all_rev<I>(&mut self, index: usize, items: I)
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator;
}
impl<T> ScanMut<T> for Vec<T> {
fn multi_insert<I>(&mut self, iter: I)
where
I: IntoIterator<Item = (usize, T)>,
I::IntoIter: ExactSizeIterator,
{
let iter = iter.into_iter();
let mut inserter = Inserter::new(self, iter.len());
iter.for_each(|(ix, item)| {
inserter.move_to(ix);
inserter.insert(item);
});
assert!(
inserter.remaining_inserts() == 0,
"Iterator shorter than reported length"
);
}
fn multi_remove<I, F>(&mut self, iter: I, mut sink: F)
where
I: IntoIterator<Item = usize>,
F: FnMut(T),
{
let mut remover = Remover::new(self);
iter.into_iter().for_each(|ix| {
remover.move_to(ix);
sink(remover.remove());
});
}
fn insert_all<I>(&mut self, index: usize, items: I)
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator + DoubleEndedIterator,
{
let iter = items.into_iter();
let mut inserter = Inserter::new(self, iter.len());
inserter.move_to(index);
inserter.insert_all(iter);
assert!(
inserter.remaining_inserts() == 0,
"Iterator shorter than reported length"
);
}
fn insert_all_rev<I>(&mut self, index: usize, items: I)
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator,
{
let iter = items.into_iter();
let mut inserter = Inserter::new(self, iter.len());
inserter.move_to(index);
inserter.insert_all_rev(iter);
assert!(
inserter.remaining_inserts() == 0,
"Iterator shorter than reported length"
);
}
}
pub trait InsertSliceClone<T: Clone>: ScanMut<T> {
fn insert_slice_clone(&mut self, index: usize, slice: &[T]);
}
impl<T: Clone> InsertSliceClone<T> for Vec<T> {
fn insert_slice_clone(&mut self, index: usize, slice: &[T]) {
let mut inserter = Inserter::new(self, slice.len());
inserter.move_to(index);
inserter.insert_slice_clone(slice);
}
}
pub trait InsertSliceCopy<T: Copy>: InsertSliceClone<T> {
fn insert_slice_copy(&mut self, index: usize, slice: &[T]);
}
impl<T: Copy> InsertSliceCopy<T> for Vec<T> {
fn insert_slice_copy(&mut self, index: usize, slice: &[T]) {
let mut inserter = Inserter::new(self, slice.len());
inserter.move_to(index);
inserter.insert_slice_copy(slice);
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
use core::iter::once;
#[test]
fn multimutate_single_insert() {
let mut items = Vec::new();
items.multi_insert(once((0, 1)));
assert_eq!(items, vec![1]);
}
#[test]
fn multimutate_single_insert_pre() {
let mut items = vec![0];
items.multi_insert(once((0, 1)));
assert_eq!(items, vec![1, 0]);
}
#[test]
fn multimutate_single_insert_mid() {
let mut items = vec![0, 2];
items.multi_insert(once((1, 1)));
assert_eq!(items, vec![0, 1, 2]);
}
#[test]
fn multimutate_single_insert_post() {
let mut items = vec![0];
items.multi_insert(once((1, 1)));
assert_eq!(items, vec![0, 1]);
}
#[test]
#[should_panic]
fn multimutate_single_insert_out_of_bounds() {
let mut items = vec![0];
items.multi_insert(once((2, 1)));
}
#[test]
fn multimutate_multiple_insert() {
let mut items = vec![1];
items.multi_insert([(1, 2), (0, 0)].iter().cloned());
assert_eq!(items, vec![0, 1, 2]);
}
#[test]
fn multimutate_single_insert_zero_sized() {
let mut items = vec![()];
items.multi_insert(once((0, ())));
assert_eq!(items, vec![(), ()]);
}
#[test]
#[should_panic]
fn multimutate_single_insert_zero_sized_out_of_bounds() {
let mut items = vec![()];
items.multi_insert(once((2, ())));
assert_eq!(items, vec![(), ()]);
}
#[test]
#[should_panic]
fn multimutate_remove() {
let mut items = vec![1, 2, 3];
let mut index = 0;
items.multi_remove(vec![1, 2], |x| {
assert_eq!(
x,
match index {
0 => 1,
1 => 2,
_ => panic!(),
}
);
index += 1;
});
assert_eq!(items, [1]);
}
#[test]
fn insert_all() {
let mut items = vec![1, 2, 3];
items.insert_all(1, [4, 5, 6].iter().cloned());
assert_eq!(items, [1, 4, 5, 6, 2, 3]);
}
#[test]
fn insert_all_end() {
let mut items = vec![1, 2, 3];
items.insert_all(3, [4, 5, 6].iter().cloned());
assert_eq!(items, [1, 2, 3, 4, 5, 6]);
}
#[test]
fn insert_all_rev() {
let mut items = vec![1, 2, 3];
items.insert_all_rev(1, [4, 5, 6].iter().cloned());
assert_eq!(items, [1, 6, 5, 4, 2, 3]);
}
#[test]
fn insert_all_rev_end() {
let mut items = vec![1, 2, 3];
items.insert_all_rev(3, [4, 5, 6].iter().cloned());
assert_eq!(items, [1, 2, 3, 6, 5, 4]);
}
#[test]
fn insert_slice_clone() {
let mut items = vec![1, 2, 3];
items.insert_slice_clone(1, &[4, 5, 6]);
assert_eq!(items, [1, 4, 5, 6, 2, 3]);
}
#[test]
fn insert_slice_copy() {
let mut items = vec![1, 2, 3];
items.insert_slice_copy(1, &[4, 5, 6]);
assert_eq!(items, [1, 4, 5, 6, 2, 3]);
}
}