cairo_lang_syntax/node/
with_db.rs

1use cairo_lang_primitive_token::{PrimitiveSpan, PrimitiveToken, ToPrimitiveTokenStream};
2
3use super::SyntaxNode;
4use super::db::SyntaxGroup;
5
6pub struct SyntaxNodeWithDb<'a, Db: SyntaxGroup> {
7    node: &'a SyntaxNode,
8    db: &'a Db,
9}
10
11impl<'a, Db: SyntaxGroup> SyntaxNodeWithDb<'a, Db> {
12    pub fn new(node: &'a SyntaxNode, db: &'a Db) -> Self {
13        Self { node, db }
14    }
15}
16
17impl<'a, Db: SyntaxGroup> ToPrimitiveTokenStream for SyntaxNodeWithDb<'a, Db> {
18    type Iter = SyntaxNodeWithDbIterator<'a, Db>;
19
20    fn to_primitive_token_stream(&self) -> Self::Iter {
21        // The lifetime of the iterator should extend 'a because it derives from both node and db
22        SyntaxNodeWithDbIterator::new(Box::new(self.node.tokens(self.db)), self.db)
23    }
24}
25
26pub struct SyntaxNodeWithDbIterator<'a, Db: SyntaxGroup> {
27    inner: Box<dyn Iterator<Item = SyntaxNode> + 'a>,
28    db: &'a Db,
29}
30
31impl<'a, Db: SyntaxGroup> SyntaxNodeWithDbIterator<'a, Db> {
32    pub fn new(inner: Box<dyn Iterator<Item = SyntaxNode> + 'a>, db: &'a Db) -> Self {
33        Self { inner, db }
34    }
35}
36
37impl<Db: SyntaxGroup> Iterator for SyntaxNodeWithDbIterator<'_, Db> {
38    type Item = PrimitiveToken;
39
40    fn next(&mut self) -> Option<Self::Item> {
41        self.inner.next().map(|node| {
42            let span = node.span(self.db).to_str_range();
43            PrimitiveToken {
44                content: node.get_text(self.db),
45                span: Some(PrimitiveSpan { start: span.start, end: span.end }),
46            }
47        })
48    }
49}