#![no_std]
pub struct SealingSlice<'s, T: 's> {
slice: &'s mut [T],
index: usize,
}
impl<'s, T> SealingSlice<'s, T> {
pub fn new(slice: &'s mut [T]) -> Self {
SealingSlice { slice, index: 0 }
}
pub fn seal(&mut self, n: usize) {
self.index = self.index.saturating_add(n);
if self.index > self.slice.len() {
panic!("Seal operation exceeds slice length");
}
}
pub fn mutable<'a>(&'a mut self) -> &'a mut [T] {
&mut self.slice[self.index..]
}
pub fn sealed<'a>(&'a self) -> &'s [T] {
unsafe { &*(&self.slice[..self.index] as *const _) }
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn seal_nothing() {
let mut data = [0, 1, 2].to_vec();
let mut s = SealingSlice::new(data.as_mut());
s.seal(0);
assert_eq!(s.mutable(), &[0, 1, 2]);
assert_eq!(s.sealed(), &[]);
}
#[test]
fn seal_all() {
let mut data = [0, 1, 2].to_vec();
let mut s = SealingSlice::new(data.as_mut());
s.seal(3);
assert_eq!(s.mutable(), &[]);
assert_eq!(s.sealed(), &[0, 1, 2]);
}
#[test]
#[should_panic]
fn seal_too_much() {
let mut data = [0, 1, 2].to_vec();
let mut s = SealingSlice::new(data.as_mut());
s.seal(4);
}
#[test]
fn seal_some() {
let mut data = [0, 1, 2].to_vec();
let mut s = SealingSlice::new(data.as_mut());
s.seal(2);
assert_eq!(s.mutable(), &[2]);
assert_eq!(s.sealed(), &[0, 1]);
s.mutable()[0] = 4;
s.seal(1);
assert_eq!(s.sealed(), &[0, 1, 4]);
}
#[test]
fn identical_ptrs() {
let mut data = [0, 1, 2].to_vec();
let dataptr = data.as_ref() as *const _;
let datalen = data.len();
let mut s = SealingSlice::new(data.as_mut());
assert_eq!(s.mutable() as *const _, dataptr);
assert_eq!(s.mutable().len(), datalen);
s.seal(1);
s.seal(2);
assert_eq!(s.sealed() as *const _, dataptr);
assert_eq!(s.sealed().len(), datalen);
}
}