Skip to main content

buildfix_domain/
ports.rs

1use anyhow::Context;
2use camino::{Utf8Path, Utf8PathBuf};
3use fs_err as fs;
4
5// Re-exported for downstream reuse and compatibility with microcrate adapters.
6pub use buildfix_fixer_api::RepoView;
7
8/// File-system backed `RepoView`.
9#[derive(Debug, Clone)]
10pub struct FsRepoView {
11    root: Utf8PathBuf,
12}
13
14impl FsRepoView {
15    pub fn new(root: Utf8PathBuf) -> Self {
16        Self { root }
17    }
18
19    fn abs(&self, rel: &Utf8Path) -> Utf8PathBuf {
20        if rel.is_absolute() {
21            rel.to_path_buf()
22        } else {
23            self.root.join(rel)
24        }
25    }
26}
27
28impl RepoView for FsRepoView {
29    fn root(&self) -> &Utf8Path {
30        &self.root
31    }
32
33    fn read_to_string(&self, rel: &Utf8Path) -> anyhow::Result<String> {
34        let abs = self.abs(rel);
35        fs::read_to_string(&abs).with_context(|| format!("read {}", abs))
36    }
37
38    fn exists(&self, rel: &Utf8Path) -> bool {
39        self.abs(rel).exists()
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46    use fs_err as fs;
47    use tempfile::TempDir;
48
49    #[test]
50    fn fs_repo_view_reads_relative_and_absolute_paths() {
51        let temp = TempDir::new().expect("temp dir");
52        let root = Utf8PathBuf::from_path_buf(temp.path().to_path_buf()).expect("utf8");
53        let file_path = root.join("Cargo.toml");
54        fs::write(&file_path, "name = \"demo\"").expect("write");
55
56        let repo = FsRepoView::new(root.clone());
57
58        let rel_contents = repo
59            .read_to_string(Utf8Path::new("Cargo.toml"))
60            .expect("read relative");
61        assert_eq!(rel_contents, "name = \"demo\"");
62
63        assert!(file_path.is_absolute());
64        let abs_contents = repo.read_to_string(&file_path).expect("read absolute");
65        assert_eq!(abs_contents, "name = \"demo\"");
66    }
67
68    #[test]
69    fn fs_repo_view_exists_checks() {
70        let temp = TempDir::new().expect("temp dir");
71        let root = Utf8PathBuf::from_path_buf(temp.path().to_path_buf()).expect("utf8");
72        let file_path = root.join("Cargo.toml");
73        fs::write(&file_path, "name = \"demo\"").expect("write");
74
75        let repo = FsRepoView::new(root);
76        assert!(repo.exists(Utf8Path::new("Cargo.toml")));
77        assert!(!repo.exists(Utf8Path::new("missing.toml")));
78    }
79
80    #[test]
81    fn fs_repo_view_root_is_stable() {
82        let temp = TempDir::new().expect("temp dir");
83        let root = Utf8PathBuf::from_path_buf(temp.path().to_path_buf()).expect("utf8");
84        let repo = FsRepoView::new(root.clone());
85        assert_eq!(repo.root(), root.as_path());
86    }
87}