use std::path::{Path, PathBuf, Component,};
use std::env::current_dir;
pub fn resolve_path(file: &str, path: &str) -> String {
let path: &Path = std::path::Path::new(path);
let mut this_file_directory = Path::new(file)
.parent()
.expect("Could not get current file's directory.")
.to_path_buf();
#[allow(unused_mut)]
let mut fp_fs: String; match this_file_directory.components().next() {
Some(Component::Normal(segment)) => fp_fs = segment.to_string_lossy().to_string(),
Some(Component::RootDir) => {
let component = this_file_directory
.components()
.next()
.expect(&format!(
"Failed to find first directory segment from path {}.",
this_file_directory.to_string_lossy())
);
match component {
Component::Normal(segment) => fp_fs = segment.to_string_lossy().to_string(),
_ => {
panic!(
"Failed to find first directory normal segment from path {}.",
this_file_directory.to_string_lossy()
)
}
}
},
_ => panic!("Unexpected kind of directory."),
}
let curr_dir = current_dir().unwrap();
let paths_are_redundant = curr_dir.ends_with(&fp_fs) &&
this_file_directory.starts_with(&fp_fs);
if paths_are_redundant {
let mut new_path = PathBuf::new();
let mut components = this_file_directory.components();
if let Some(_) = components.next() {
components.for_each(|component| new_path.push(component));
}
this_file_directory = new_path;
}
let joined_path = this_file_directory.join(path);
let canonicalized = joined_path.canonicalize();
match canonicalized {
Err(err) => panic!("{}\n{}\n", err, joined_path.to_string_lossy()),
Ok(path) => path.to_string_lossy().to_string()
}
}
#[cfg(test)]
mod test {
use std::io::Read;
#[test]
fn test_resolve_path() {
let abs_path = "tests/dummy.txt";
let rel_path = "../../tests/dummy.txt";
let resolved_rel_path = super::resolve_path(file!(), &rel_path);
let mut abs_file_contents = String::new();
let mut rel_file_contents = String::new();
let _ = std::fs::File::open(abs_path).unwrap().read_to_string(&mut abs_file_contents);
let _ = std::fs::File::open(resolved_rel_path).unwrap().read_to_string(&mut rel_file_contents);
assert_eq!(abs_file_contents, rel_file_contents);
}
}