1use std::{env, error::Error, path::PathBuf};
8
9pub fn get_crate_root() -> Result<PathBuf, Box<dyn Error>> {
15 let exe_path = env::current_exe().expect("Failed to get executable path");
16 let mut crate_root = exe_path
17 .parent()
18 .ok_or("Failed to get parent directory")?
19 .parent()
20 .ok_or("Failed to get crate root directory")?
21 .to_path_buf();
22
23 loop {
24 let is_final = crate_root.ends_with("target");
25 crate_root = crate_root
26 .parent()
27 .ok_or("Failed to get crate root directory")?
28 .to_path_buf();
29 if is_final {
30 break;
31 }
32 }
33
34 Ok(crate_root)
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn test_get_crate_root_returns_path() {
43 let result = get_crate_root();
44 assert!(result.is_ok());
45 let root = result.unwrap();
46 assert!(root.exists());
47 }
48
49 #[test]
50 fn test_get_crate_root_not_inside_target() {
51 let root = get_crate_root().unwrap();
52 assert!(!root.ends_with("target"));
53 }
54}