stern4rust/finding/parsing/
registry_parser.rs1use syn::Item;
6use syn::parse_file;
7use syn::spanned::Spanned;
8
9use crate::finding::model::registry_item::RegistryItem;
10use crate::finding::model::registry_policy::RegistryPolicy;
11use crate::finding::parsing::item_naming::ItemNaming;
12use crate::source_file::SourceFile;
13
14pub struct RegistryParser;
21
22impl RegistryParser {
23 pub fn strays(file: &SourceFile, policy: RegistryPolicy) -> Option<Vec<RegistryItem>> {
26 let syntax = parse_file(&file.contents()).ok()?;
27 Some(
28 syntax
29 .items
30 .iter()
31 .filter(|item| !policy.is_declaration(item))
32 .map(|item| Self::stray(file, item))
33 .collect(),
34 )
35 }
36
37 fn stray(file: &SourceFile, item: &Item) -> RegistryItem {
38 let line = item.span().start().line;
39 RegistryItem::new(line, &Self::label(file, item, line))
40 }
41
42 fn label(file: &SourceFile, item: &Item, line: usize) -> String {
50 let Some(kind) = Self::kind(item) else {
51 return format!("`{}`", ItemNaming::source_line(file, line));
52 };
53 let subject =
54 ItemNaming::identifier(item).unwrap_or_else(|| ItemNaming::source_line(file, line));
55 format!("the {kind} `{subject}`")
56 }
57
58 fn kind(item: &Item) -> Option<&'static str> {
59 match item {
60 Item::Const(_) => Some("constant"),
61 Item::Enum(_) => Some("enum"),
62 Item::Fn(_) => Some("function"),
63 Item::Impl(_) => Some("impl block"),
64 Item::Mod(_) => Some("inline module"),
65 Item::Static(_) => Some("static"),
66 Item::Struct(_) => Some("struct"),
67 Item::Trait(_) => Some("trait"),
68 Item::Type(_) => Some("type alias"),
69 Item::Use(_) => Some("import"),
70 _ => None,
71 }
72 }
73}