nativeshell 0.1.0

NativeShell Rust package
Documentation
#[derive(Debug)]
pub enum DiffResult<T> {
    Remove(T),
    Update(T, T),
    Keep(T, T),
    Insert(T),
}

pub fn update_diff<'a, T: PartialEq, F>(
    old: &'a [T],
    new: &'a [T],
    can_update: F,
) -> Vec<DiffResult<&'a T>>
where
    F: Fn(&T, &T) -> bool,
{
    let mut diff = diff::slice(old, new);
    let mut res = Vec::<DiffResult<&'a T>>::new();
    let mut i = 0;
    while i < diff.len() {
        let cur = &diff[i];
        match cur {
            diff::Result::Left(remove) => {
                let mut next_add = i + 1;
                let mut next_add_value: Option<&T> = None;
                while next_add < diff.len() {
                    match &diff[next_add] {
                        diff::Result::Left(_) => {
                            next_add += 1;
                        }
                        diff::Result::Both(_, _) => {
                            next_add = diff.len();
                        }
                        diff::Result::Right(add) => {
                            next_add_value.replace(add);
                            break;
                        }
                    }
                }
                if next_add < diff.len() && can_update(remove, next_add_value.as_ref().unwrap()) {
                    res.push(DiffResult::Update(remove, next_add_value.as_ref().unwrap()));
                    diff.remove(next_add);
                } else {
                    res.push(DiffResult::Remove(remove));
                }
            }
            diff::Result::Both(same1, same2) => res.push(DiffResult::Keep(same1, same2)),
            diff::Result::Right(added) => res.push(DiffResult::Insert(added)),
        }
        i += 1;
    }
    res
}