Skip to main content

rexlang_util/
imports.rs

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
11/// Resolves a local Rex library import to a `.rex` path relative to `base_dir`.
12/// Leading `super` segments walk up the directory tree.
13pub 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}