microcad_lang/resolve/symbol/
iterators.rs1use crate::resolve::*;
7
8pub struct Children {
10 symbol: Symbol,
11 index: usize,
12}
13
14impl Children {
15 pub fn new(symbol: Symbol) -> Self {
17 Self { symbol, index: 0 }
18 }
19}
20
21impl Iterator for Children {
22 type Item = Symbol;
23
24 fn next(&mut self) -> Option<Self::Item> {
25 let symbol = self.symbol.inner.borrow();
26 let child = symbol
27 .children
28 .get_index(self.index)
29 .map(|(_, child)| child);
30 self.index += 1;
31 child.cloned()
32 }
33}
34
35pub struct RecurseChildren {
37 stack: Symbols,
38}
39
40impl RecurseChildren {
41 pub(crate) fn new(symbol: Symbol) -> Self {
43 Self {
44 stack: vec![symbol].into(),
45 }
46 }
47}
48
49impl Iterator for RecurseChildren {
50 type Item = Symbol;
51
52 fn next(&mut self) -> Option<Self::Item> {
53 if let Some(symbol) = self.stack.pop() {
54 self.stack
55 .extend(symbol.inner.borrow().children.values().rev().cloned());
56
57 Some(symbol)
58 } else {
59 None
60 }
61 }
62}
63
64#[test]
65fn test_recurse_children() {
66 use crate::rc::*;
67
68 let mut root = Symbol::new(
69 SymbolDef::SourceFile(Rc::new(SourceFile::new(
70 None,
71 StatementList::default(),
72 String::new(),
73 0,
74 ))),
75 None,
76 );
77
78 let mut foo = Symbol::new(
79 SymbolDef::Tester(Identifier::no_ref("foo")),
80 Some(root.clone()),
81 );
82 {
83 let mut baz = Symbol::new(
84 SymbolDef::Tester(Identifier::no_ref("baz")),
85 Some(foo.clone()),
86 );
87 {
88 let bam = Symbol::new(
89 SymbolDef::Tester(Identifier::no_ref("bam")),
90 Some(baz.clone()),
91 );
92 baz.add_symbol(bam).expect("test error");
93 }
94
95 foo.add_symbol(baz).expect("test error");
96 }
97 root.add_symbol(foo).expect("test error");
98
99 let bar = Symbol::new(
100 SymbolDef::Tester(Identifier::no_ref("bar")),
101 Some(root.clone()),
102 );
103 root.add_symbol(bar).expect("test error");
104
105 let s = root
106 .riter()
107 .map(|symbol| format!("{}", symbol.id()))
108 .collect::<Vec<_>>()
109 .join(" ");
110
111 assert_eq!(s, "<NO ID> foo baz bam bar");
112}