stern4rust/
registry_parser.rs1use syn::Item;
6use syn::parse_file;
7use syn::spanned::Spanned;
8
9use crate::registry_item::RegistryItem;
10use crate::registry_policy::RegistryPolicy;
11use crate::source_file::SourceFile;
12
13pub struct RegistryParser;
20
21impl RegistryParser {
22 pub fn strays(file: &SourceFile, policy: RegistryPolicy) -> Option<Vec<RegistryItem>> {
25 let syntax = parse_file(&file.contents()).ok()?;
26 Some(
27 syntax
28 .items
29 .iter()
30 .filter(|item| !policy.is_declaration(item))
31 .map(|item| Self::stray(file, item))
32 .collect(),
33 )
34 }
35
36 fn stray(file: &SourceFile, item: &Item) -> RegistryItem {
37 let line = item.span().start().line;
38 RegistryItem::new(line, &Self::label(file, item, line))
39 }
40
41 fn label(file: &SourceFile, item: &Item, line: usize) -> String {
46 match item {
47 Item::Const(inner) => format!("the constant `{}`", inner.ident),
48 Item::Enum(inner) => format!("the enum `{}`", inner.ident),
49 Item::Fn(inner) => format!("the function `{}`", inner.sig.ident),
50 Item::Impl(_) => format!("the impl block `{}`", Self::source_line(file, line)),
51 Item::Mod(inner) => format!("the inline module `{}`", inner.ident),
52 Item::Static(inner) => format!("the static `{}`", inner.ident),
53 Item::Struct(inner) => format!("the struct `{}`", inner.ident),
54 Item::Trait(inner) => format!("the trait `{}`", inner.ident),
55 Item::Type(inner) => format!("the type alias `{}`", inner.ident),
56 Item::Use(_) => format!("the import `{}`", Self::source_line(file, line)),
57 _ => format!("`{}`", Self::source_line(file, line)),
58 }
59 }
60
61 fn source_line(file: &SourceFile, line: usize) -> String {
62 file.lines()
63 .get(line.saturating_sub(1))
64 .map_or_else(String::new, |text| text.trim().to_string())
65 }
66}