Skip to main content

prefix_trie/
fmt.rs

1//! Debug formatting for PrefixMap.
2//!
3//! The output hides the internal TreeBitMap structure and shows the logical prefix trie,
4//! matching the style of PrefixMap's debug output.
5
6use std::fmt::{Debug, Formatter, Result};
7
8use crate::{Prefix, PrefixMap};
9
10impl<P: Prefix + Debug, T: Debug> Debug for PrefixMap<P, T> {
11    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
12        let entries: Vec<(P, &T)> = self.iter().collect();
13        DebugSubtree { entries: &entries }.fmt(f)
14    }
15}
16
17struct DebugSubtree<'a, P, T> {
18    entries: &'a [(P, &'a T)],
19}
20
21struct DebugExtendedNode<'a, P, T> {
22    value: &'a T,
23    children: DebugSubtree<'a, P, T>,
24}
25
26impl<P: Prefix + Debug, T: Debug> Debug for DebugExtendedNode<'_, P, T> {
27    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
28        let mut d = f.debug_struct("");
29        d.field("value", self.value);
30        if !self.children.entries.is_empty() {
31            d.field("children", &self.children);
32        }
33        d.finish()
34    }
35}
36
37impl<P: Prefix + Debug, T: Debug> Debug for DebugSubtree<'_, P, T> {
38    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
39        let mut dm = f.debug_map();
40        let mut entries = self.entries;
41
42        while let Some(((prefix, value), rest)) = entries.split_first() {
43            let child_count = rest.iter().take_while(|(p, _)| prefix.contains(p)).count();
44            let (children, remaining) = rest.split_at(child_count);
45            entries = remaining;
46
47            dm.entry(
48                prefix,
49                &DebugExtendedNode {
50                    value: *value,
51                    children: DebugSubtree { entries: children },
52                },
53            );
54        }
55
56        dm.finish()
57    }
58}