kserd/nav/mod.rs
1//! Navigate around a [`Kserd`].
2//!
3//! # Reading
4//! It is cumbersome when trying to loop through a nested `Kserd` structure. There is a [`Navigator`]
5//! structure that can be used that flattens the tree structure when constructed to make use of
6//! indexing and iterators throughout the `Kserd`.
7//!
8//! [`Kserd`]: crate::Kserd
9//! [`Navigator`]: crate::nav::Navigator
10// TODO: Lifetimes should be scoped to the borrowed kserd as much as possible.
11// TODO: Can probably remove the 'node lifetime, as it is borrowed from the Navigator
12use super::*;
13
14mod navigator;
15mod node;
16mod value;
17
18/// A structure to efficiently navigate through a [`Kserd`].
19///
20/// When trying to interrogate a `Kserd` it can become cumbersome to loop through nested children.
21/// The `Navigator` provides a structure around a root `Kserd` which then allows for efficient
22/// looping through the structure.
23///
24/// When a `Navigator` is constructed it flattens the tree structure into a depth-first vector,
25/// wrapping each `Kserd` into a [`Node`] which contains navigational information such are parent
26/// or children.
27///
28/// [`Kserd`]: crate::Kserd
29/// [`Node`]: crate::nav::Node
30pub struct Navigator<'a, 'k> {
31 inner: Vec<NodeInner<'a, 'k>>,
32}
33
34/// A node in the [`Kserd`] tree.
35///
36/// A `Node` wraps a pointer to the `Kserd` value, and carries positional information about itself
37/// and surrounding family. As such `Node`s can walk the tree structures, and have uses when
38/// interrogating a `Kserd` data structure.
39///
40/// Since a `Node` carries a reference to the `Navigator` and the `Kserd`, it is a read-only
41/// structure and no mutation can occur.
42///
43/// [`Kserd`]: crate::Kserd
44#[derive(Copy, Clone)]
45pub struct Node<'a, 'k, 'nav, 'node> {
46 nav: &'nav Navigator<'a, 'k>,
47 node: &'node NodeInner<'a, 'k>,
48}
49
50struct NodeInner<'a, 'k> {
51 kserd: &'a Kserd<'k>,
52 idx: usize,
53 parent: Option<usize>,
54 value_idx_in_parent: Option<usize>,
55 key_idx_in_parent: Option<usize>,
56 value_children: Vec<usize>,
57 key_children: Vec<usize>,
58}
59
60/// The node's value type.
61///
62/// Differs to [`Value`] in that it groups primitives, and provides
63/// iterators over nested `Kserd`s that themselves return `Node`s, such that position information
64/// is retained if walking through a `Kserd`.
65///
66/// [`Value`]: crate::Value
67pub enum NodeValue<'a, 'k, 'nav, 'node> {
68 /// A primitive value.
69 Primitive,
70 /// A tuple value.
71 Tuple(SeqIter<'a, 'k, 'nav, 'node>),
72 /// A container value.
73 Cntr(NamedIter<'a, 'k, 'nav, 'node>),
74 /// A sequence value.
75 Seq(SeqIter<'a, 'k, 'nav, 'node>),
76 /// A map value.
77 Map(KeyedIter<'a, 'k, 'nav, 'node>),
78}
79
80/// Iterator of nodes.
81pub struct NodeIter<'a, 'k, 'nav> {
82 iter: std::slice::Iter<'nav, NodeInner<'a, 'k>>,
83 nav: &'nav Navigator<'a, 'k>,
84}
85
86/// Iterator for sequential items like sequences.
87/// Can be used for keys of maps as well.
88pub struct SeqIter<'a, 'k, 'nav, 'node> {
89 seq: std::slice::Iter<'node, usize>,
90 nav: &'nav Navigator<'a, 'k>,
91}
92
93/// Iterator for named items like in containers.
94pub struct NamedIter<'a, 'k, 'nav, 'node> {
95 names: std::collections::btree_map::Keys<'node, Kstr<'k>, Kserd<'k>>,
96 values: std::slice::Iter<'node, usize>,
97 nav: &'nav Navigator<'a, 'k>,
98}
99
100/// Iterator for keyed items like in maps.
101pub struct KeyedIter<'a, 'k, 'nav, 'node> {
102 keys: std::slice::Iter<'node, usize>,
103 values: std::slice::Iter<'node, usize>,
104 nav: &'nav Navigator<'a, 'k>,
105}