Skip to main content

rs_hack/
visitor.rs

1//! AST visitor that walks syn trees to collect node matches
2//! (structs, enums, functions, match expressions).
3
4use syn::visit::Visit;
5use syn::{*, spanned::Spanned};
6
7#[allow(dead_code)]
8pub struct NodeFinder {
9    pub matches: Vec<NodeMatch>,
10}
11
12#[derive(Debug, Clone)]
13#[allow(dead_code)]
14pub enum NodeMatch {
15    Struct { name: String, span: proc_macro2::Span },
16    Enum { name: String, span: proc_macro2::Span },
17    Function { name: String, span: proc_macro2::Span },
18    MatchExpr { span: proc_macro2::Span },
19}
20
21#[allow(dead_code)]
22impl NodeFinder {
23    pub fn new() -> Self {
24        Self {
25            matches: Vec::new(),
26        }
27    }
28}
29
30impl<'ast> Visit<'ast> for NodeFinder {
31    fn visit_item_struct(&mut self, node: &'ast ItemStruct) {
32        self.matches.push(NodeMatch::Struct {
33            name: node.ident.to_string(),
34            span: node.span(),
35        });
36        syn::visit::visit_item_struct(self, node);
37    }
38    
39    fn visit_item_enum(&mut self, node: &'ast ItemEnum) {
40        self.matches.push(NodeMatch::Enum {
41            name: node.ident.to_string(),
42            span: node.span(),
43        });
44        syn::visit::visit_item_enum(self, node);
45    }
46    
47    fn visit_item_fn(&mut self, node: &'ast ItemFn) {
48        self.matches.push(NodeMatch::Function {
49            name: node.sig.ident.to_string(),
50            span: node.span(),
51        });
52        syn::visit::visit_item_fn(self, node);
53    }
54    
55    fn visit_expr_match(&mut self, node: &'ast ExprMatch) {
56        self.matches.push(NodeMatch::MatchExpr {
57            span: node.span(),
58        });
59        syn::visit::visit_expr_match(self, node);
60    }
61}