Insert и Remove

Вот, что срез не предоставляет, так это insert и remove, поэтому давайте сделаем их следующими.

Insert нужно сдвинуть все элементы от целевого направо на единицу. Для этого используем ptr::copy, являющийся нашей версией memmove в Си. Он копирует кусок памяти из одного места в другое, корректно обрабатывая случаи, если источник и назначение пересекаются (что точно произойдёт здесь).

Если мы вставим по индексу i, мы должны сдвинуть [i .. len] в [i+1 .. len+1], используя старую длину.

pub fn insert(&mut self, index: usize, elem: T) {
    // Внимание: `<=` потому что считается привильным вставлять после любого элемента
    // что было бы эквивалентно push.
    assert!(index <= self.len, "index out of bounds");
    if self.cap == self.len { self.grow(); }

    unsafe {
        if index < self.len {
            // ptr::copy(src, dest, len): "копировать из источника в назначение len элементов"
            ptr::copy(self.ptr.offset(index as isize),
                      self.ptr.offset(index as isize + 1),
                      self.len - index);
        }
        ptr::write(self.ptr.offset(index as isize), elem);
        self.len += 1;
    }
}

Remove ведёт себя наоборот. Нужно сдвинуть все элементы из [i+1 .. len + 1] в [i .. len], используя новую длину.

pub fn remove(&mut self, index: usize) -> T {
    // Внимание: `<` потому что *не* правильно удалять после всего
    assert!(index < self.len, "index out of bounds");
    unsafe {
        self.len -= 1;
        let result = ptr::read(self.ptr.offset(index as isize));
        ptr::copy(self.ptr.offset(index as isize + 1),
                  self.ptr.offset(index as isize),
                  self.len - index);
        result
    }
}