Skip to main content

zenoh_keyexpr/keyexpr_tree/traits/
mod.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14
15use alloc::boxed::Box;
16
17use crate::{keyexpr, OwnedKeyExpr};
18pub mod default_impls;
19
20/// The basic immutable methods of all KeTrees.
21pub trait IKeyExprTree<'a, Weight> {
22    /// The type of a given node in the KeTree.
23    ///
24    /// The methods of nodes are exposed in the [`IKeyExprTreeNode`] and [`IKeyExprTreeNodeMut`] traits
25    type Node: IKeyExprTreeNodeMut<Weight>;
26
27    /// Accesses the node at `key` if it exists, treating KEs as if they were completely verbatim keys.
28    ///
29    /// Returns `None` if `key` is not present in the KeTree.
30    fn node(&'a self, key: &keyexpr) -> Option<&'a Self::Node>;
31
32    /// Returns a reference to the weight of the node at `key` if it exists.
33    fn weight_at(&'a self, key: &keyexpr) -> Option<&'a Weight> {
34        self.node(key)
35            .and_then(<Self::Node as IKeyExprTreeNode<Weight>>::weight)
36    }
37
38    type TreeIterItem;
39    type TreeIter: Iterator<Item = Self::TreeIterItem>;
40
41    /// Iterates over the whole tree, including nodes with no weight.
42    ///
43    /// [`IKeyExprTree::key_value_pairs`] provides an iterator over all key-value pairs in the tree.
44    fn tree_iter(&'a self) -> Self::TreeIter;
45
46    /// Iterates through weighted nodes, yielding their KE and Weight.
47    #[allow(clippy::type_complexity)]
48    fn key_value_pairs(
49        &'a self,
50    ) -> core::iter::FilterMap<
51        Self::TreeIter,
52        fn(Self::TreeIterItem) -> Option<(OwnedKeyExpr, &'a Weight)>,
53    >
54    where
55        Self::TreeIterItem: AsNode<Box<Self::Node>>,
56    {
57        self.tree_iter().filter_map(|node| {
58            // SAFETY: upheld by the surrounding invariants and prior validation.
59            unsafe {
60                core::mem::transmute::<Option<&Weight>, Option<&Weight>>(node.as_node().weight())
61            }
62            .map(|w| (node.as_node().keyexpr(), w))
63        })
64    }
65
66    type IntersectionItem;
67    type Intersection: Iterator<Item = Self::IntersectionItem>;
68
69    /// Iterates over all nodes of the tree whose KE intersects with the given `key`.
70    ///
71    /// Note that nodes without a `Weight` will also be yielded by the iterator.
72    ///
73    /// You can obtain an iterator over key-value pairs using `iter.filter_map(|node| node.weight.map(|w| (node.keyexpr(), w)))`,
74    /// keep in mind that the full keyexpr of nodes is not stored in them by default, but computed using the tree:
75    /// if you need to get a node's key often, inserting its keyexpr in the `Weight` could be a good idea.
76    fn intersecting_nodes(&'a self, key: &'a keyexpr) -> Self::Intersection;
77
78    /// Returns an iterator over the KEs contained in the tree that intersect with `key`
79    fn intersecting_keys(
80        &'a self,
81        key: &'a keyexpr,
82    ) -> Keys<Self::Intersection, Self::IntersectionItem>
83    where
84        Self::IntersectionItem: AsNode<Self::Node>,
85        Self::Node: IKeyExprTreeNode<Weight>,
86    {
87        self.intersecting_nodes(key)
88            .filter_map(filter_map_weighted_node_to_key)
89    }
90
91    type InclusionItem;
92    type Inclusion: Iterator<Item = Self::InclusionItem>;
93
94    /// Iterates over all nodes of the tree whose KE is included by the given `key`.
95    ///
96    /// Note that nodes without a `Weight` will also be yielded by the iterator.
97    ///
98    /// You can obtain an iterator over key-value pairs using `iter.filter_map(|node| node.weight.map(|w| (node.keyexpr(), w)))`,
99    /// keep in mind that the full keyexpr of nodes is not stored in them by default, but computed using the tree:
100    /// if you need to get a node's key often, inserting its keyexpr in the `Weight` could be a good idea.
101    fn included_nodes(&'a self, key: &'a keyexpr) -> Self::Inclusion;
102
103    /// Returns an iterator over the KEs contained in the tree that are included by `key`
104    fn included_keys(&'a self, key: &'a keyexpr) -> Keys<Self::Inclusion, Self::InclusionItem>
105    where
106        Self::InclusionItem: AsNode<Self::Node>,
107        Self::Node: IKeyExprTreeNode<Weight>,
108    {
109        self.included_nodes(key)
110            .filter_map(filter_map_weighted_node_to_key)
111    }
112
113    type IncluderItem;
114    type Includer: Iterator<Item = Self::IncluderItem>;
115
116    /// Iterates over all nodes of the tree whose KE includes the given `key`.
117    ///
118    /// Note that nodes without a `Weight` will also be yielded by the iterator.
119    ///
120    /// You can obtain an iterator over key-value pairs using `iter.filter_map(|node| node.weight.map(|w| (node.keyexpr(), w)))`,
121    /// keep in mind that the full keyexpr of nodes is not stored in them by default, but computed using the tree:
122    /// if you need to get a node's key often, inserting its keyexpr in the `Weight` could be a good idea.
123    fn nodes_including(&'a self, key: &'a keyexpr) -> Self::Includer;
124
125    /// Returns an iterator over the KEs contained in the tree that include `key`
126    fn keys_including(&'a self, key: &'a keyexpr) -> Keys<Self::Includer, Self::IncluderItem>
127    where
128        Self::IncluderItem: AsNode<Self::Node>,
129        Self::Node: IKeyExprTreeNode<Weight>,
130    {
131        self.nodes_including(key)
132            .filter_map(filter_map_weighted_node_to_key)
133    }
134}
135
136/// The basic mutable methods of all KeTrees.
137pub trait IKeyExprTreeMut<'a, Weight>: IKeyExprTree<'a, Weight> {
138    /// Mutably accesses the node at `key` if it exists, treating KEs as if they were completely verbatim keys.
139    ///
140    /// Returns `None` if `key` is not present. Use [`IKeyExprTreeMut::node_mut_or_create`] if you wish to construct the node if it doesn't exist.
141    fn node_mut<'b>(&'b mut self, key: &keyexpr) -> Option<&'b mut Self::Node>;
142
143    /// Returns a mutable reference to the weight of the node at `key`.
144    fn weight_at_mut(&'a mut self, key: &keyexpr) -> Option<&'a mut Weight> {
145        self.node_mut(key)
146            .and_then(<Self::Node as IKeyExprTreeNodeMut<Weight>>::weight_mut)
147    }
148
149    /// Mutably accesses the node at `key`, creating it if necessary.
150    fn node_mut_or_create<'b>(&'b mut self, key: &keyexpr) -> &'b mut Self::Node;
151
152    /// Inserts a weight at `key`, returning the previous weight if it existed.
153    fn insert(&mut self, key: &keyexpr, weight: Weight) -> Option<Weight> {
154        self.node_mut_or_create(key).insert_weight(weight)
155    }
156
157    /// Clears the weight of the node at `key`, but doesn't actually destroy the node.
158    ///
159    /// To actually destroy nodes, [`IKeyExprTreeMut::prune_where`] or [`IKeyExprTreeMut::prune`] must be called.
160    fn remove(&mut self, key: &keyexpr) -> Option<Weight>;
161
162    type TreeIterItemMut;
163    type TreeIterMut: Iterator<Item = Self::TreeIterItemMut>;
164
165    /// Iterates over the whole tree, including nodes with no weight.
166    fn tree_iter_mut(&'a mut self) -> Self::TreeIterMut;
167
168    type IntersectionItemMut;
169    type IntersectionMut: Iterator<Item = Self::IntersectionItemMut>;
170
171    /// Iterates over all nodes of the tree whose KE intersects with the given `key`.
172    ///
173    /// Note that nodes without a `Weight` will also be yielded by the iterator.
174    fn intersecting_nodes_mut(&'a mut self, key: &'a keyexpr) -> Self::IntersectionMut;
175    type InclusionItemMut;
176    type InclusionMut: Iterator<Item = Self::InclusionItemMut>;
177
178    /// Iterates over all nodes of the tree whose KE is included by the given `key`.
179    ///
180    /// Note that nodes without a `Weight` will also be yielded by the iterator.
181    fn included_nodes_mut(&'a mut self, key: &'a keyexpr) -> Self::InclusionMut;
182    type IncluderItemMut;
183    type IncluderMut: Iterator<Item = Self::IncluderItemMut>;
184
185    /// Iterates over all nodes of the tree whose KE includes the given `key`.
186    ///
187    /// Note that nodes without a `Weight` will also be yielded by the iterator.
188    fn nodes_including_mut(&'a mut self, key: &'a keyexpr) -> Self::IncluderMut;
189    /// Prunes node from the tree where the predicate returns `true`.
190    ///
191    /// Note that nodes that still have children will not be pruned.
192    fn prune_where<F: FnMut(&mut Self::Node) -> bool>(&mut self, predicate: F);
193
194    /// Prunes empty nodes from the tree, unless they have at least one non-empty descendent.
195    fn prune(&mut self) {
196        self.prune_where(|node| node.weight().is_none())
197    }
198}
199/// The basic operations of a KeTree when a Token is necessary to access data.
200pub trait ITokenKeyExprTree<'a, Weight, Token> {
201    /// An immutable guard to a node of the tree.
202    type Node: IKeyExprTreeNode<Weight>;
203    // A mutable guard to a node of the tree.
204    type NodeMut: IKeyExprTreeNodeMut<Weight>;
205
206    /// Accesses the node at `key` if it exists, treating KEs as if they were completely verbatim keys.
207    ///
208    /// Returns `None` if `key` is not present in the KeTree.
209    fn node(&'a self, token: &'a Token, key: &keyexpr) -> Option<Self::Node>;
210
211    /// Mutably accesses the node at `key` if it exists, treating KEs as if they were completely verbatim keys.
212    ///
213    /// Returns `None` if `key` is not present. Use [`IKeyExprTreeMut::node_mut_or_create`] if you wish to construct the node if it doesn't exist.
214    fn node_mut(&'a self, token: &'a mut Token, key: &keyexpr) -> Option<Self::NodeMut>;
215
216    /// Mutably accesses the node at `key`, creating it if necessary.
217    fn node_or_create(&'a self, token: &'a mut Token, key: &keyexpr) -> Self::NodeMut;
218
219    /// Inserts a weight at `key`, returning the previous weight if it existed.
220    fn insert(&'a self, token: &'a mut Token, at: &keyexpr, weight: Weight) -> Option<Weight> {
221        self.node_or_create(token, at).insert_weight(weight)
222    }
223
224    /// Clears the weight of the node at `key`, but doesn't actually destroy the node.
225    ///
226    /// To actually destroy nodes, [`ITokenKeyExprTree::prune_where`] or [`ITokenKeyExprTree::prune`] must be called.
227    fn remove(&'a mut self, token: &'a mut Token, key: &keyexpr) -> Option<Weight> {
228        self.node_mut(token, key)
229            .and_then(|mut node| node.take_weight())
230    }
231
232    type TreeIterItem;
233    type TreeIter: Iterator<Item = Self::TreeIterItem>;
234
235    /// Iterates over the whole tree, including nodes with no weight.
236    fn tree_iter(&'a self, token: &'a Token) -> Self::TreeIter;
237
238    type TreeIterItemMut;
239    type TreeIterMut: Iterator<Item = Self::TreeIterItemMut>;
240
241    /// Iterates over the whole tree, including nodes with no weight.
242    fn tree_iter_mut(&'a self, token: &'a mut Token) -> Self::TreeIterMut;
243
244    type IntersectionItem;
245    type Intersection: Iterator<Item = Self::IntersectionItem>;
246
247    /// Iterates over all nodes of the tree whose KE intersects with the given `key`.
248    ///
249    /// Note that nodes without a `Weight` will also be yielded by the iterator.
250    ///
251    /// You can obtain an iterator over key-value pairs using `iter.filter_map(|node| node.weight.map(|w| (node.keyexpr(), w)))`,
252    /// keep in mind that the full keyexpr of nodes is not stored in them by default, but computed using the tree:
253    /// if you need to get a node's key often, inserting its keyexpr in the `Weight` could be a good idea.
254    fn intersecting_nodes(&'a self, token: &'a Token, key: &'a keyexpr) -> Self::Intersection;
255
256    /// Returns an iterator over the KEs contained in the tree that intersect with `key`
257    fn intersecting_keys(
258        &'a self,
259        token: &'a Token,
260        key: &'a keyexpr,
261    ) -> Keys<Self::Intersection, Self::IntersectionItem>
262    where
263        Self::IntersectionItem: AsNode<Self::Node>,
264        Self::Node: IKeyExprTreeNode<Weight>,
265    {
266        self.intersecting_nodes(token, key)
267            .filter_map(filter_map_weighted_node_to_key)
268    }
269
270    type IntersectionItemMut;
271    type IntersectionMut: Iterator<Item = Self::IntersectionItemMut>;
272
273    /// Iterates over all nodes of the tree whose KE intersects with the given `key`.
274    ///
275    /// Note that nodes without a `Weight` will also be yielded by the iterator.
276    fn intersecting_nodes_mut(
277        &'a self,
278        token: &'a mut Token,
279        key: &'a keyexpr,
280    ) -> Self::IntersectionMut;
281
282    type InclusionItem;
283    type Inclusion: Iterator<Item = Self::InclusionItem>;
284
285    /// Iterates over all nodes of the tree whose KE is included by the given `key`.
286    ///
287    /// Note that nodes without a `Weight` will also be yielded by the iterator.
288    fn included_nodes(&'a self, token: &'a Token, key: &'a keyexpr) -> Self::Inclusion;
289
290    /// Returns an iterator over the KEs contained in the tree that are included by `key`
291    fn included_keys(
292        &'a self,
293        token: &'a Token,
294        key: &'a keyexpr,
295    ) -> Keys<Self::Inclusion, Self::InclusionItem>
296    where
297        Self::InclusionItem: AsNode<Self::Node>,
298        Self::Node: IKeyExprTreeNode<Weight>,
299    {
300        self.included_nodes(token, key)
301            .filter_map(filter_map_weighted_node_to_key)
302    }
303
304    type InclusionItemMut;
305    type InclusionMut: Iterator<Item = Self::InclusionItemMut>;
306
307    /// Iterates over all nodes of the tree whose KE is included by the given `key`.
308    ///
309    /// Note that nodes without a `Weight` will also be yielded by the iterator.
310    fn included_nodes_mut(&'a self, token: &'a mut Token, key: &'a keyexpr) -> Self::InclusionMut;
311
312    type IncluderItem;
313    type Includer: Iterator<Item = Self::IncluderItem>;
314
315    /// Iterates over all nodes of the tree whose KE includes the given `key`.
316    ///
317    /// Note that nodes without a `Weight` will also be yielded by the iterator.
318    fn nodes_including(&'a self, token: &'a Token, key: &'a keyexpr) -> Self::Includer;
319
320    /// Returns an iterator over the KEs contained in the tree that include `key`
321    fn keys_including(
322        &'a self,
323        token: &'a Token,
324        key: &'a keyexpr,
325    ) -> Keys<Self::Includer, Self::IncluderItem>
326    where
327        Self::IncluderItem: AsNode<Self::Node>,
328        Self::Node: IKeyExprTreeNode<Weight>,
329    {
330        self.nodes_including(token, key)
331            .filter_map(filter_map_weighted_node_to_key)
332    }
333
334    type IncluderItemMut;
335    type IncluderMut: Iterator<Item = Self::IncluderItemMut>;
336
337    /// Iterates over all nodes of the tree whose KE includes the given `key`.
338    ///
339    /// Note that nodes without a `Weight` will also be yielded by the iterator.
340    fn nodes_including_mut(&'a self, token: &'a mut Token, key: &'a keyexpr) -> Self::IncluderMut;
341
342    type PruneNode: IKeyExprTreeNodeMut<Weight>;
343
344    fn prune_where<F: FnMut(&mut Self::PruneNode) -> bool>(&self, token: &mut Token, predicate: F);
345    fn prune(&self, token: &mut Token) {
346        self.prune_where(token, |node| node.weight().is_none())
347    }
348}
349
350/// The non-mutating methods of a KeTree node.
351pub trait IKeyExprTreeNode<Weight>: UIKeyExprTreeNode<Weight> {
352    /// Access the parent node if it exists (the node isn't the first chunk of a key-expression).
353    fn parent(&self) -> Option<&Self::Parent> {
354        // SAFETY: upheld by the surrounding invariants and prior validation.
355        unsafe { self.__parent() }
356    }
357    /// Compute this node's full key expression.
358    ///
359    /// Note that KeTrees don't normally store each node's full key expression.
360    /// If you need to repeatedly access a node's full key expression, it is suggested
361    /// to store that key expression as part of the node's `Weight` (it's optional value).
362    fn keyexpr(&self) -> OwnedKeyExpr {
363        // SAFETY: upheld by the surrounding invariants and prior validation.
364        unsafe { self.__keyexpr() }
365    }
366
367    /// Access the node's weight (or value).
368    ///
369    /// Weights can be assigned to a node through many of [`IKeyExprTreeNodeMut`]'s methods, as well as through [`IKeyExprTreeMut::insert`].
370    ///
371    /// Nodes may not have a value in any of the following cases:
372    /// - The node is a parent to other nodes, but was never assigned a weight itself (or that weight has been removed).
373    /// - The node is a leaf of the KeTree whose value was [`IKeyExprTreeMut::remove`]d, but [`IKeyExprTreeMut::prune`] hasn't been called yet.
374    fn weight(&self) -> Option<&Weight> {
375        // SAFETY: upheld by the surrounding invariants and prior validation.
376        unsafe { self.__weight() }
377    }
378
379    /// Access a node's children.
380    fn children(&self) -> &Self::Children {
381        // SAFETY: upheld by the surrounding invariants and prior validation.
382        unsafe { self.__children() }
383    }
384}
385
386#[doc(hidden)]
387pub trait UIKeyExprTreeNode<Weight> {
388    type Parent;
389    /// # Safety
390    /// Implementations may return references derived from internal raw pointers or token-guarded state.
391    /// Callers must uphold the implementation-specific aliasing and lifetime guarantees.
392    unsafe fn __parent(&self) -> Option<&Self::Parent>;
393    /// # Safety
394    /// Implementations may reconstruct the full key expression from internal state that must remain valid.
395    /// Callers must ensure the node is in a readable, non-invalidated state.
396    unsafe fn __keyexpr(&self) -> OwnedKeyExpr;
397    /// # Safety
398    /// Implementations may expose internal references whose validity depends on external synchronization/token rules.
399    /// Callers must uphold those rules.
400    unsafe fn __weight(&self) -> Option<&Weight>;
401    type Child;
402    type Children: IChildren<Self::Child>;
403    /// # Safety
404    /// Implementations may expose references to internal child collections that require external synchronization/token rules.
405    /// Callers must uphold those rules.
406    unsafe fn __children(&self) -> &Self::Children;
407}
408
409/// The mutating methods of a KeTree node.
410pub trait IKeyExprTreeNodeMut<Weight>: IKeyExprTreeNode<Weight> {
411    /// Mutably access the parent node if it exists (the node isn't the first chunk of a key-expression).
412    fn parent_mut(&mut self) -> Option<&mut Self::Parent>;
413
414    /// Mutably access the node's weight.
415    fn weight_mut(&mut self) -> Option<&mut Weight>;
416
417    /// Remove the node's weight.
418    fn take_weight(&mut self) -> Option<Weight>;
419
420    /// Assign a weight to the node, returning the previous weight if the node had one.
421    fn insert_weight(&mut self, weight: Weight) -> Option<Weight>;
422
423    /// Mutably access the node's children.
424    fn children_mut(&mut self) -> &mut Self::Children;
425}
426
427/// Nodes from a token-locked tree need a token to obtain read/write permissions.
428///
429/// This trait allows tokenizing a node, allowing to use [`IKeyExprTreeNode`] and [`IKeyExprTreeNodeMut`]'s methods on it.
430pub trait ITokenKeyExprTreeNode<'a, Weight, Token> {
431    type Tokenized: IKeyExprTreeNode<Weight>;
432    /// Wrap the node with the an immutable reference to the token to allow immutable access to its contents.
433    fn tokenize(&'a self, token: &'a Token) -> Self::Tokenized;
434    type TokenizedMut: IKeyExprTreeNodeMut<Weight>;
435    /// Wrap the node with a mutable reference to the token to allow mutable access to its contents
436    fn tokenize_mut(&'a self, token: &'a mut Token) -> Self::TokenizedMut;
437}
438impl<'a, T: 'a, Weight, Token: 'a> ITokenKeyExprTreeNode<'a, Weight, Token> for T
439where
440    (&'a T, &'a Token): IKeyExprTreeNode<Weight>,
441    (&'a T, &'a mut Token): IKeyExprTreeNodeMut<Weight>,
442{
443    type Tokenized = (&'a T, &'a Token);
444    fn tokenize(&'a self, token: &'a Token) -> Self::Tokenized {
445        (self, token)
446    }
447    type TokenizedMut = (&'a T, &'a mut Token);
448    fn tokenize_mut(&'a self, token: &'a mut Token) -> Self::TokenizedMut {
449        (self, token)
450    }
451}
452
453/// Provides a data-structure to store children to the KeTree.
454pub trait IChildrenProvider<T> {
455    type Assoc: Default + 'static;
456}
457
458pub trait IChildren<T: ?Sized> {
459    type Node: HasChunk + AsNode<T> + AsNodeMut<T>;
460    fn len(&self) -> usize;
461    fn is_empty(&self) -> bool {
462        self.len() == 0
463    }
464    fn child_at<'a>(&'a self, chunk: &keyexpr) -> Option<&'a Self::Node>;
465    fn child_at_mut<'a>(&'a mut self, chunk: &keyexpr) -> Option<&'a mut Self::Node>;
466    type Entry<'a, 'b>: IEntry<'a, 'b, T>
467    where
468        Self: 'a,
469        'a: 'b,
470        T: 'b;
471    fn remove(&mut self, chunk: &keyexpr) -> Option<Self::Node>;
472    fn entry<'a, 'b>(&'a mut self, chunk: &'b keyexpr) -> Self::Entry<'a, 'b>
473    where
474        Self: 'a + 'b,
475        T: 'b;
476    type Iter<'a>: Iterator<Item = &'a Self::Node>
477    where
478        Self: 'a,
479        Self::Node: 'a;
480    fn children<'a>(&'a self) -> Self::Iter<'a>
481    where
482        Self: 'a;
483    type IterMut<'a>: Iterator<Item = &'a mut Self::Node>
484    where
485        Self: 'a,
486        Self::Node: 'a;
487    fn children_mut<'a>(&'a mut self) -> Self::IterMut<'a>
488    where
489        Self: 'a;
490    type Intersection<'a>: Iterator<Item = &'a Self::Node>
491    where
492        Self: 'a,
493        Self::Node: 'a;
494    fn intersection<'a>(&'a self, key: &'a keyexpr) -> Self::Intersection<'a>;
495    type IntersectionMut<'a>: Iterator<Item = &'a mut Self::Node>
496    where
497        Self: 'a,
498        Self::Node: 'a;
499    fn intersection_mut<'a>(&'a mut self, key: &'a keyexpr) -> Self::IntersectionMut<'a>;
500    type Inclusion<'a>: Iterator<Item = &'a Self::Node>
501    where
502        Self: 'a,
503        Self::Node: 'a;
504    fn inclusion<'a>(&'a self, key: &'a keyexpr) -> Self::Inclusion<'a>;
505    type InclusionMut<'a>: Iterator<Item = &'a mut Self::Node>
506    where
507        Self: 'a,
508        Self::Node: 'a;
509    fn inclusion_mut<'a>(&'a mut self, key: &'a keyexpr) -> Self::InclusionMut<'a>;
510    fn filter_out<F: FnMut(&mut T) -> bool>(&mut self, predicate: &mut F);
511}
512
513pub trait IEntry<'a, 'b, T: ?Sized> {
514    fn get_or_insert_with<F: FnOnce(&'b keyexpr) -> T>(self, f: F) -> &'a mut T;
515}
516
517pub trait HasChunk {
518    fn chunk(&self) -> &keyexpr;
519}
520
521pub trait AsNode<T: ?Sized> {
522    fn as_node(&self) -> &T;
523}
524pub trait AsNodeMut<T: ?Sized>: AsNode<T> {
525    fn as_node_mut(&mut self) -> &mut T;
526}
527
528type Keys<I, Item> = core::iter::FilterMap<I, fn(Item) -> Option<OwnedKeyExpr>>;
529fn filter_map_weighted_node_to_key<N: IKeyExprTreeNode<W>, I: AsNode<N>, W>(
530    item: I,
531) -> Option<OwnedKeyExpr> {
532    let node: &N = item.as_node();
533    node.weight().is_some().then(|| node.keyexpr())
534}