accesskit_consumer/
tree.rs

1// Copyright 2021 The AccessKit Authors. All rights reserved.
2// Licensed under the Apache License, Version 2.0 (found in
3// the LICENSE-APACHE file) or the MIT license (found in
4// the LICENSE-MIT file), at your option.
5
6use accesskit::{Node as NodeData, NodeId, Tree as TreeData, TreeUpdate};
7use immutable_chunkmap::map::MapM as ChunkMap;
8use std::{
9    collections::{HashMap, HashSet},
10    sync::Arc,
11};
12
13use crate::node::{Node, NodeState, ParentAndIndex};
14
15#[derive(Clone)]
16pub struct State {
17    pub(crate) nodes: ChunkMap<NodeId, NodeState>,
18    pub(crate) data: TreeData,
19    focus: NodeId,
20    is_host_focused: bool,
21}
22
23#[derive(Default)]
24struct InternalChanges {
25    added_node_ids: HashSet<NodeId>,
26    updated_node_ids: HashSet<NodeId>,
27    removed_node_ids: HashSet<NodeId>,
28}
29
30impl State {
31    fn validate_global(&self) {
32        if self.nodes.get_key(&self.data.root).is_none() {
33            panic!("Root id #{} is not in the node list", self.data.root.0);
34        }
35        if self.nodes.get_key(&self.focus).is_none() {
36            panic!("Focused id #{} is not in the node list", self.focus.0);
37        }
38    }
39
40    fn update(
41        &mut self,
42        update: TreeUpdate,
43        is_host_focused: bool,
44        mut changes: Option<&mut InternalChanges>,
45    ) {
46        let mut orphans = HashSet::new();
47
48        if let Some(tree) = update.tree {
49            if tree.root != self.data.root {
50                orphans.insert(self.data.root);
51            }
52            self.data = tree;
53        }
54
55        let root = self.data.root;
56        let mut pending_nodes: HashMap<NodeId, _> = HashMap::new();
57        let mut pending_children = HashMap::new();
58
59        fn add_node(
60            nodes: &mut ChunkMap<NodeId, NodeState>,
61            changes: &mut Option<&mut InternalChanges>,
62            parent_and_index: Option<ParentAndIndex>,
63            id: NodeId,
64            data: NodeData,
65        ) {
66            let state = NodeState {
67                parent_and_index,
68                data: Arc::new(data),
69            };
70            nodes.insert_cow(id, state);
71            if let Some(changes) = changes {
72                changes.added_node_ids.insert(id);
73            }
74        }
75
76        for (node_id, node_data) in update.nodes {
77            orphans.remove(&node_id);
78
79            let mut seen_child_ids = HashSet::new();
80            for (child_index, child_id) in node_data.children().iter().enumerate() {
81                if seen_child_ids.contains(child_id) {
82                    panic!(
83                        "Node #{} of TreeUpdate includes duplicate child #{};",
84                        node_id.0, child_id.0
85                    );
86                }
87                orphans.remove(child_id);
88                let parent_and_index = ParentAndIndex(node_id, child_index);
89                if let Some(child_state) = self.nodes.get_mut_cow(child_id) {
90                    if child_state.parent_and_index != Some(parent_and_index) {
91                        child_state.parent_and_index = Some(parent_and_index);
92                    }
93                } else if let Some(child_data) = pending_nodes.remove(child_id) {
94                    add_node(
95                        &mut self.nodes,
96                        &mut changes,
97                        Some(parent_and_index),
98                        *child_id,
99                        child_data,
100                    );
101                } else {
102                    pending_children.insert(*child_id, parent_and_index);
103                }
104                seen_child_ids.insert(child_id);
105            }
106
107            if let Some(node_state) = self.nodes.get_mut_cow(&node_id) {
108                if node_id == root {
109                    node_state.parent_and_index = None;
110                }
111                for child_id in node_state.data.children().iter() {
112                    if !seen_child_ids.contains(child_id) {
113                        orphans.insert(*child_id);
114                    }
115                }
116                if *node_state.data != node_data {
117                    node_state.data = Arc::new(node_data);
118                    if let Some(changes) = &mut changes {
119                        changes.updated_node_ids.insert(node_id);
120                    }
121                }
122            } else if let Some(parent_and_index) = pending_children.remove(&node_id) {
123                add_node(
124                    &mut self.nodes,
125                    &mut changes,
126                    Some(parent_and_index),
127                    node_id,
128                    node_data,
129                );
130            } else if node_id == root {
131                add_node(&mut self.nodes, &mut changes, None, node_id, node_data);
132            } else {
133                pending_nodes.insert(node_id, node_data);
134            }
135        }
136
137        if !pending_nodes.is_empty() {
138            panic!("TreeUpdate includes {} nodes which are neither in the current tree nor a child of another node from the update: {}", pending_nodes.len(), short_node_list(pending_nodes.keys()));
139        }
140        if !pending_children.is_empty() {
141            panic!("TreeUpdate's nodes include {} children ids which are neither in the current tree nor the id of another node from the update: {}", pending_children.len(), short_node_list(pending_children.keys()));
142        }
143
144        self.focus = update.focus;
145        self.is_host_focused = is_host_focused;
146
147        if !orphans.is_empty() {
148            let mut to_remove = HashSet::new();
149
150            fn traverse_orphan(
151                nodes: &ChunkMap<NodeId, NodeState>,
152                to_remove: &mut HashSet<NodeId>,
153                id: NodeId,
154            ) {
155                to_remove.insert(id);
156                let node = nodes.get(&id).unwrap();
157                for child_id in node.data.children().iter() {
158                    traverse_orphan(nodes, to_remove, *child_id);
159                }
160            }
161
162            for id in orphans {
163                traverse_orphan(&self.nodes, &mut to_remove, id);
164            }
165
166            for id in to_remove {
167                if self.nodes.remove_cow(&id).is_some() {
168                    if let Some(changes) = &mut changes {
169                        changes.removed_node_ids.insert(id);
170                    }
171                }
172            }
173        }
174
175        self.validate_global();
176    }
177
178    fn update_host_focus_state(
179        &mut self,
180        is_host_focused: bool,
181        changes: Option<&mut InternalChanges>,
182    ) {
183        let update = TreeUpdate {
184            nodes: vec![],
185            tree: None,
186            focus: self.focus,
187        };
188        self.update(update, is_host_focused, changes);
189    }
190
191    pub fn serialize(&self) -> TreeUpdate {
192        let mut nodes = Vec::new();
193
194        fn traverse(state: &State, nodes: &mut Vec<(NodeId, NodeData)>, id: NodeId) {
195            let node = state.nodes.get(&id).unwrap();
196            nodes.push((id, (*node.data).clone()));
197
198            for child_id in node.data.children().iter() {
199                traverse(state, nodes, *child_id);
200            }
201        }
202
203        traverse(self, &mut nodes, self.data.root);
204        assert_eq!(nodes.len(), self.nodes.len());
205
206        TreeUpdate {
207            nodes,
208            tree: Some(self.data.clone()),
209            focus: self.focus,
210        }
211    }
212
213    pub fn has_node(&self, id: NodeId) -> bool {
214        self.nodes.get(&id).is_some()
215    }
216
217    pub fn node_by_id(&self, id: NodeId) -> Option<Node<'_>> {
218        self.nodes.get(&id).map(|node_state| Node {
219            tree_state: self,
220            id,
221            state: node_state,
222        })
223    }
224
225    pub fn root_id(&self) -> NodeId {
226        self.data.root
227    }
228
229    pub fn root(&self) -> Node<'_> {
230        self.node_by_id(self.root_id()).unwrap()
231    }
232
233    pub fn is_host_focused(&self) -> bool {
234        self.is_host_focused
235    }
236
237    pub fn focus_id(&self) -> Option<NodeId> {
238        self.is_host_focused.then_some(self.focus)
239    }
240
241    pub fn focus(&self) -> Option<Node<'_>> {
242        self.focus_id().map(|id| self.node_by_id(id).unwrap())
243    }
244
245    pub fn app_name(&self) -> Option<String> {
246        self.data.app_name.clone()
247    }
248
249    pub fn toolkit_name(&self) -> Option<String> {
250        self.data.toolkit_name.clone()
251    }
252
253    pub fn toolkit_version(&self) -> Option<String> {
254        self.data.toolkit_version.clone()
255    }
256}
257
258pub trait ChangeHandler {
259    fn node_added(&mut self, node: &Node);
260    fn node_updated(&mut self, old_node: &Node, new_node: &Node);
261    fn focus_moved(&mut self, old_node: Option<&Node>, new_node: Option<&Node>);
262    fn node_removed(&mut self, node: &Node);
263}
264
265pub struct Tree {
266    state: State,
267}
268
269impl Tree {
270    pub fn new(mut initial_state: TreeUpdate, is_host_focused: bool) -> Self {
271        let Some(tree) = initial_state.tree.take() else {
272            panic!("Tried to initialize the accessibility tree without a root tree. TreeUpdate::tree must be Some.");
273        };
274        let mut state = State {
275            nodes: ChunkMap::new(),
276            data: tree,
277            focus: initial_state.focus,
278            is_host_focused,
279        };
280        state.update(initial_state, is_host_focused, None);
281        Self { state }
282    }
283
284    pub fn update(&mut self, update: TreeUpdate) {
285        self.state.update(update, self.state.is_host_focused, None);
286    }
287
288    pub fn update_and_process_changes(
289        &mut self,
290        update: TreeUpdate,
291        handler: &mut impl ChangeHandler,
292    ) {
293        let mut changes = InternalChanges::default();
294        let old_state = self.state.clone();
295        self.state
296            .update(update, self.state.is_host_focused, Some(&mut changes));
297        self.process_changes(old_state, changes, handler);
298    }
299
300    pub fn update_host_focus_state(&mut self, is_host_focused: bool) {
301        self.state.update_host_focus_state(is_host_focused, None);
302    }
303
304    pub fn update_host_focus_state_and_process_changes(
305        &mut self,
306        is_host_focused: bool,
307        handler: &mut impl ChangeHandler,
308    ) {
309        let mut changes = InternalChanges::default();
310        let old_state = self.state.clone();
311        self.state
312            .update_host_focus_state(is_host_focused, Some(&mut changes));
313        self.process_changes(old_state, changes, handler);
314    }
315
316    fn process_changes(
317        &self,
318        old_state: State,
319        changes: InternalChanges,
320        handler: &mut impl ChangeHandler,
321    ) {
322        for id in &changes.added_node_ids {
323            let node = self.state.node_by_id(*id).unwrap();
324            handler.node_added(&node);
325        }
326        for id in &changes.updated_node_ids {
327            let old_node = old_state.node_by_id(*id).unwrap();
328            let new_node = self.state.node_by_id(*id).unwrap();
329            handler.node_updated(&old_node, &new_node);
330        }
331        if old_state.focus_id() != self.state.focus_id() {
332            let old_node = old_state.focus();
333            if let Some(old_node) = &old_node {
334                let id = old_node.id();
335                if !changes.updated_node_ids.contains(&id)
336                    && !changes.removed_node_ids.contains(&id)
337                {
338                    if let Some(old_node_new_version) = self.state.node_by_id(id) {
339                        handler.node_updated(old_node, &old_node_new_version);
340                    }
341                }
342            }
343            let new_node = self.state.focus();
344            if let Some(new_node) = &new_node {
345                let id = new_node.id();
346                if !changes.added_node_ids.contains(&id) && !changes.updated_node_ids.contains(&id)
347                {
348                    if let Some(new_node_old_version) = old_state.node_by_id(id) {
349                        handler.node_updated(&new_node_old_version, new_node);
350                    }
351                }
352            }
353            handler.focus_moved(old_node.as_ref(), new_node.as_ref());
354        }
355        for id in &changes.removed_node_ids {
356            let node = old_state.node_by_id(*id).unwrap();
357            handler.node_removed(&node);
358        }
359    }
360
361    pub fn state(&self) -> &State {
362        &self.state
363    }
364}
365
366fn short_node_list<'a>(nodes: impl ExactSizeIterator<Item = &'a NodeId>) -> String {
367    if nodes.len() > 10 {
368        format!(
369            "[{} ...]",
370            nodes
371                .take(10)
372                .map(|id| format!("#{}", id.0))
373                .collect::<Vec<_>>()
374                .join(", "),
375        )
376    } else {
377        format!(
378            "[{}]",
379            nodes
380                .map(|id| format!("#{}", id.0))
381                .collect::<Vec<_>>()
382                .join(", "),
383        )
384    }
385}
386
387#[cfg(test)]
388mod tests {
389    use accesskit::{NodeBuilder, NodeId, Role, Tree, TreeUpdate};
390
391    #[test]
392    fn init_tree_with_root_node() {
393        let update = TreeUpdate {
394            nodes: vec![(NodeId(0), NodeBuilder::new(Role::Window).build())],
395            tree: Some(Tree::new(NodeId(0))),
396            focus: NodeId(0),
397        };
398        let tree = super::Tree::new(update, false);
399        assert_eq!(NodeId(0), tree.state().root().id());
400        assert_eq!(Role::Window, tree.state().root().role());
401        assert!(tree.state().root().parent().is_none());
402    }
403
404    #[test]
405    fn root_node_has_children() {
406        let update = TreeUpdate {
407            nodes: vec![
408                (NodeId(0), {
409                    let mut builder = NodeBuilder::new(Role::Window);
410                    builder.set_children(vec![NodeId(1), NodeId(2)]);
411                    builder.build()
412                }),
413                (NodeId(1), NodeBuilder::new(Role::Button).build()),
414                (NodeId(2), NodeBuilder::new(Role::Button).build()),
415            ],
416            tree: Some(Tree::new(NodeId(0))),
417            focus: NodeId(0),
418        };
419        let tree = super::Tree::new(update, false);
420        let state = tree.state();
421        assert_eq!(
422            NodeId(0),
423            state.node_by_id(NodeId(1)).unwrap().parent().unwrap().id()
424        );
425        assert_eq!(
426            NodeId(0),
427            state.node_by_id(NodeId(2)).unwrap().parent().unwrap().id()
428        );
429        assert_eq!(2, state.root().children().count());
430    }
431
432    #[test]
433    fn add_child_to_root_node() {
434        let root_builder = NodeBuilder::new(Role::Window);
435        let first_update = TreeUpdate {
436            nodes: vec![(NodeId(0), root_builder.clone().build())],
437            tree: Some(Tree::new(NodeId(0))),
438            focus: NodeId(0),
439        };
440        let mut tree = super::Tree::new(first_update, false);
441        assert_eq!(0, tree.state().root().children().count());
442        let second_update = TreeUpdate {
443            nodes: vec![
444                (NodeId(0), {
445                    let mut builder = root_builder;
446                    builder.push_child(NodeId(1));
447                    builder.build()
448                }),
449                (NodeId(1), NodeBuilder::new(Role::RootWebArea).build()),
450            ],
451            tree: None,
452            focus: NodeId(0),
453        };
454        struct Handler {
455            got_new_child_node: bool,
456            got_updated_root_node: bool,
457        }
458        fn unexpected_change() {
459            panic!("expected only new child node and updated root node");
460        }
461        impl super::ChangeHandler for Handler {
462            fn node_added(&mut self, node: &crate::Node) {
463                if node.id() == NodeId(1) {
464                    self.got_new_child_node = true;
465                    return;
466                }
467                unexpected_change();
468            }
469            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
470                if new_node.id() == NodeId(0)
471                    && old_node.data().children().is_empty()
472                    && new_node.data().children() == [NodeId(1)]
473                {
474                    self.got_updated_root_node = true;
475                    return;
476                }
477                unexpected_change();
478            }
479            fn focus_moved(
480                &mut self,
481                _old_node: Option<&crate::Node>,
482                _new_node: Option<&crate::Node>,
483            ) {
484                unexpected_change();
485            }
486            fn node_removed(&mut self, _node: &crate::Node) {
487                unexpected_change();
488            }
489        }
490        let mut handler = Handler {
491            got_new_child_node: false,
492            got_updated_root_node: false,
493        };
494        tree.update_and_process_changes(second_update, &mut handler);
495        assert!(handler.got_new_child_node);
496        assert!(handler.got_updated_root_node);
497        let state = tree.state();
498        assert_eq!(1, state.root().children().count());
499        assert_eq!(NodeId(1), state.root().children().next().unwrap().id());
500        assert_eq!(
501            NodeId(0),
502            state.node_by_id(NodeId(1)).unwrap().parent().unwrap().id()
503        );
504    }
505
506    #[test]
507    fn remove_child_from_root_node() {
508        let root_builder = NodeBuilder::new(Role::Window);
509        let first_update = TreeUpdate {
510            nodes: vec![
511                (NodeId(0), {
512                    let mut builder = root_builder.clone();
513                    builder.push_child(NodeId(1));
514                    builder.build()
515                }),
516                (NodeId(1), NodeBuilder::new(Role::RootWebArea).build()),
517            ],
518            tree: Some(Tree::new(NodeId(0))),
519            focus: NodeId(0),
520        };
521        let mut tree = super::Tree::new(first_update, false);
522        assert_eq!(1, tree.state().root().children().count());
523        let second_update = TreeUpdate {
524            nodes: vec![(NodeId(0), root_builder.build())],
525            tree: None,
526            focus: NodeId(0),
527        };
528        struct Handler {
529            got_updated_root_node: bool,
530            got_removed_child_node: bool,
531        }
532        fn unexpected_change() {
533            panic!("expected only removed child node and updated root node");
534        }
535        impl super::ChangeHandler for Handler {
536            fn node_added(&mut self, _node: &crate::Node) {
537                unexpected_change();
538            }
539            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
540                if new_node.id() == NodeId(0)
541                    && old_node.data().children() == [NodeId(1)]
542                    && new_node.data().children().is_empty()
543                {
544                    self.got_updated_root_node = true;
545                    return;
546                }
547                unexpected_change();
548            }
549            fn focus_moved(
550                &mut self,
551                _old_node: Option<&crate::Node>,
552                _new_node: Option<&crate::Node>,
553            ) {
554                unexpected_change();
555            }
556            fn node_removed(&mut self, node: &crate::Node) {
557                if node.id() == NodeId(1) {
558                    self.got_removed_child_node = true;
559                    return;
560                }
561                unexpected_change();
562            }
563        }
564        let mut handler = Handler {
565            got_updated_root_node: false,
566            got_removed_child_node: false,
567        };
568        tree.update_and_process_changes(second_update, &mut handler);
569        assert!(handler.got_updated_root_node);
570        assert!(handler.got_removed_child_node);
571        assert_eq!(0, tree.state().root().children().count());
572        assert!(tree.state().node_by_id(NodeId(1)).is_none());
573    }
574
575    #[test]
576    fn move_focus_between_siblings() {
577        let first_update = TreeUpdate {
578            nodes: vec![
579                (NodeId(0), {
580                    let mut builder = NodeBuilder::new(Role::Window);
581                    builder.set_children(vec![NodeId(1), NodeId(2)]);
582                    builder.build()
583                }),
584                (NodeId(1), NodeBuilder::new(Role::Button).build()),
585                (NodeId(2), NodeBuilder::new(Role::Button).build()),
586            ],
587            tree: Some(Tree::new(NodeId(0))),
588            focus: NodeId(1),
589        };
590        let mut tree = super::Tree::new(first_update, true);
591        assert!(tree.state().node_by_id(NodeId(1)).unwrap().is_focused());
592        let second_update = TreeUpdate {
593            nodes: vec![],
594            tree: None,
595            focus: NodeId(2),
596        };
597        struct Handler {
598            got_old_focus_node_update: bool,
599            got_new_focus_node_update: bool,
600            got_focus_change: bool,
601        }
602        fn unexpected_change() {
603            panic!("expected only focus change");
604        }
605        impl super::ChangeHandler for Handler {
606            fn node_added(&mut self, _node: &crate::Node) {
607                unexpected_change();
608            }
609            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
610                if old_node.id() == NodeId(1)
611                    && new_node.id() == NodeId(1)
612                    && old_node.is_focused()
613                    && !new_node.is_focused()
614                {
615                    self.got_old_focus_node_update = true;
616                    return;
617                }
618                if old_node.id() == NodeId(2)
619                    && new_node.id() == NodeId(2)
620                    && !old_node.is_focused()
621                    && new_node.is_focused()
622                {
623                    self.got_new_focus_node_update = true;
624                    return;
625                }
626                unexpected_change();
627            }
628            fn focus_moved(
629                &mut self,
630                old_node: Option<&crate::Node>,
631                new_node: Option<&crate::Node>,
632            ) {
633                if let (Some(old_node), Some(new_node)) = (old_node, new_node) {
634                    if old_node.id() == NodeId(1) && new_node.id() == NodeId(2) {
635                        self.got_focus_change = true;
636                        return;
637                    }
638                }
639                unexpected_change();
640            }
641            fn node_removed(&mut self, _node: &crate::Node) {
642                unexpected_change();
643            }
644        }
645        let mut handler = Handler {
646            got_old_focus_node_update: false,
647            got_new_focus_node_update: false,
648            got_focus_change: false,
649        };
650        tree.update_and_process_changes(second_update, &mut handler);
651        assert!(handler.got_old_focus_node_update);
652        assert!(handler.got_new_focus_node_update);
653        assert!(handler.got_focus_change);
654        assert!(tree.state().node_by_id(NodeId(2)).unwrap().is_focused());
655        assert!(!tree.state().node_by_id(NodeId(1)).unwrap().is_focused());
656    }
657
658    #[test]
659    fn update_node() {
660        let child_builder = NodeBuilder::new(Role::Button);
661        let first_update = TreeUpdate {
662            nodes: vec![
663                (NodeId(0), {
664                    let mut builder = NodeBuilder::new(Role::Window);
665                    builder.set_children(vec![NodeId(1)]);
666                    builder.build()
667                }),
668                (NodeId(1), {
669                    let mut builder = child_builder.clone();
670                    builder.set_name("foo");
671                    builder.build()
672                }),
673            ],
674            tree: Some(Tree::new(NodeId(0))),
675            focus: NodeId(0),
676        };
677        let mut tree = super::Tree::new(first_update, false);
678        assert_eq!(
679            Some("foo".into()),
680            tree.state().node_by_id(NodeId(1)).unwrap().name()
681        );
682        let second_update = TreeUpdate {
683            nodes: vec![(NodeId(1), {
684                let mut builder = child_builder;
685                builder.set_name("bar");
686                builder.build()
687            })],
688            tree: None,
689            focus: NodeId(0),
690        };
691        struct Handler {
692            got_updated_child_node: bool,
693        }
694        fn unexpected_change() {
695            panic!("expected only updated child node");
696        }
697        impl super::ChangeHandler for Handler {
698            fn node_added(&mut self, _node: &crate::Node) {
699                unexpected_change();
700            }
701            fn node_updated(&mut self, old_node: &crate::Node, new_node: &crate::Node) {
702                if new_node.id() == NodeId(1)
703                    && old_node.name() == Some("foo".into())
704                    && new_node.name() == Some("bar".into())
705                {
706                    self.got_updated_child_node = true;
707                    return;
708                }
709                unexpected_change();
710            }
711            fn focus_moved(
712                &mut self,
713                _old_node: Option<&crate::Node>,
714                _new_node: Option<&crate::Node>,
715            ) {
716                unexpected_change();
717            }
718            fn node_removed(&mut self, _node: &crate::Node) {
719                unexpected_change();
720            }
721        }
722        let mut handler = Handler {
723            got_updated_child_node: false,
724        };
725        tree.update_and_process_changes(second_update, &mut handler);
726        assert!(handler.got_updated_child_node);
727        assert_eq!(
728            Some("bar".into()),
729            tree.state().node_by_id(NodeId(1)).unwrap().name()
730        );
731    }
732
733    // Verify that if an update consists entirely of node data and tree data
734    // that's the same as before, no changes are reported. This is useful
735    // for a provider that constructs a fresh tree every time, such as
736    // an immediate-mode GUI.
737    #[test]
738    fn no_change_update() {
739        let update = TreeUpdate {
740            nodes: vec![
741                (NodeId(0), {
742                    let mut builder = NodeBuilder::new(Role::Window);
743                    builder.set_children(vec![NodeId(1)]);
744                    builder.build()
745                }),
746                (NodeId(1), {
747                    let mut builder = NodeBuilder::new(Role::Button);
748                    builder.set_name("foo");
749                    builder.build()
750                }),
751            ],
752            tree: Some(Tree::new(NodeId(0))),
753            focus: NodeId(0),
754        };
755        let mut tree = super::Tree::new(update.clone(), false);
756        struct Handler;
757        fn unexpected_change() {
758            panic!("expected no changes");
759        }
760        impl super::ChangeHandler for Handler {
761            fn node_added(&mut self, _node: &crate::Node) {
762                unexpected_change();
763            }
764            fn node_updated(&mut self, _old_node: &crate::Node, _new_node: &crate::Node) {
765                unexpected_change();
766            }
767            fn focus_moved(
768                &mut self,
769                _old_node: Option<&crate::Node>,
770                _new_node: Option<&crate::Node>,
771            ) {
772                unexpected_change();
773            }
774            fn node_removed(&mut self, _node: &crate::Node) {
775                unexpected_change();
776            }
777        }
778        let mut handler = Handler {};
779        tree.update_and_process_changes(update, &mut handler);
780    }
781}