Skip to main content

stern4rust/
source_walker.rs

1// Copyright 2025 Umberto Gotti <umberto.gotti@umbertogotti.dev>
2// Licensed under the MIT License
3// SPDX-License-Identifier: MIT
4
5use std::path::Path;
6use std::path::PathBuf;
7
8use walkdir::WalkDir;
9
10// Every .rs file under a package, tests included.
11//
12// "Every .rs file" is the rule's own wording, so src/ and tests/ are both in
13// scope -- a test file without the header is exactly as wrong as a source file
14// without it. target/ is skipped because it holds generated code nobody wrote
15// and build scripts write files there that no rule should judge.
16//
17// Nothing else is skipped. An earlier version also skipped any directory
18// holding its own Cargo.toml, so that a fixture crate nested under
19// tests/fixtures/ would not be judged as though this package had written it.
20// That was the wrong place to solve it: sample code a tool analyses does not
21// belong inside the package that ships, and a linter quietly declining to look
22// at part of a tree is the kind of silence this tool exists to refuse. The fix
23// belongs in the layout -- fixtures live beside the package, not within it --
24// and where a tree genuinely cannot be moved, in an explicit exclusion the
25// reader can see in the report.
26pub struct SourceWalker;
27
28impl SourceWalker {
29    pub fn walk(root: &Path) -> Vec<PathBuf> {
30        let mut paths: Vec<PathBuf> = WalkDir::new(root)
31            .into_iter()
32            .filter_entry(|entry| !Self::is_skipped(entry.path()))
33            .filter_map(Result::ok)
34            .filter(|entry| entry.file_type().is_file())
35            .map(|entry| entry.into_path())
36            .filter(|path| path.extension().is_some_and(|extension| extension == "rs"))
37            .collect();
38        paths.sort();
39        paths
40    }
41
42    fn is_skipped(path: &Path) -> bool {
43        matches!(
44            path.file_name().and_then(|name| name.to_str()),
45            Some("target") | Some(".git")
46        )
47    }
48}