Skip to main content

Recorder

Struct Recorder 

Source
pub struct Recorder<C: Container, DC: Container = BTreeMap<<C as Container>::Key, <C as Container>::Value>> { /* private fields */ }
Expand description

Records deltas applied to a container so that they can be replayed or reverted.

Implementations§

Source§

impl<C: Container, DC: Container + Default> Recorder<C, DC>

Source

pub fn new(container: C) -> Self

Create a new recorder recording changes to an owned container.

Examples found in repository?
examples/cmd_commit.rs (line 19)
17fn main() {
18    let mut recorder: Recorder<HashMap<usize, char>, HashMapHalfDelta<usize, char>> =
19        Recorder::new(HashMap::new());
20    let mut undoredo: UndoRedo<HashMapDelta<usize, char>, Command> = UndoRedo::new();
21
22    recorder.insert(1, 'A');
23
24    // Commit `Command::PushChar` enum variant as command metadata ("cmd") along
25    // with the recorded delta.
26    undoredo.cmd_commit(Command::PushChar, &mut recorder);
27
28    // `Command::PushChar` is now the top element of the stack of done cmd-deltas.
29    assert_eq!(undoredo.done().last().unwrap().cmd, Command::PushChar);
30
31    undoredo.undo(&mut recorder);
32
33    // After undo, `Command::PushChar` is now the top element of the stack of
34    // undone cmd-deltas.
35    assert_eq!(undoredo.undone().last().unwrap().cmd, Command::PushChar);
36}
More examples
Hide additional examples
examples/bihashmap.rs (line 16)
9fn main() {
10    let mut map = BiHashMap::new();
11    map.insert("A", 1);
12    map.insert("BB", 2);
13    map.insert("CCC", 3);
14
15    let mut recorder: Recorder<BiHashMap<&str, usize>, BiHashMapHalfDelta<&str, usize>> =
16        Recorder::new(map);
17    let mut undoredo: UndoRedo<BiHashMapDelta<&str, usize>> = UndoRedo::new();
18
19    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
20    assert_eq!(recorder.get_by_right(&2), Some(&"BB"));
21
22    assert_eq!(recorder.remove_by_left(&"A"), Some(1));
23    assert_eq!(recorder.remove_by_right(&3), Some("CCC"));
24    undoredo.commit(&mut recorder);
25
26    assert_eq!(recorder.get_by_left(&"A"), None);
27    assert_eq!(recorder.get_by_right(&3), None);
28
29    undoredo.undo(&mut recorder);
30    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
31    assert_eq!(recorder.get_by_left(&"CCC"), Some(&3));
32
33    undoredo.redo(&mut recorder);
34    assert_eq!(recorder.get_by_left(&"A"), None);
35    assert_eq!(recorder.get_by_right(&3), None);
36}
examples/btreeset.rs (line 12)
10fn main() {
11    let mut recorder: Recorder<BTreeSet<char>, BTreeSetHalfDelta<char>> =
12        Recorder::new(BTreeSet::new());
13    let mut undoredo: UndoRedo<BTreeSetDelta<char>> = UndoRedo::new();
14
15    recorder.insert('A', ());
16    undoredo.commit(&mut recorder);
17
18    recorder.insert('B', ());
19    // Inserting to a set is idempotent: repeating the same insert does nothing.
20    // It is, however, a logic error if the recorded container is a multiset,
21    // e.g. `rstar::RTree`.
22    recorder.insert('B', ());
23    undoredo.commit(&mut recorder);
24
25    recorder.insert('C', ());
26    undoredo.commit(&mut recorder);
27
28    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B', 'C']));
29
30    undoredo.undo(&mut recorder);
31    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B']));
32
33    undoredo.undo(&mut recorder);
34    assert_eq!(*recorder.container(), BTreeSet::from(['A']));
35
36    undoredo.redo(&mut recorder);
37    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B']));
38
39    undoredo.redo(&mut recorder);
40    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B', 'C']));
41}
examples/stable_vec.rs (line 11)
9fn main() {
10    let mut recorder: Recorder<StableVec<char>, StableVecHalfDelta<char>> =
11        Recorder::new(StableVec::new());
12    let mut undoredo: UndoRedo<StableVecDelta<char>> = UndoRedo::new();
13
14    recorder.push('A');
15    undoredo.commit(&mut recorder);
16
17    recorder.push('B');
18    recorder.push('B');
19    undoredo.commit(&mut recorder);
20
21    let key = recorder.push('X');
22    recorder.remove(&key);
23    recorder.push('C');
24    undoredo.commit(&mut recorder);
25
26    assert!(
27        recorder
28            .container()
29            .values()
30            .copied()
31            .eq(['A', 'B', 'B', 'C'])
32    );
33
34    undoredo.undo(&mut recorder);
35    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
36
37    undoredo.undo(&mut recorder);
38    assert!(recorder.container().values().copied().eq(['A']));
39
40    undoredo.redo(&mut recorder);
41    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
42
43    undoredo.redo(&mut recorder);
44    assert!(
45        recorder
46            .container()
47            .values()
48            .copied()
49            .eq(['A', 'B', 'B', 'C'])
50    );
51}
examples/thunderdome.rs (line 10)
9fn main() {
10    let mut recorder: Recorder<Arena<char>, ArenaHalfDelta<char>> = Recorder::new(Arena::new());
11    let mut undoredo: UndoRedo<ArenaDelta<char>> = UndoRedo::new();
12
13    recorder.push('A');
14    undoredo.commit(&mut recorder);
15
16    recorder.push('B');
17    recorder.push('B');
18    undoredo.commit(&mut recorder);
19
20    let key = recorder.push('X');
21    recorder.remove(&key);
22    recorder.push('C');
23    undoredo.commit(&mut recorder);
24
25    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
26    assert!(values == vec!['A', 'B', 'B', 'C']);
27
28    undoredo.undo(&mut recorder);
29    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
30    assert!(values == vec!['A', 'B', 'B']);
31
32    undoredo.undo(&mut recorder);
33    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
34    assert!(values == vec!['A']);
35
36    undoredo.redo(&mut recorder);
37    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
38    assert!(values == vec!['A', 'B', 'B']);
39
40    undoredo.redo(&mut recorder);
41    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
42    assert!(values == vec!['A', 'B', 'B', 'C']);
43}
examples/rstar.rs (line 11)
9fn main() {
10    let mut recorder: Recorder<RTree<(i32, i32)>, RTreeHalfDelta<(i32, i32)>> =
11        Recorder::new(RTree::new());
12    let mut undoredo: UndoRedo<RTreeDelta<(i32, i32)>> = UndoRedo::new();
13
14    recorder.insert((1, 1), ());
15    undoredo.commit(&mut recorder);
16
17    recorder.insert((2, 2), ());
18    undoredo.commit(&mut recorder);
19
20    recorder.insert((3, 3), ());
21    undoredo.commit(&mut recorder);
22
23    assert_eq!(
24        recorder.container().iter().collect::<Vec<_>>(),
25        RTree::bulk_load(vec![(1, 1), (2, 2), (3, 3)])
26            .iter()
27            .collect::<Vec<_>>()
28    );
29
30    undoredo.undo(&mut recorder);
31    assert_eq!(
32        *recorder.container().iter().collect::<Vec<_>>(),
33        RTree::bulk_load(vec![(1, 1), (2, 2)])
34            .iter()
35            .collect::<Vec<_>>()
36    );
37
38    undoredo.undo(&mut recorder);
39    assert_eq!(
40        *recorder.container().iter().collect::<Vec<_>>(),
41        RTree::bulk_load(vec![(1, 1)]).iter().collect::<Vec<_>>()
42    );
43
44    undoredo.redo(&mut recorder);
45    assert_eq!(
46        *recorder.container().iter().collect::<Vec<_>>(),
47        RTree::bulk_load(vec![(1, 1), (2, 2)])
48            .iter()
49            .collect::<Vec<_>>()
50    );
51
52    undoredo.redo(&mut recorder);
53    assert_eq!(
54        *recorder.container().iter().collect::<Vec<_>>(),
55        RTree::bulk_load(vec![(1, 1), (2, 2), (3, 3)])
56            .iter()
57            .collect::<Vec<_>>()
58    );
59}
Source§

