catvec 0.1.6

Persistent, catenable vectors
Documentation
use arbitrary::{Arbitrary, Unstructured};
use catvec::CatVec;

#[cfg(fuzzing)]
fn main() {
    use log::LevelFilter;
    let _ = env_logger::builder()
        .filter_level(LevelFilter::Trace)
        .try_init();
    loop {
        honggfuzz::fuzz!(|data: &[u8]| { test_once(&data) });
    }
}

#[derive(Debug, Arbitrary, Clone)]
enum Op {
    Literal(Vec<u8>),
    Append,
    Insert(usize, u8),
    Slice(usize, usize),
}

fn eval(ops: &[Op]) -> Option<CatVec<u8, 4>> {
    let mut stack: Vec<CatVec<u8, 4>> = Vec::new();
    let mut shadow = Vec::new();
    for op in ops {
        match op {
            Op::Literal(v) => {
                shadow.push(v.clone());
                stack.push(v.into())
            }
            Op::Append => {
                let mut x = stack.pop()?;
                let y = stack.pop()?;
                let mut sx = shadow.pop()?;
                assert_eq!(sx, Vec::from(x.clone()));
                let mut sy = shadow.pop()?;
                assert_eq!(sy, Vec::from(y.clone()));
                eprintln!(
                    "popped {} {:?} and {} {:?} of shadow",
                    sx.len(),
                    sx,
                    sy.len(),
                    sy
                );
                x.append(y);
                x.debug_graphviz();
                x.check_invariants();
                stack.push(x);
                sx.append(&mut sy);
                shadow.push(sx);
            }
            Op::Insert(i, v) => {
                let mut x = stack.pop()?;
                let mut sx = shadow.pop()?;
                let i = *i % (x.len() + 1);
                eprintln!("insert {} to {:?} pos {}", v, sx, i);
                x.debug_graphviz();
                x.insert(i, *v);
                sx.insert(i, *v);
                eprintln!("------------");
                x.debug_graphviz();
                assert_eq!(sx, Vec::from(x.clone()));
                stack.push(x);
                shadow.push(sx);
            }
            Op::Slice(i, j) => {
                let mut x = stack.pop()?;
                let mut sx = shadow.pop()?;
                let i = *i % (x.len() + 1);
                let j = (*j % (x.len() + 1)).max(i);
                dbg!(i, j, x.len());
                x.slice_into(i..j);
                x.check_invariants();
                sx = sx[i..j].to_vec();
                stack.push(x);
                shadow.push(sx);
            }
        }
    }
    stack.pop()
}

fn test_once(data: &[u8]) {
    let data = Vec::<Op>::arbitrary(&mut Unstructured::new(data));
    if let Ok(data) = data {
        eval(&data);
    }
}

#[cfg(not(fuzzing))]
fn main() {}