tree_building/tree_building.rs
1use loaned::{take, LoanedMut};
2
3#[derive(Debug, Default, Clone, PartialEq, Eq)]
4enum Tree {
5 #[default]
6 Null,
7 Leaf(i32),
8 Node(Box<Tree>, Box<Tree>),
9}
10
11#[cfg_attr(test, test)]
12fn main() {
13 // First, we create a single node `a`, which has two holes, `b` and `c`.
14 // ```text
15 // a
16 // / \
17 // ?b ?c
18 // ```
19 // `a` is a `LoanedMut<Tree>`, whilst `b` and `c` are `&mut Tree`s.
20 let (a, b, c) = new_node();
21
22 // Next, we fill one of those holes, `b`, with a leaf:
23 // ```text
24 // a
25 // / \
26 // 1 ?c
27 // ```
28 *b = Tree::Leaf(1);
29
30 // Now, we create another node, `x`, with holes `y` and `z`:
31 // ```text
32 // a x
33 // / \ / \
34 // 1 ?c ?y ?z
35 // ```
36 let (x, y, z) = new_node();
37
38 // We fill `y` with another leaf:
39 // ```text
40 // a x
41 // / \ / \
42 // 1 ?c 2 ?z
43 // ```
44 *y = Tree::Leaf(2);
45
46 // Now, we fill the hole `c` with the node `x`.
47 // ```text
48 // a
49 // / \
50 // 1 / \
51 // 2 ?z
52 // ```
53 // We still have a mutable reference to the hole `z`, even though we just
54 // moved ownership of `x` – this is the key power of `Loaned` values.
55 x.place(c); // this is like `*c = x`, except it accepts `Loaned` values.
56
57 // Finally, we can fill the hole `z` (which is a mutable reference to data now owned by `a`):
58 // ```text
59 // a
60 // / \
61 // 1 / \
62 // 2 3
63 // ```
64 *z = Tree::Leaf(3);
65
66 // All of the borrows have expired, so we can now take the tree out of `a`:
67 let a = take!(a);
68
69 println!("{a:?}");
70 assert_eq!(format!("{a:?}"), "Node(Leaf(1), Node(Leaf(2), Leaf(3)))");
71
72 // If we tried to use one of the borrows now, we would get an error from the borrow checker.
73 // *z = Tree::Leaf(0xBAD);
74}
75
76fn new_node<'t>() -> (LoanedMut<'t, Tree>, &'t mut Tree, &'t mut Tree) {
77 let ((left, right), root) = LoanedMut::loan_with(
78 Tree::Node(Default::default(), Default::default()),
79 |tree, l| {
80 let Tree::Node(left, right) = tree else {
81 unreachable!()
82 };
83 (l.loan_mut(left), l.loan_mut(right))
84 },
85 );
86 (root, left, right)
87}