impl<C: Container, DC: Container> Recorder<C, DC>

Source

pub fn with_delta(container: C, delta: Delta<DC>) -> Self

Create a new recorder recording changes to an owned container, storing them in an already existing delta.

Source

pub fn container(&self) -> &C

Returns a reference to the recorded container.

Examples found in repository?
examples/entities.rs (line 71)
70    pub fn update(&mut self) {
71        self.turn_counter.assign(*self.turn_counter.container() + 1);
72
73        for i in 0..self.positions.container().len() {
74            self.update_entity(i);
75        }
76    }
77
78    fn update_entity(&mut self, index: usize) {
79        // Add velocities to positions on every update.
80
81        let velocity = self.velocities[index];
82        self.positions
83            .modify(index, |position| *position += velocity);
84
85        // Alternatively, you could update them more verbosely this way:
86
87        /*self.positions
88        .set(index, self.positions[index] + self.velocities[index]);*/
89
90        // Decrease health by 1 on every update.
91        self.healths.set(index, self.healths[index] - 1);
92    }
93}
94
95fn assert_entity(entities: &Entities<f64>, index: usize, pos: Vector2<f64>, health: i64) {
96    assert_eq!(entities.positions[index], pos);
97    assert_eq!(entities.healths[index], health);
98}
99
100fn main() {
101    let mut entities = Entities::<f64> {
102        positions: Recorder::new(Vec::new()),
103        velocities: Recorder::new(Vec::new()),
104        healths: Recorder::new(Vec::new()),
105        turn_counter: Recorder::new(0),
106        not_in_delta: "not_in_delta".to_string(),
107    };
108
109    // `EntitiesDelta` was generated by `#[derive(Delta)]` on `Entities`.
110    let mut undoredo: UndoRedo<EntitiesDelta<f64>> = UndoRedo::new();
111
112    entities.new_entity(Vector2 { x: 0.0, y: 0.0 }, Vector2 { x: 1.0, y: 0.0 }, 100);
113    entities.new_entity(Vector2 { x: 0.0, y: 0.0 }, Vector2 { x: 0.0, y: 2.0 }, 100);
114    undoredo.commit(&mut entities);
115
116    entities.new_entity(
117        Vector2 { x: 100.0, y: 100.0 },
118        Vector2 { x: -1.0, y: -1.0 },
119        50,
120    );
121    undoredo.commit(&mut entities);
122
123    assert_eq!(entities.positions.container().len(), 3);
124
125    // Perform three simulation updates, committing after each tick.
126    for _ in 0..3 {
127        entities.update();
128        undoredo.commit(&mut entities);
129    }
130
131    // Perform five more simulation updates, this time committing only once afterwards.
132    for _ in 0..5 {
133        entities.update();
134    }
135    undoredo.commit(&mut entities);
136
137    assert!(entities.positions.container().len() == 3);
138    assert_entity(&entities, 0, Vector2 { x: 8.0, y: 0.0 }, 92);
139    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 16.0 }, 92);
140    assert_entity(&entities, 2, Vector2 { x: 92.0, y: 92.0 }, 42);
141    assert_eq!(*entities.turn_counter.container(), 8);
142
143    undoredo.undo(&mut entities);
144
145    assert!(entities.positions.container().len() == 3);
146    assert_entity(&entities, 0, Vector2 { x: 3.0, y: 0.0 }, 97);
147    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 6.0 }, 97);
148    assert_entity(&entities, 2, Vector2 { x: 97.0, y: 97.0 }, 47);
149    assert_eq!(*entities.turn_counter.container(), 3);
150
151    undoredo.undo(&mut entities);
152
153    assert!(entities.positions.container().len() == 3);
154    assert_entity(&entities, 0, Vector2 { x: 2.0, y: 0.0 }, 98);
155    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 4.0 }, 98);
156    assert_entity(&entities, 2, Vector2 { x: 98.0, y: 98.0 }, 48);
157
158    undoredo.undo(&mut entities);
159
160    assert!(entities.positions.container().len() == 3);
161    assert_entity(&entities, 0, Vector2 { x: 1.0, y: 0.0 }, 99);
162    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 2.0 }, 99);
163    assert_entity(&entities, 2, Vector2 { x: 99.0, y: 99.0 }, 49);
164
165    undoredo.undo(&mut entities);
166
167    assert!(entities.positions.container().len() == 3);
168    assert_entity(&entities, 0, Vector2 { x: 0.0, y: 0.0 }, 100);
169    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 0.0 }, 100);
170    assert_entity(&entities, 2, Vector2 { x: 100.0, y: 100.0 }, 50);
171    assert_eq!(*entities.turn_counter.container(), 0);
172
173    undoredo.undo(&mut entities);
174
175    assert!(entities.positions.container().len() == 2);
176    assert_entity(&entities, 0, Vector2 { x: 0.0, y: 0.0 }, 100);
177    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 0.0 }, 100);
178
179    undoredo.redo(&mut entities);
180
181    assert!(entities.positions.container().len() == 3);
182    assert_entity(&entities, 0, Vector2 { x: 0.0, y: 0.0 }, 100);
183    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 0.0 }, 100);
184    assert_entity(&entities, 2, Vector2 { x: 100.0, y: 100.0 }, 50);
185
186    undoredo.redo(&mut entities);
187
188    assert_entity(&entities, 0, Vector2 { x: 1.0, y: 0.0 }, 99);
189    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 2.0 }, 99);
190    assert_entity(&entities, 2, Vector2 { x: 99.0, y: 99.0 }, 49);
191
192    undoredo.redo(&mut entities);
193
194    assert_entity(&entities, 0, Vector2 { x: 2.0, y: 0.0 }, 98);
195    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 4.0 }, 98);
196    assert_entity(&entities, 2, Vector2 { x: 98.0, y: 98.0 }, 48);
197
198    undoredo.redo(&mut entities);
199
200    assert_entity(&entities, 0, Vector2 { x: 3.0, y: 0.0 }, 97);
201    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 6.0 }, 97);
202    assert_entity(&entities, 2, Vector2 { x: 97.0, y: 97.0 }, 47);
203
204    undoredo.redo(&mut entities);
205
206    assert!(entities.positions.container().len() == 3);
207    assert_entity(&entities, 0, Vector2 { x: 8.0, y: 0.0 }, 92);
208    assert_entity(&entities, 1, Vector2 { x: 0.0, y: 16.0 }, 92);
209    assert_entity(&entities, 2, Vector2 { x: 92.0, y: 92.0 }, 42);
210    assert_eq!(*entities.turn_counter.container(), 8);
211}
More examples
Hide additional examples
examples/btreeset.rs (line 28)
10fn main() {
11    let mut recorder: Recorder<BTreeSet<char>, BTreeSetHalfDelta<char>> =
12        Recorder::new(BTreeSet::new());
13    let mut undoredo: UndoRedo<BTreeSetDelta<char>> = UndoRedo::new();
14
15    recorder.insert('A', ());
16    undoredo.commit(&mut recorder);
17
18    recorder.insert('B', ());
19    // Inserting to a set is idempotent: repeating the same insert does nothing.
20    // It is, however, a logic error if the recorded container is a multiset,
21    // e.g. `rstar::RTree`.
22    recorder.insert('B', ());
23    undoredo.commit(&mut recorder);
24
25    recorder.insert('C', ());
26    undoredo.commit(&mut recorder);
27
28    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B', 'C']));
29
30    undoredo.undo(&mut recorder);
31    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B']));
32
33    undoredo.undo(&mut recorder);
34    assert_eq!(*recorder.container(), BTreeSet::from(['A']));
35
36    undoredo.redo(&mut recorder);
37    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B']));
38
39    undoredo.redo(&mut recorder);
40    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B', 'C']));
41}
examples/stable_vec.rs (line 28)
9fn main() {
10    let mut recorder: Recorder<StableVec<char>, StableVecHalfDelta<char>> =
11        Recorder::new(StableVec::new());
12    let mut undoredo: UndoRedo<StableVecDelta<char>> = UndoRedo::new();
13
14    recorder.push('A');
15    undoredo.commit(&mut recorder);
16
17    recorder.push('B');
18    recorder.push('B');
19    undoredo.commit(&mut recorder);
20
21    let key = recorder.push('X');
22    recorder.remove(&key);
23    recorder.push('C');
24    undoredo.commit(&mut recorder);
25
26    assert!(
27        recorder
28            .container()
29            .values()
30            .copied()
31            .eq(['A', 'B', 'B', 'C'])
32    );
33
34    undoredo.undo(&mut recorder);
35    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
36
37    undoredo.undo(&mut recorder);
38    assert!(recorder.container().values().copied().eq(['A']));
39
40    undoredo.redo(&mut recorder);
41    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
42
43    undoredo.redo(&mut recorder);
44    assert!(
45        recorder
46            .container()
47            .values()
48            .copied()
49            .eq(['A', 'B', 'B', 'C'])
50    );
51}
examples/thunderdome.rs (line 25)
9fn main() {
10    let mut recorder: Recorder<Arena<char>, ArenaHalfDelta<char>> = Recorder::new(Arena::new());
11    let mut undoredo: UndoRedo<ArenaDelta<char>> = UndoRedo::new();
12
13    recorder.push('A');
14    undoredo.commit(&mut recorder);
15
16    recorder.push('B');
17    recorder.push('B');
18    undoredo.commit(&mut recorder);
19
20    let key = recorder.push('X');
21    recorder.remove(&key);
22    recorder.push('C');
23    undoredo.commit(&mut recorder);
24
25    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
26    assert!(values == vec!['A', 'B', 'B', 'C']);
27
28    undoredo.undo(&mut recorder);
29    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
30    assert!(values == vec!['A', 'B', 'B']);
31
32    undoredo.undo(&mut recorder);
33    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
34    assert!(values == vec!['A']);
35
36    undoredo.redo(&mut recorder);
37    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
38    assert!(values == vec!['A', 'B', 'B']);
39
40    undoredo.redo(&mut recorder);
41    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
42    assert!(values == vec!['A', 'B', 'B', 'C']);
43}
examples/rstar.rs (line 24)
9fn main() {
10    let mut recorder: Recorder<RTree<(i32, i32)>, RTreeHalfDelta<(i32, i32)>> =
11        Recorder::new(RTree::new());
12    let mut undoredo: UndoRedo<RTreeDelta<(i32, i32)>> = UndoRedo::new();
13
14    recorder.insert((1, 1), ());
15    undoredo.commit(&mut recorder);
16
17    recorder.insert((2, 2), ());
18    undoredo.commit(&mut recorder);
19
20    recorder.insert((3, 3), ());
21    undoredo.commit(&mut recorder);
22
23    assert_eq!(
24        recorder.container().iter().collect::<Vec<_>>(),
25        RTree::bulk_load(vec![(1, 1), (2, 2), (3, 3)])
26            .iter()
27            .collect::<Vec<_>>()
28    );
29
30    undoredo.undo(&mut recorder);
31    assert_eq!(
32        *recorder.container().iter().collect::<Vec<_>>(),
33        RTree::bulk_load(vec![(1, 1), (2, 2)])
34            .iter()
35            .collect::<Vec<_>>()
36    );
37
38    undoredo.undo(&mut recorder);
39    assert_eq!(
40        *recorder.container().iter().collect::<Vec<_>>(),
41        RTree::bulk_load(vec![(1, 1)]).iter().collect::<Vec<_>>()
42    );
43
44    undoredo.redo(&mut recorder);
45    assert_eq!(
46        *recorder.container().iter().collect::<Vec<_>>(),
47        RTree::bulk_load(vec![(1, 1), (2, 2)])
48            .iter()
49            .collect::<Vec<_>>()
50    );
51
52    undoredo.redo(&mut recorder);
53    assert_eq!(
54        *recorder.container().iter().collect::<Vec<_>>(),
55        RTree::bulk_load(vec![(1, 1), (2, 2), (3, 3)])
56            .iter()
57            .collect::<Vec<_>>()
58    );
59}
examples/basic_usage.rs (line 28)
9fn main() {
10    // The recorder records the ongoing changes to the recorded container.
11    //
12    // For some containers such as `HashMap` and `HashSet`, you need
13    // to explicitly pass a half-delta type to the `Recorder` (here
14    // `HashMapHalfDelta`). For most containers, however, you don't need to do
15    // that because their half-delta is already the default, `BTreeMap`.
16    let mut recorder: Recorder<HashMap<usize, char>, HashMapHalfDelta<usize, char>> =
17        Recorder::new(HashMap::new());
18
19    // The undo-redo struct that holds and maintains the undo-redo bistack.
20    let mut undoredo: UndoRedo<HashMapDelta<usize, char>> = UndoRedo::new();
21
22    // Push elements while recording the changes in a delta.
23    recorder.insert(1, 'A');
24    recorder.insert(2, 'B');
25    recorder.insert(3, 'C');
26
27    // The pushed elements are now present in the container.
28    assert!(*recorder.container() == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
29
30    // Flush the recorder and commit the recorded delta of pushing 'A', 'B', 'C'
31    // into the undo-redo bistack.
32    undoredo.commit(&mut recorder);
33
34    // Now undo the action.
35    undoredo.undo(&mut recorder);
36
37    // The container is now empty; the action of pushing elements has been undone.
38    assert!(*recorder.container() == HashMap::from([]));
39
40    // Now redo the action.
41    undoredo.redo(&mut recorder);
42
43    // The elements are back in the container; the action has been redone.
44    assert!(*recorder.container() == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
45
46    // Once you are done recording, you can dissolve the recorder to regain
47    // ownership and mutability over the recorded container.
48    let (hashmap, ..) = recorder.dissolve();
49    assert!(hashmap == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
50}
Source

pub fn dissolve(self) -> (C, Delta<DC>)

Dissolve the recorder, returning and ceding ownership of its recorded container and delta.

Examples found in repository?
examples/basic_usage.rs (line 48)
9fn main() {
10    // The recorder records the ongoing changes to the recorded container.
11    //
12    // For some containers such as `HashMap` and `HashSet`, you need
13    // to explicitly pass a half-delta type to the `Recorder` (here
14    // `HashMapHalfDelta`). For most containers, however, you don't need to do
15    // that because their half-delta is already the default, `BTreeMap`.
16    let mut recorder: Recorder<HashMap<usize, char>, HashMapHalfDelta<usize, char>> =
17        Recorder::new(HashMap::new());
18
19    // The undo-redo struct that holds and maintains the undo-redo bistack.
20    let mut undoredo: UndoRedo<HashMapDelta<usize, char>> = UndoRedo::new();
21
22    // Push elements while recording the changes in a delta.
23    recorder.insert(1, 'A');
24    recorder.insert(2, 'B');
25    recorder.insert(3, 'C');
26
27    // The pushed elements are now present in the container.
28    assert!(*recorder.container() == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
29
30    // Flush the recorder and commit the recorded delta of pushing 'A', 'B', 'C'
31    // into the undo-redo bistack.
32    undoredo.commit(&mut recorder);
33
34    // Now undo the action.
35    undoredo.undo(&mut recorder);
36
37    // The container is now empty; the action of pushing elements has been undone.
38    assert!(*recorder.container() == HashMap::from([]));
39
40    // Now redo the action.
41    undoredo.redo(&mut recorder);
42
43    // The elements are back in the container; the action has been redone.
44    assert!(*recorder.container() == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
45
46    // Once you are done recording, you can dissolve the recorder to regain
47    // ownership and mutability over the recorded container.
48    let (hashmap, ..) = recorder.dissolve();
49    assert!(hashmap == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
50}
Source§

impl<C, DC> Recorder<C, DC>
where C: Assign + Clone, DC: Get<usize, Value = C> + Set<usize>,

Source

pub fn assign(&mut self, value: C)

Assign a new value to *self.

Examples found in repository?
examples/entities.rs (line 71)
70    pub fn update(&mut self) {
71        self.turn_counter.assign(*self.turn_counter.container() + 1);
72
73        for i in 0..self.positions.container().len() {
74            self.update_entity(i);
75        }
76    }
Source§

impl<K, C, DC> Recorder<C, DC>
where C: Get<K, Key = K>, DC: Container,

Source

pub fn get(&self, key: &K) -> Option<&C::Value>

Returns a reference to the value corresponding to the key.

Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + GetByLeft<K>, DC: Container,

Source

pub fn get_by_left(&self, key: &K) -> Option<&V>

Returns a reference to the right value corresponding to the given left value in a bidirectional map.

Examples found in repository?
examples/bihashmap.rs (line 19)
9fn main() {
10    let mut map = BiHashMap::new();
11    map.insert("A", 1);
12    map.insert("BB", 2);
13    map.insert("CCC", 3);
14
15    let mut recorder: Recorder<BiHashMap<&str, usize>, BiHashMapHalfDelta<&str, usize>> =
16        Recorder::new(map);
17    let mut undoredo: UndoRedo<BiHashMapDelta<&str, usize>> = UndoRedo::new();
18
19    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
20    assert_eq!(recorder.get_by_right(&2), Some(&"BB"));
21
22    assert_eq!(recorder.remove_by_left(&"A"), Some(1));
23    assert_eq!(recorder.remove_by_right(&3), Some("CCC"));
24    undoredo.commit(&mut recorder);
25
26    assert_eq!(recorder.get_by_left(&"A"), None);
27    assert_eq!(recorder.get_by_right(&3), None);
28
29    undoredo.undo(&mut recorder);
30    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
31    assert_eq!(recorder.get_by_left(&"CCC"), Some(&3));
32
33    undoredo.redo(&mut recorder);
34    assert_eq!(recorder.get_by_left(&"A"), None);
35    assert_eq!(recorder.get_by_right(&3), None);
36}
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + GetByRight<K>, DC: Container,

Source

pub fn get_by_right(&self, key: &V) -> Option<&K>

Returns a reference to the left value corresponding to the given right value in a bidirectional map.

Examples found in repository?
examples/bihashmap.rs (line 20)
9fn main() {
10    let mut map = BiHashMap::new();
11    map.insert("A", 1);
12    map.insert("BB", 2);
13    map.insert("CCC", 3);
14
15    let mut recorder: Recorder<BiHashMap<&str, usize>, BiHashMapHalfDelta<&str, usize>> =
16        Recorder::new(map);
17    let mut undoredo: UndoRedo<BiHashMapDelta<&str, usize>> = UndoRedo::new();
18
19    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
20    assert_eq!(recorder.get_by_right(&2), Some(&"BB"));
21
22    assert_eq!(recorder.remove_by_left(&"A"), Some(1));
23    assert_eq!(recorder.remove_by_right(&3), Some("CCC"));
24    undoredo.commit(&mut recorder);
25
26    assert_eq!(recorder.get_by_left(&"A"), None);
27    assert_eq!(recorder.get_by_right(&3), None);
28
29    undoredo.undo(&mut recorder);
30    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
31    assert_eq!(recorder.get_by_left(&"CCC"), Some(&3));
32
33    undoredo.redo(&mut recorder);
34    assert_eq!(recorder.get_by_left(&"A"), None);
35    assert_eq!(recorder.get_by_right(&3), None);
36}
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + Get<K> + Set<K>, DC: Container<Key = K, Value = V> + Get<K> + Insert<K>, K: Clone, V: Clone,

Source

pub fn set(&mut self, key: K, value: V) -> <C as Set<K>>::Output

Set the value of an already existing element under a key.

Examples found in repository?
examples/entities.rs (line 91)
78    fn update_entity(&mut self, index: usize) {
79        // Add velocities to positions on every update.
80
81        let velocity = self.velocities[index];
82        self.positions
83            .modify(index, |position| *position += velocity);
84
85        // Alternatively, you could update them more verbosely this way:
86
87        /*self.positions
88        .set(index, self.positions[index] + self.velocities[index]);*/
89
90        // Decrease health by 1 on every update.
91        self.healths.set(index, self.healths[index] - 1);
92    }
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + Get<K> + Modify<K>, DC: Container<Key = K, Value = V> + Get<K> + Insert<K>, K: Clone, V: Clone,

Source

pub fn modify<F>(&mut self, key: K, f: F)
where F: FnOnce(&mut V),

Modify the value under key with a closure.

Examples found in repository?
examples/entities.rs (line 83)
78    fn update_entity(&mut self, index: usize) {
79        // Add velocities to positions on every update.
80
81        let velocity = self.velocities[index];
82        self.positions
83            .modify(index, |position| *position += velocity);
84
85        // Alternatively, you could update them more verbosely this way:
86
87        /*self.positions
88        .set(index, self.positions[index] + self.velocities[index]);*/
89
90        // Decrease health by 1 on every update.
91        self.healths.set(index, self.healths[index] - 1);
92    }
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + Get<K> + Insert<K>, DC: Container<Key = K, Value = V> + Get<K> + Insert<K>, K: Clone, V: Clone,

Source

pub fn insert(&mut self, key: K, value: V) -> <C as Insert<K>>::Output

Insert a key-value pair into the container.

Examples found in repository?
examples/cmd_commit.rs (line 22)
17fn main() {
18    let mut recorder: Recorder<HashMap<usize, char>, HashMapHalfDelta<usize, char>> =
19        Recorder::new(HashMap::new());
20    let mut undoredo: UndoRedo<HashMapDelta<usize, char>, Command> = UndoRedo::new();
21
22    recorder.insert(1, 'A');
23
24    // Commit `Command::PushChar` enum variant as command metadata ("cmd") along
25    // with the recorded delta.
26    undoredo.cmd_commit(Command::PushChar, &mut recorder);
27
28    // `Command::PushChar` is now the top element of the stack of done cmd-deltas.
29    assert_eq!(undoredo.done().last().unwrap().cmd, Command::PushChar);
30
31    undoredo.undo(&mut recorder);
32
33    // After undo, `Command::PushChar` is now the top element of the stack of
34    // undone cmd-deltas.
35    assert_eq!(undoredo.undone().last().unwrap().cmd, Command::PushChar);
36}
More examples
Hide additional examples
examples/btreeset.rs (line 15)
10fn main() {
11    let mut recorder: Recorder<BTreeSet<char>, BTreeSetHalfDelta<char>> =
12        Recorder::new(BTreeSet::new());
13    let mut undoredo: UndoRedo<BTreeSetDelta<char>> = UndoRedo::new();
14
15    recorder.insert('A', ());
16    undoredo.commit(&mut recorder);
17
18    recorder.insert('B', ());
19    // Inserting to a set is idempotent: repeating the same insert does nothing.
20    // It is, however, a logic error if the recorded container is a multiset,
21    // e.g. `rstar::RTree`.
22    recorder.insert('B', ());
23    undoredo.commit(&mut recorder);
24
25    recorder.insert('C', ());
26    undoredo.commit(&mut recorder);
27
28    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B', 'C']));
29
30    undoredo.undo(&mut recorder);
31    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B']));
32
33    undoredo.undo(&mut recorder);
34    assert_eq!(*recorder.container(), BTreeSet::from(['A']));
35
36    undoredo.redo(&mut recorder);
37    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B']));
38
39    undoredo.redo(&mut recorder);
40    assert_eq!(*recorder.container(), BTreeSet::from(['A', 'B', 'C']));
41}
examples/rstar.rs (line 14)
9fn main() {
10    let mut recorder: Recorder<RTree<(i32, i32)>, RTreeHalfDelta<(i32, i32)>> =
11        Recorder::new(RTree::new());
12    let mut undoredo: UndoRedo<RTreeDelta<(i32, i32)>> = UndoRedo::new();
13
14    recorder.insert((1, 1), ());
15    undoredo.commit(&mut recorder);
16
17    recorder.insert((2, 2), ());
18    undoredo.commit(&mut recorder);
19
20    recorder.insert((3, 3), ());
21    undoredo.commit(&mut recorder);
22
23    assert_eq!(
24        recorder.container().iter().collect::<Vec<_>>(),
25        RTree::bulk_load(vec![(1, 1), (2, 2), (3, 3)])
26            .iter()
27            .collect::<Vec<_>>()
28    );
29
30    undoredo.undo(&mut recorder);
31    assert_eq!(
32        *recorder.container().iter().collect::<Vec<_>>(),
33        RTree::bulk_load(vec![(1, 1), (2, 2)])
34            .iter()
35            .collect::<Vec<_>>()
36    );
37
38    undoredo.undo(&mut recorder);
39    assert_eq!(
40        *recorder.container().iter().collect::<Vec<_>>(),
41        RTree::bulk_load(vec![(1, 1)]).iter().collect::<Vec<_>>()
42    );
43
44    undoredo.redo(&mut recorder);
45    assert_eq!(
46        *recorder.container().iter().collect::<Vec<_>>(),
47        RTree::bulk_load(vec![(1, 1), (2, 2)])
48            .iter()
49            .collect::<Vec<_>>()
50    );
51
52    undoredo.redo(&mut recorder);
53    assert_eq!(
54        *recorder.container().iter().collect::<Vec<_>>(),
55        RTree::bulk_load(vec![(1, 1), (2, 2), (3, 3)])
56            .iter()
57            .collect::<Vec<_>>()
58    );
59}
examples/basic_usage.rs (line 23)
9fn main() {
10    // The recorder records the ongoing changes to the recorded container.
11    //
12    // For some containers such as `HashMap` and `HashSet`, you need
13    // to explicitly pass a half-delta type to the `Recorder` (here
14    // `HashMapHalfDelta`). For most containers, however, you don't need to do
15    // that because their half-delta is already the default, `BTreeMap`.
16    let mut recorder: Recorder<HashMap<usize, char>, HashMapHalfDelta<usize, char>> =
17        Recorder::new(HashMap::new());
18
19    // The undo-redo struct that holds and maintains the undo-redo bistack.
20    let mut undoredo: UndoRedo<HashMapDelta<usize, char>> = UndoRedo::new();
21
22    // Push elements while recording the changes in a delta.
23    recorder.insert(1, 'A');
24    recorder.insert(2, 'B');
25    recorder.insert(3, 'C');
26
27    // The pushed elements are now present in the container.
28    assert!(*recorder.container() == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
29
30    // Flush the recorder and commit the recorded delta of pushing 'A', 'B', 'C'
31    // into the undo-redo bistack.
32    undoredo.commit(&mut recorder);
33
34    // Now undo the action.
35    undoredo.undo(&mut recorder);
36
37    // The container is now empty; the action of pushing elements has been undone.
38    assert!(*recorder.container() == HashMap::from([]));
39
40    // Now redo the action.
41    undoredo.redo(&mut recorder);
42
43    // The elements are back in the container; the action has been redone.
44    assert!(*recorder.container() == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
45
46    // Once you are done recording, you can dissolve the recorder to regain
47    // ownership and mutability over the recorded container.
48    let (hashmap, ..) = recorder.dissolve();
49    assert!(hashmap == HashMap::from([(1, 'A'), (2, 'B'), (3, 'C')]));
50}
examples/rstared.rs (line 23)
12fn main() {
13    // A hashmap of 2D rectangles will be the underlying container.
14    let rect_hashmap: HashMap<i32, Rectangle<(i32, i32)>> = HashMap::new();
15    // Wrap `RTreed` around the hashmap and then `Recorder` around it.
16    let mut recorder = Recorder::<
17        RTreed<HashMap<i32, Rectangle<(i32, i32)>>>,
18        RTreedHalfDelta<i32, Rectangle<(i32, i32)>>,
19    >::new(RTreed::new(rect_hashmap));
20    let mut undoredo: UndoRedo<RTreedDelta<i32, Rectangle<(i32, i32)>>> = UndoRedo::new();
21
22    // Insert two rectangles, recording them in the R-tree.
23    recorder.insert(1, Rectangle::from_corners((0, 0), (1, 1)));
24    undoredo.commit(&mut recorder);
25
26    recorder.insert(2, Rectangle::from_corners((1, 1), (2, 2)));
27    undoredo.commit(&mut recorder);
28
29    // Locate the two rectangles in the R-tree.
30    assert_eq!(
31        recorder
32            .container()
33            .rtree()
34            .locate_in_envelope(&AABB::from_corners((0, 0), (2, 2)))
35            .count(),
36        2
37    );
38
39    undoredo.undo(&mut recorder);
40
41    // After undo, there is now only one rectangle.
42    assert_eq!(
43        recorder
44            .container()
45            .rtree()
46            .locate_in_envelope(&AABB::from_corners((0, 0), (2, 2)))
47            .count(),
48        1
49    );
50
51    undoredo.undo(&mut recorder);
52
53    // After another undo, there is no rectangles anymore.
54    assert_eq!(
55        recorder
56            .container()
57            .rtree()
58            .locate_in_envelope(&AABB::from_corners((0, 0), (2, 2)))
59            .count(),
60        0
61    );
62
63    undoredo.redo(&mut recorder);
64
65    // After redo, we are back to one rectangle.
66    assert_eq!(
67        recorder
68            .container()
69            .rtree()
70            .locate_in_envelope(&AABB::from_corners((0, 0), (2, 2)))
71            .count(),
72        1
73    );
74
75    undoredo.redo(&mut recorder);
76
77    // After another redo, we are back to two rectangles.
78    assert_eq!(
79        recorder
80            .container()
81            .rtree()
82            .locate_in_envelope(&AABB::from_corners((0, 0), (2, 2)))
83            .count(),
84        2
85    );
86}
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + Remove<K>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source

pub fn remove(&mut self, key: &K) -> Option<V>

Remove an element under a key from the container, returning the value at the key if the key was previously in the map.

Examples found in repository?
examples/stable_vec.rs (line 22)
9fn main() {
10    let mut recorder: Recorder<StableVec<char>, StableVecHalfDelta<char>> =
11        Recorder::new(StableVec::new());
12    let mut undoredo: UndoRedo<StableVecDelta<char>> = UndoRedo::new();
13
14    recorder.push('A');
15    undoredo.commit(&mut recorder);
16
17    recorder.push('B');
18    recorder.push('B');
19    undoredo.commit(&mut recorder);
20
21    let key = recorder.push('X');
22    recorder.remove(&key);
23    recorder.push('C');
24    undoredo.commit(&mut recorder);
25
26    assert!(
27        recorder
28            .container()
29            .values()
30            .copied()
31            .eq(['A', 'B', 'B', 'C'])
32    );
33
34    undoredo.undo(&mut recorder);
35    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
36
37    undoredo.undo(&mut recorder);
38    assert!(recorder.container().values().copied().eq(['A']));
39
40    undoredo.redo(&mut recorder);
41    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
42
43    undoredo.redo(&mut recorder);
44    assert!(
45        recorder
46            .container()
47            .values()
48            .copied()
49            .eq(['A', 'B', 'B', 'C'])
50    );
51}
More examples
Hide additional examples
examples/thunderdome.rs (line 21)
9fn main() {
10    let mut recorder: Recorder<Arena<char>, ArenaHalfDelta<char>> = Recorder::new(Arena::new());
11    let mut undoredo: UndoRedo<ArenaDelta<char>> = UndoRedo::new();
12
13    recorder.push('A');
14    undoredo.commit(&mut recorder);
15
16    recorder.push('B');
17    recorder.push('B');
18    undoredo.commit(&mut recorder);
19
20    let key = recorder.push('X');
21    recorder.remove(&key);
22    recorder.push('C');
23    undoredo.commit(&mut recorder);
24
25    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
26    assert!(values == vec!['A', 'B', 'B', 'C']);
27
28    undoredo.undo(&mut recorder);
29    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
30    assert!(values == vec!['A', 'B', 'B']);
31
32    undoredo.undo(&mut recorder);
33    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
34    assert!(values == vec!['A']);
35
36    undoredo.redo(&mut recorder);
37    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
38    assert!(values == vec!['A', 'B', 'B']);
39
40    undoredo.redo(&mut recorder);
41    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
42    assert!(values == vec!['A', 'B', 'B', 'C']);
43}
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + RemoveByLeft<K>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source

pub fn remove_by_left(&mut self, key: &K) -> Option<V>

Remove the left and right values from pair corresponding to the given left value in a bidirectional map.

Examples found in repository?
examples/bihashmap.rs (line 22)
9fn main() {
10    let mut map = BiHashMap::new();
11    map.insert("A", 1);
12    map.insert("BB", 2);
13    map.insert("CCC", 3);
14
15    let mut recorder: Recorder<BiHashMap<&str, usize>, BiHashMapHalfDelta<&str, usize>> =
16        Recorder::new(map);
17    let mut undoredo: UndoRedo<BiHashMapDelta<&str, usize>> = UndoRedo::new();
18
19    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
20    assert_eq!(recorder.get_by_right(&2), Some(&"BB"));
21
22    assert_eq!(recorder.remove_by_left(&"A"), Some(1));
23    assert_eq!(recorder.remove_by_right(&3), Some("CCC"));
24    undoredo.commit(&mut recorder);
25
26    assert_eq!(recorder.get_by_left(&"A"), None);
27    assert_eq!(recorder.get_by_right(&3), None);
28
29    undoredo.undo(&mut recorder);
30    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
31    assert_eq!(recorder.get_by_left(&"CCC"), Some(&3));
32
33    undoredo.redo(&mut recorder);
34    assert_eq!(recorder.get_by_left(&"A"), None);
35    assert_eq!(recorder.get_by_right(&3), None);
36}
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + RemoveByRight<K>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source

pub fn remove_by_right(&mut self, key: &V) -> Option<K>

Remove the left and right values from pair corresponding to the given right value in a bidirectional map.

Examples found in repository?
examples/bihashmap.rs (line 23)
9fn main() {
10    let mut map = BiHashMap::new();
11    map.insert("A", 1);
12    map.insert("BB", 2);
13    map.insert("CCC", 3);
14
15    let mut recorder: Recorder<BiHashMap<&str, usize>, BiHashMapHalfDelta<&str, usize>> =
16        Recorder::new(map);
17    let mut undoredo: UndoRedo<BiHashMapDelta<&str, usize>> = UndoRedo::new();
18
19    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
20    assert_eq!(recorder.get_by_right(&2), Some(&"BB"));
21
22    assert_eq!(recorder.remove_by_left(&"A"), Some(1));
23    assert_eq!(recorder.remove_by_right(&3), Some("CCC"));
24    undoredo.commit(&mut recorder);
25
26    assert_eq!(recorder.get_by_left(&"A"), None);
27    assert_eq!(recorder.get_by_right(&3), None);
28
29    undoredo.undo(&mut recorder);
30    assert_eq!(recorder.get_by_left(&"A"), Some(&1));
31    assert_eq!(recorder.get_by_left(&"CCC"), Some(&3));
32
33    undoredo.redo(&mut recorder);
34    assert_eq!(recorder.get_by_left(&"A"), None);
35    assert_eq!(recorder.get_by_right(&3), None);
36}
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + Push<K>, DC: Container<Key = K, Value = V> + Insert<K>, K: Clone, V: Clone,

Source

pub fn push(&mut self, value: V) -> K

Insert a value into the container without specifying a key, returning the key that was automatically generated.

Examples found in repository?
examples/entities.rs (line 65)
64    pub fn new_entity(&mut self, position: Vector2<T>, velocity: Vector2<T>, health: i64) -> usize {
65        self.positions.push(position);
66        self.velocities.push(velocity);
67        self.healths.push(health)
68    }
More examples
Hide additional examples
examples/stable_vec.rs (line 14)
9fn main() {
10    let mut recorder: Recorder<StableVec<char>, StableVecHalfDelta<char>> =
11        Recorder::new(StableVec::new());
12    let mut undoredo: UndoRedo<StableVecDelta<char>> = UndoRedo::new();
13
14    recorder.push('A');
15    undoredo.commit(&mut recorder);
16
17    recorder.push('B');
18    recorder.push('B');
19    undoredo.commit(&mut recorder);
20
21    let key = recorder.push('X');
22    recorder.remove(&key);
23    recorder.push('C');
24    undoredo.commit(&mut recorder);
25
26    assert!(
27        recorder
28            .container()
29            .values()
30            .copied()
31            .eq(['A', 'B', 'B', 'C'])
32    );
33
34    undoredo.undo(&mut recorder);
35    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
36
37    undoredo.undo(&mut recorder);
38    assert!(recorder.container().values().copied().eq(['A']));
39
40    undoredo.redo(&mut recorder);
41    assert!(recorder.container().values().copied().eq(['A', 'B', 'B']));
42
43    undoredo.redo(&mut recorder);
44    assert!(
45        recorder
46            .container()
47            .values()
48            .copied()
49            .eq(['A', 'B', 'B', 'C'])
50    );
51}
examples/thunderdome.rs (line 13)
9fn main() {
10    let mut recorder: Recorder<Arena<char>, ArenaHalfDelta<char>> = Recorder::new(Arena::new());
11    let mut undoredo: UndoRedo<ArenaDelta<char>> = UndoRedo::new();
12
13    recorder.push('A');
14    undoredo.commit(&mut recorder);
15
16    recorder.push('B');
17    recorder.push('B');
18    undoredo.commit(&mut recorder);
19
20    let key = recorder.push('X');
21    recorder.remove(&key);
22    recorder.push('C');
23    undoredo.commit(&mut recorder);
24
25    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
26    assert!(values == vec!['A', 'B', 'B', 'C']);
27
28    undoredo.undo(&mut recorder);
29    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
30    assert!(values == vec!['A', 'B', 'B']);
31
32    undoredo.undo(&mut recorder);
33    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
34    assert!(values == vec!['A']);
35
36    undoredo.redo(&mut recorder);
37    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
38    assert!(values == vec!['A', 'B', 'B']);
39
40    undoredo.redo(&mut recorder);
41    let (_, values): (Vec<_>, Vec<char>) = recorder.container().clone().into_iter().unzip();
42    assert!(values == vec!['A', 'B', 'B', 'C']);
43}
Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Container<Key = K, Value = V> + Len + Pop, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source

pub fn pop(&mut self) -> Option<V>

Insert a value into the container without specifying a key, returning the key that was automatically generated.

Source§

impl<K, V, C, DC> Recorder<C, DC>
where C: Clear + Clone + IntoIter<K, Value = V>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,

Source

pub fn clear(&mut self)

Remove all elements from the container.

Source§

impl<C: Container + ApplyDelta<DC>, DC: IntoIter<C::Key> + Container<Key = C::Key, Value = C::Value>> Recorder<C, DC>
where Delta<DC>: Clone + Default + MergeDeltas<DC>,

Source

pub fn extend_delta(&mut self, delta: Delta<DC>)

Extend (merge) the recorder’s recorded delta with the delta passed as an argument.

Source§

impl<C: Container, DC: Container + Default> Recorder<C, DC>

Source

pub fn flush_delta(&mut self) -> Delta<DC>

Flush the recorder, returning the recorded delta and replacing it with a new empty one.

Source§

impl<C: Container + ApplyDelta<DC>, DC: Container + Default> Recorder<C, DC>

Source

pub fn reset_delta(&mut self)

Reset the currently recorded delta by flushing it out of the recorder and then applying its reverse.

Trait Implementations§

Source§

impl<C: Container + ApplyDelta<DC>, RDC: Container, DC: IntoIter<C::Key> + Container<Key = C::Key, Value = C::Value>> ApplyDelta<DC> for Recorder<C, RDC>

Source§

fn apply_delta(&mut self, delta: Delta<DC>)

Apply the changes in a delta to a container. Read more
Source§

impl<C: Container, DC: Container> AsRef<C> for Recorder<C, DC>

Source§

fn as_ref(&self) -> &C

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl<C, DC> Assign<C> for Recorder<C, DC>
where C: Assign + Clone, DC: Get<usize, Value = C> + Set<usize>,

Source§

fn assign(&mut self, value: C)

Replace self with a new value.
Source§

impl<K, V, C, DC> Clear for Recorder<C, DC>
where C: Clear + Clone + IntoIter<K, Value = V>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>,

Source§

fn clear(&mut self)

Remove all elements from the collection.
Source§

impl<C: Clone + Container, DC: Clone + Container> Clone for Recorder<C, DC>

Source§

fn clone(&self) -> Recorder<C, DC>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<C: Container, DC: Container> Container for Recorder<C, DC>

Source§

type Key = <C as Container>::Key

Type of the keys in the keyed collection.
Source§

type Value = <C as Container>::Value

Type of the values in the keyed collection.
Source§

impl<C: Debug + Container, DC: Debug + Container> Debug for Recorder<C, DC>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<C: Default + Container, DC: Default + Container> Default for Recorder<C, DC>

Source§

fn default() -> Recorder<C, DC>

Returns the “default value” for a type. Read more
Source§

impl<'de, C, DC> Deserialize<'de> for Recorder<C, DC>
where C: Deserialize<'de> + Container, DC: Deserialize<'de> + Container,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<C: Container + ApplyDelta<DC>, DC: IntoIter<C::Key> + Container<Key = C::Key, Value = C::Value>> ExtendDelta<DC> for Recorder<C, DC>
where Delta<DC>: Clone + Default + MergeDeltas<DC>,

Source§

fn extend_delta(&mut self, delta: Delta<DC>)

Extend (merge) the recorder’s recorded delta with the delta passed as an argument.
Source§

impl<C: Container, DC: Container + Default> FlushDelta<DC> for Recorder<C, DC>

Source§

fn flush_delta(&mut self) -> Delta<DC>

Flush the recorder, returning the recorded delta and replacing it with a new empty one.
Source§

impl<C: Container + Default + ApplyDelta<DC>, DC: Container + Default> FlushDelta<Recorder<C, DC>> for Recorder<C, DC>

Source§

fn flush_delta(&mut self) -> Delta<Recorder<C, DC>>

Flush the recorder, returning the recorded delta and replacing it with a new empty one.
Source§

impl<K, Q: ?Sized, C, DC> Get<K, Q> for Recorder<C, DC>
where K: Borrow<Q>, C: Get<K, Q, Key = K>, DC: Container,

Source§

fn get(&self, key: &Q) -> Option<&C::Value>

Returns a reference to the value corresponding to the key.
Source§

impl<K, Q: ?Sized, V, C, DC> GetByLeft<K, Q> for Recorder<C, DC>
where K: Borrow<Q>, C: Container<Key = K, Value = V> + GetByLeft<K, Q>, DC: Container,

Source§

fn get_by_left(&self, key: &Q) -> Option<&C::Value>

Returns a reference to the right value corresponding to the given left value. Read more
Source§

impl<K, V, Q: ?Sized, C, DC> GetByRight<K, Q> for Recorder<C, DC>
where V: Borrow<Q>, C: Container<Key = K, Value = V> + GetByRight<K, Q>, DC: Container,

Source§

fn get_by_right(&self, key: &Q) -> Option<&K>

Returns a reference to the right value corresponding to the given left value. Read more
Source§

impl<I, C, DC> Index<I> for Recorder<C, DC>
where C: Container + Index<I, Output = C::Value>, DC: Container,

Source§

type Output = <C as Container>::Value

The returned type after indexing.
Source§

fn index(&self, index: I) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<K, V, C, DC> Insert<K> for Recorder<C, DC>
where C: Container<Key = K, Value = V> + Get<K> + Insert<K>, DC: Container<Key = K, Value = V> + Get<K> + Insert<K>, K: Clone, V: Clone,

Source§

type Output = <C as Insert<K>>::Output

Return type of insert.
Source§

fn insert(&mut self, key: K, value: V) -> Self::Output

Insert a new key-value pair into the container at an arbitrary key. Read more
Source§

impl<K, C, DC> IntoIter<K> for Recorder<C, DC>
where C: IntoIter<K>, DC: Container,

Source§

type IntoIter = <C as IntoIter<K>>::IntoIter

Iterator that consumes the collection.
Source§

fn into_iter(self) -> C::IntoIter

Consume the collection and yield owned key-value pairs.
Source§

impl<C, DC> Len for Recorder<C, DC>
where C: Len, DC: Container,

Source§

fn len(&self) -> C::Key

Returns the length of the collection. Read more
Source§

impl<K, V, C, DC> Modify<K> for Recorder<C, DC>
where C: Container<Key = K, Value = V> + Get<K> + Modify<K>, DC: Container<Key = K, Value = V> + Get<K> + Insert<K>, K: Clone, V: Clone,

Source§

fn modify<F>(&mut self, key: &K, f: F)
where F: FnOnce(&mut Self::Value),

Modify the value under key with a closure. Read more
Source§

impl<C: PartialEq + Container, DC: PartialEq + Container> PartialEq for Recorder<C, DC>

Source§

fn eq(&self, other: &Recorder<C, DC>) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<K, V, C, DC> Pop for Recorder<C, DC>
where C: Container<Key = K, Value = V> + Len + Pop, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source§

fn pop(&mut self) -> Option<V>

Remove the last element of the collection, returning it. Read more
Source§

impl<K, V, C, DC> Push<K> for Recorder<C, DC>
where C: Container<Key = K, Value = V> + Push<K>, DC: Container<Key = K, Value = V> + Insert<K>, K: Clone, V: Clone,

Source§

fn push(&mut self, value: V) -> K

Insert a value into the collection without specifying a key, returning the key that was automatically generated.
Source§

impl<K, V, C, DC> Remove<K> for Recorder<C, DC>
where C: Container<Key = K, Value = V> + Remove<K>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source§

fn remove(&mut self, key: &K) -> Option<V>

Remove an element under a key from the collection, returning the value at the key if the key was previously in the map. Other keys are not invalidated. Read more
Source§

impl<K, V, C, DC> RemoveByLeft<K> for Recorder<C, DC>
where C: Container<Key = K, Value = V> + RemoveByLeft<K>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source§

fn remove_by_left(&mut self, key: &K) -> Option<V>

Remove the left and right values from pair corresponding to the given left value in a bidirectional map. Read more
Source§

impl<K, V, C, DC> RemoveByRight<K> for Recorder<C, DC>
where C: Container<Key = K, Value = V> + RemoveByRight<K>, DC: Container<Key = K, Value = V> + Insert<K> + Remove<K>, K: Clone, V: Clone,

Source§

fn remove_by_right(&mut self, key: &Self::Value) -> Option<K>

Remove the left and right values from pair corresponding to the given right value in a bidirectional map. Read more
Source§

impl<C: Container + ApplyDelta<DC>, DC: Container + Default> ResetDelta<DC> for Recorder<C, DC>

Source§

fn reset_delta(&mut self)

Reset the currently recorded delta by flushing it out of the recorder and then applying its reverse.
Source§

impl<C: Container + Default + ApplyDelta<DC>, DC: IntoIter<C::Key> + Container<Key = C::Key, Value = C::Value> + Default> ResetDelta<Recorder<C, DC>> for Recorder<C, DC>

Source§

fn reset_delta(&mut self)

Reset the currently recorded delta by flushing it out of the recorder and then applying its reverse.
Source§

impl<C, DC> Serialize for Recorder<C, DC>

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<K, V, C, DC> Set<K> for Recorder<C, DC>
where C: Container<Key = K, Value = V> + Get<K> + Set<K>, DC: Container<Key = K, Value = V> + Get<K> + Insert<K>, K: Clone, V: Clone,

Source§

type Output = <C as Set<K>>::Output

Return type of set.
Source§

fn set(&mut self, key: K, value: Self::Value) -> Self::Output

Set the value of an already existing element under a key. Read more
Source§

impl<C: PartialEq + Container, DC: PartialEq + Container> StructuralPartialEq for Recorder<C, DC>

Auto Trait Implementations§

§

impl<C, DC> Freeze for Recorder<C, DC>
where C: Freeze, DC: Freeze,

§

impl<C, DC> RefUnwindSafe for Recorder<C, DC>

§

impl<C, DC> Send for Recorder<C, DC>
where C: Send, DC: Send,

§

impl<C, DC> Sync for Recorder<C, DC>
where C: Sync, DC: Sync,

§

impl<C, DC> Unpin for Recorder<C, DC>
where C: Unpin, DC: Unpin,

§

impl<C, DC> UnsafeUnpin for Recorder<C, DC>
where C: UnsafeUnpin, DC: UnsafeUnpin,

§

impl<C, DC> UnwindSafe for Recorder<C, DC>
where C: UnwindSafe, DC: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<K, T> Arraylike<K> for T
where T: Index<K> + Get<K> + Set<K> + Len,

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<K, T> Maplike<K> for T
where T: Get<K> + Set<K> + Insert<K> + Remove<K> + Clear + for<'a> Index<&'a K>,

Source§

impl<V, T> Scalarlike<V> for T
where T: Assign<V>,

Source§

impl<K, T> Setlike<K> for T
where T: Maplike<K, Value = ()>,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<K, T> Veclike<K> for T
where T: Arraylike<K> + Push<K> + Pop + Clear,