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}