1use crate::constants::TRIDENT_TOML;
2use crate::Error;
3
4use anyhow::Context;
5use fehler::throw;
6use std::env;
7use std::path::Path;
8use std::path::PathBuf;
9
10pub(crate) fn resolve_path(filename: &str) -> PathBuf {
11 let path = Path::new(filename);
12 if path.is_absolute() {
13 path.to_path_buf()
14 } else {
15 discover_root()
16 .map(|cwd| cwd.join(path))
17 .unwrap_or_else(|_| panic!("Failed to resolve relative path: {}", path.display()))
18 }
19}
20
21pub fn discover_root() -> Result<PathBuf, Error> {
24 let current_dir = env::current_dir()?;
25 let mut dir = Some(current_dir.as_path());
26 while let Some(cwd) = dir {
27 for file in std::fs::read_dir(cwd)
28 .with_context(|| format!("Error reading the directory with path: {}", cwd.display()))?
29 {
30 let path = file
31 .with_context(|| {
32 format!("Error reading the directory with path: {}", cwd.display())
33 })?
34 .path();
35 if let Some(filename) = path.file_name() {
36 if filename.to_str() == Some(TRIDENT_TOML) {
37 return Ok(PathBuf::from(cwd));
38 }
39 }
40 }
41 dir = cwd.parent();
42 }
43 throw!(Error::BadWorkspace)
44}