1use std::path::{Path, PathBuf};
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum ImportPathError {
7 #[error("import path escapes filesystem root")]
8 EscapesRoot,
9}
10
11pub fn resolve_local_import_path<S: AsRef<str>>(
14 base_dir: &Path,
15 segments: &[S],
16) -> Result<Option<PathBuf>, ImportPathError> {
17 if segments.is_empty() {
18 return Ok(None);
19 }
20
21 let mut dir = base_dir.to_path_buf();
22 let mut idx = 0usize;
23 while idx < segments.len() && segments[idx].as_ref() == "super" {
24 dir = dir
25 .parent()
26 .ok_or(ImportPathError::EscapesRoot)?
27 .to_path_buf();
28 idx += 1;
29 }
30
31 let mut path = dir;
32 for seg in &segments[idx..segments.len().saturating_sub(1)] {
33 path.push(seg.as_ref());
34 }
35 let Some(last) = segments.last().map(|s| s.as_ref()) else {
36 return Ok(None);
37 };
38 path.push(format!("{last}.rex"));
39 Ok(Some(path))
40}