1use syn::spanned::Spanned;
5use syn::visit::Visit;
6use syn::*;
7
8#[allow(dead_code)]
9pub struct NodeFinder {
10 pub matches: Vec<NodeMatch>,
11}
12
13#[derive(Debug, Clone)]
14#[allow(dead_code)]
15pub enum NodeMatch {
16 Struct {
17 name: String,
18 span: proc_macro2::Span,
19 },
20 Enum {
21 name: String,
22 span: proc_macro2::Span,
23 },
24 Function {
25 name: String,
26 span: proc_macro2::Span,
27 },
28 MatchExpr {
29 span: proc_macro2::Span,
30 },
31}
32
33#[allow(dead_code)]
34impl Default for NodeFinder {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl NodeFinder {
41 pub const fn new() -> Self {
42 Self {
43 matches: Vec::new(),
44 }
45 }
46}
47
48impl<'ast> Visit<'ast> for NodeFinder {
49 fn visit_item_struct(&mut self, node: &'ast ItemStruct) {
50 self.matches.push(NodeMatch::Struct {
51 name: node.ident.to_string(),
52 span: node.span(),
53 });
54 syn::visit::visit_item_struct(self, node);
55 }
56
57 fn visit_item_enum(&mut self, node: &'ast ItemEnum) {
58 self.matches.push(NodeMatch::Enum {
59 name: node.ident.to_string(),
60 span: node.span(),
61 });
62 syn::visit::visit_item_enum(self, node);
63 }
64
65 fn visit_item_fn(&mut self, node: &'ast ItemFn) {
66 self.matches.push(NodeMatch::Function {
67 name: node.sig.ident.to_string(),
68 span: node.span(),
69 });
70 syn::visit::visit_item_fn(self, node);
71 }
72
73 fn visit_expr_match(&mut self, node: &'ast ExprMatch) {
74 self.matches
75 .push(NodeMatch::MatchExpr { span: node.span() });
76 syn::visit::visit_expr_match(self, node);
77 }
78}