Skip to main content

winreg_core/
iter.rs

1//! Key iterators — BFS and DFS traversal of the registry tree.
2
3use std::collections::VecDeque;
4use std::io::Cursor;
5
6use crate::error::Result;
7use crate::hive::Hive;
8use crate::key::Key;
9
10/// Breadth-first iterator over all keys in the hive.
11pub struct BfsIter<'h> {
12    queue: VecDeque<Key<'h>>,
13}
14
15impl<'h> BfsIter<'h> {
16    pub fn new(hive: &'h Hive<Cursor<Vec<u8>>>) -> Result<Self> {
17        let root = hive.root_key()?;
18        let mut queue = VecDeque::new();
19        queue.push_back(root);
20        Ok(Self { queue })
21    }
22}
23
24impl<'h> Iterator for BfsIter<'h> {
25    type Item = Result<Key<'h>>;
26
27    fn next(&mut self) -> Option<Self::Item> {
28        let key = self.queue.pop_front()?;
29        match key.subkeys() {
30            Ok(children) => {
31                for child in children {
32                    self.queue.push_back(child);
33                }
34                Some(Ok(key))
35            }
36            Err(e) => Some(Err(e)),
37        }
38    }
39}
40
41/// Depth-first (pre-order) iterator over all keys in the hive.
42pub struct DfsIter<'h> {
43    stack: Vec<Key<'h>>,
44}
45
46impl<'h> DfsIter<'h> {
47    pub fn new(hive: &'h Hive<Cursor<Vec<u8>>>) -> Result<Self> {
48        let root = hive.root_key()?;
49        Ok(Self { stack: vec![root] })
50    }
51}
52
53impl<'h> Iterator for DfsIter<'h> {
54    type Item = Result<Key<'h>>;
55
56    fn next(&mut self) -> Option<Self::Item> {
57        let key = self.stack.pop()?;
58        match key.subkeys() {
59            Ok(children) => {
60                for child in children.into_iter().rev() {
61                    self.stack.push(child);
62                }
63                Some(Ok(key))
64            }
65            Err(e) => Some(Err(e)),
66        }
67    }
68}
69
70impl Hive<Cursor<Vec<u8>>> {
71    /// Iterate all keys in breadth-first order.
72    pub fn iter_bfs(&self) -> Result<BfsIter<'_>> {
73        BfsIter::new(self)
74    }
75
76    /// Iterate all keys in depth-first (pre-order) order.
77    pub fn iter_dfs(&self) -> Result<DfsIter<'_>> {
78        DfsIter::new(self)
79    }
80}