use std::path::{Path, PathBuf};
pub(super) fn find_subdir(dir: &Path, suffix: &str) -> Option<PathBuf> {
let candidate = if suffix.len() == 13 {
format!("{}-", suffix.to_ascii_uppercase())
} else if let Ok(n) = suffix.parse::<u32>() {
format!("{n:04}-")
} else {
format!("{suffix}-")
};
std::fs::read_dir(dir).ok()?.find_map(|e| {
let path = e.ok()?.path();
(path.is_dir() && path.file_name()?.to_string_lossy().starts_with(&candidate))
.then_some(path)
})
}
pub(super) fn directory_prefix(suffix: &str) -> String {
if suffix.len() == 13 {
return suffix.to_ascii_uppercase();
}
if let Ok(n) = suffix.parse::<u32>() {
return format!("{n:04}");
}
suffix.to_ascii_uppercase()
}
pub(super) fn collect_index_paths(dir: &Path) -> anyhow::Result<Vec<PathBuf>> {
if !dir.exists() {
return Ok(vec![]);
}
let mut paths = Vec::new();
for entry in std::fs::read_dir(dir)
.map_err(|e| anyhow::anyhow!("reading directory {}: {e}", dir.display()))?
{
let path = entry?.path();
if path.is_dir() {
let index = path.join("index.md");
if index.exists() {
paths.push(index);
}
}
}
Ok(paths)
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::TempDir;
fn make_subdir(parent: &Path, name: &str) {
std::fs::create_dir(parent.join(name)).unwrap();
}
#[test]
fn find_subdir_returns_matching_directory() {
let tmp = TempDir::new().unwrap();
make_subdir(tmp.path(), "0001-add-login");
let found = find_subdir(tmp.path(), "0001");
assert!(found.is_some());
assert!(found.unwrap().ends_with("0001-add-login"));
}
#[test]
fn find_subdir_pads_short_numeric_suffix_to_four_digits() {
let tmp = TempDir::new().unwrap();
make_subdir(tmp.path(), "0042-foo");
let found = find_subdir(tmp.path(), "42");
assert!(found.is_some());
assert!(found.unwrap().ends_with("0042-foo"));
}
#[test]
fn find_subdir_matches_tsid_prefix() {
let tmp = TempDir::new().unwrap();
make_subdir(tmp.path(), "0DCT3MKW5T2K0-add-login");
let found = find_subdir(tmp.path(), "0DCT3MKW5T2K0");
assert!(found.is_some());
assert!(found.unwrap().ends_with("0DCT3MKW5T2K0-add-login"));
}
#[test]
fn find_subdir_returns_none_when_absent() {
let tmp = TempDir::new().unwrap();
assert!(find_subdir(tmp.path(), "99").is_none());
}
#[test]
fn collect_index_paths_returns_index_md_from_subdirs() {
let tmp = TempDir::new().unwrap();
let sub = tmp.path().join("0001-issue");
std::fs::create_dir(&sub).unwrap();
std::fs::write(sub.join("index.md"), "").unwrap();
let paths = collect_index_paths(tmp.path()).unwrap();
assert_eq!(paths.len(), 1);
assert!(paths[0].ends_with("index.md"));
}
}