1use std::env;
2use std::{fs, path};
3
4pub fn root() -> Option<path::PathBuf> {
6 if let Ok(exec_path) = env::current_exe() {
7 walk_up(&exec_path)
8 } else {
9 None
10 }
11}
12
13fn walk_up(path: &path::Path) -> Option<path::PathBuf> {
15 if let Ok(dir) = fs::read_dir(&path) {
16 let mut found_target = false;
17 let mut found_cargo_toml = false;
18
19 for entry_result in dir {
20 if let Ok(entry) = &entry_result {
21 if !found_target && entry.file_name() == "target" {
22 found_target = true;
23 }
24
25 if !found_cargo_toml && entry.file_name() == "Cargo.toml" {
26 found_cargo_toml = true;
27 }
28
29 if found_target && found_cargo_toml {
30 return Some(path.to_path_buf());
31 }
32 }
33 }
34 }
35
36 if let Some(parent) = path.parent() {
37 walk_up(parent)
38 } else {
39 None
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn found_crate() {
49 assert_eq!(root().unwrap(), env::current_dir().unwrap());
50 }
51}