1use crate::RuleFormat;
4use crate::discover::ToolRuleDir;
5use std::path::{Path, PathBuf};
6
7#[derive(Debug, Clone)]
9pub struct DiscoveredFile {
10 pub path: PathBuf,
12 pub relative: PathBuf,
14 pub format: RuleFormat,
16}
17
18pub fn walk_tool_dir(
20 root: &Path,
21 dir: &ToolRuleDir,
22) -> Result<Vec<DiscoveredFile>, std::io::Error> {
23 let mut files = Vec::new();
24 walk_recursive(root, root, dir, &mut files)?;
25 files.sort_by(|a, b| a.relative.cmp(&b.relative));
26 Ok(files)
27}
28
29fn walk_recursive(
30 root: &Path,
31 current: &Path,
32 dir: &ToolRuleDir,
33 files: &mut Vec<DiscoveredFile>,
34) -> Result<(), std::io::Error> {
35 if !current.is_dir() {
36 return Ok(());
37 }
38
39 for entry in std::fs::read_dir(current)? {
40 let entry = entry?;
41 let path = entry.path();
42 if path.is_dir() {
43 walk_recursive(root, &path, dir, files)?;
44 } else if matches_rule_file(&path, dir) {
45 let relative = path.strip_prefix(root).unwrap_or(&path).to_path_buf();
46 files.push(DiscoveredFile {
47 path: path.clone(),
48 relative,
49 format: dir.format,
50 });
51 }
52 }
53 Ok(())
54}
55
56fn matches_rule_file(path: &Path, dir: &ToolRuleDir) -> bool {
57 let file_name = match path.file_name().and_then(|n| n.to_str()) {
58 Some(n) => n,
59 None => return false,
60 };
61
62 if let Some(suffix) = dir.suffix {
63 return file_name.ends_with(suffix);
64 }
65
66 path.extension()
67 .and_then(|e| e.to_str())
68 .is_some_and(|ext| dir.extensions.contains(&ext))
69}
70
71pub fn walk_md_files(root: &Path) -> Result<Vec<PathBuf>, std::io::Error> {
73 let mut files = Vec::new();
74 walk_md_recursive(root, &mut files)?;
75 files.sort();
76 Ok(files)
77}
78
79fn walk_md_recursive(current: &Path, files: &mut Vec<PathBuf>) -> Result<(), std::io::Error> {
80 if !current.is_dir() {
81 return Ok(());
82 }
83 for entry in std::fs::read_dir(current)? {
84 let entry = entry?;
85 let path = entry.path();
86 if path.is_dir() {
87 walk_md_recursive(&path, files)?;
88 } else if path.extension().and_then(|e| e.to_str()) == Some("md") {
89 files.push(path);
90 }
91 }
92 Ok(())
93}