Skip to main content

history_tree/
history_tree.rs

1// SPDX-FileCopyrightText: 2026 undoredo contributors
2//
3// SPDX-License-Identifier: MIT OR Apache-2.0
4
5use undoredo::aliases::VecDelta;
6use undoredo::{HistoryTree, Recorder};
7
8fn main() {
9    let mut history_tree: HistoryTree<VecDelta<&str>> = HistoryTree::new();
10    let mut state = Recorder::new(vec!["root"]);
11
12    // Right below the root we push a "fork" node, from which we will fork two
13    // branches.
14    state.push("fork");
15    history_tree.commit(&mut state);
16
17    let fork = history_tree.curr_node();
18
19    assert_eq!(*state.as_ref(), vec!["root", "fork"]);
20
21    // Add first node of left branch.
22    state.push("left_branch_1");
23    history_tree.commit(&mut state);
24
25    let left_branch_1 = history_tree.curr_node();
26
27    // Add second node of left branch.
28    state.push("left_branch_2");
29    history_tree.commit(&mut state);
30
31    let left_branch_2 = history_tree.curr_node();
32
33    // Now we have assembled the whole of the left branch.
34    assert_eq!(
35        *state.as_ref(),
36        vec!["root", "fork", "left_branch_1", "left_branch_2"]
37    );
38
39    // Let's now undo the whole left branch up to the fork node.
40    history_tree.undo(&mut state);
41    history_tree.undo(&mut state);
42
43    assert_eq!(*state.as_ref(), vec!["root", "fork"]);
44    assert_eq!(history_tree.curr_node(), fork);
45
46    // Add first node of right branch.
47    state.push("right_branch_1");
48    history_tree.commit(&mut state);
49
50    let right_branch_1 = history_tree.curr_node();
51
52    // Add second node of right branch.
53    state.push("right_branch_2");
54    history_tree.commit(&mut state);
55
56    let right_branch_2 = history_tree.curr_node();
57
58    // Now we have assembled the whole of the right branch.
59    assert_eq!(
60        *state.as_ref(),
61        vec!["root", "fork", "right_branch_1", "right_branch_2"]
62    );
63
64    let root_children = history_tree
65        .node(history_tree.node(fork).parent().unwrap())
66        .children();
67    assert_eq!(root_children, &[fork]);
68
69    assert_eq!(
70        history_tree.node(fork).children(),
71        &[left_branch_1, right_branch_1]
72    );
73    assert_eq!(
74        history_tree.node(left_branch_1).children(),
75        &[left_branch_2]
76    );
77    assert_eq!(
78        history_tree.node(right_branch_1).children(),
79        &[right_branch_2]
80    );
81
82    // Check out left branch from the apex of the right branch.
83    history_tree.checkout(&mut state, left_branch_2);
84
85    assert_eq!(history_tree.curr_node(), left_branch_2);
86    assert_eq!(
87        *state.as_ref(),
88        vec!["root", "fork", "left_branch_1", "left_branch_2"]
89    );
90
91    // Check out the right branch from the apex of the left branch.
92    history_tree.checkout(&mut state, right_branch_2);
93
94    assert_eq!(history_tree.curr_node(), right_branch_2);
95    assert_eq!(
96        *state.as_ref(),
97        vec!["root", "fork", "right_branch_1", "right_branch_2"]
98    );
99
100    // Let's now undo the whole right branch up to the fork node.
101    history_tree.undo(&mut state);
102    history_tree.undo(&mut state);
103
104    assert_eq!(*state.as_ref(), vec!["root", "fork"]);
105    assert_eq!(history_tree.curr_node(), fork);
106}
107
108#[test]
109fn test() {
110    main();
111}