undoredo 0.8.21

Delta-based undo-redo decorator for collections such as HashMap, BTreeMap, StableVec, thunderdome::Arena, rstar::RTree. No need to implement commands.
Documentation
// SPDX-FileCopyrightText: 2025 undoredo contributors
//
// SPDX-License-Identifier: MIT OR Apache-2.0

use std::collections::BTreeMap;

use thunderdome::Arena;
use undoredo::{Recorder, UndoRedo};

fn main() {
    let mut recorder: Recorder<Arena<char>, BTreeMap<thunderdome::Index, char>> =
        Recorder::new(Arena::new());
    let mut undoredo: UndoRedo<BTreeMap<thunderdome::Index, char>> = UndoRedo::new();

    recorder.push('A');
    undoredo.commit(recorder.flush_delta());

    recorder.push('B');
    recorder.push('B');
    undoredo.commit(recorder.flush_delta());

    let key = recorder.push('X');
    recorder.remove(&key);
    recorder.push('C');
    undoredo.commit(recorder.flush_delta());

    let (_, values): (Vec<_>, Vec<char>) = recorder.collection().clone().into_iter().unzip();
    assert!(values == vec!['A', 'B', 'B', 'C']);

    undoredo.undo(&mut recorder);
    let (_, values): (Vec<_>, Vec<char>) = recorder.collection().clone().into_iter().unzip();
    assert!(values == vec!['A', 'B', 'B']);

    undoredo.undo(&mut recorder);
    let (_, values): (Vec<_>, Vec<char>) = recorder.collection().clone().into_iter().unzip();
    assert!(values == vec!['A']);

    undoredo.redo(&mut recorder);
    let (_, values): (Vec<_>, Vec<char>) = recorder.collection().clone().into_iter().unzip();
    assert!(values == vec!['A', 'B', 'B']);

    undoredo.redo(&mut recorder);
    let (_, values): (Vec<_>, Vec<char>) = recorder.collection().clone().into_iter().unzip();
    assert!(values == vec!['A', 'B', 'B', 'C']);
}

#[test]
fn test() {
    main();
}