Skip to main content

assay_core/config/
path_resolver.rs

1use std::path::{Path, PathBuf};
2
3#[derive(Clone)]
4pub struct PathResolver {
5    base_dir: PathBuf,
6}
7
8impl PathResolver {
9    pub fn new(config_path: &Path) -> Self {
10        let base_dir = config_path.parent().unwrap_or(Path::new(".")).to_path_buf();
11        Self { base_dir }
12    }
13
14    pub fn resolve_opt_str(&self, p: &mut Option<String>) {
15        let Some(s) = p.as_mut() else { return };
16        if s.trim().is_empty() {
17            return;
18        }
19
20        let pb = PathBuf::from(&*s);
21        if pb.is_absolute() {
22            return;
23        }
24
25        let joined = self.join_clean(&pb);
26        *s = joined.to_string_lossy().to_string();
27    }
28
29    pub fn resolve_str(&self, s: &mut String) {
30        if s.trim().is_empty() {
31            return;
32        }
33        let pb = PathBuf::from(&*s);
34        if pb.is_absolute() {
35            return;
36        }
37
38        let joined = self.join_clean(&pb);
39        *s = joined.to_string_lossy().to_string();
40    }
41
42    fn join_clean(&self, rel: &Path) -> PathBuf {
43        let joined = self.base_dir.join(rel);
44
45        let mut out = PathBuf::new();
46        for c in joined.components() {
47            use std::path::Component::*;
48            match c {
49                CurDir => {}
50                ParentDir => {
51                    out.pop();
52                }
53                RootDir | Prefix(_) | Normal(_) => out.push(c.as_os_str()),
54            }
55        }
56        out
57    }
58}