1use std::path::{Path, PathBuf};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
4pub enum PathError {
5 NotFound,
6}
7
8unsafe impl Send for PathError {}
9unsafe impl Sync for PathError {}
10
11pub fn find(
12 path: impl AsRef<Path>,
13 name: impl AsRef<Path>,
14) -> Result<PathBuf, PathError> {
15 let mut path = path.as_ref();
16 let name = name.as_ref();
17
18 loop {
19 let candidate = path.join(&name);
20 if candidate.exists() {
21 return Ok(candidate);
22 }
23
24 path = match path.parent() {
25 Some(parent) => parent,
26 None => return Err(PathError::NotFound),
27 };
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn test_find() {
37 let path = Path::new("src");
38 let name = Path::new(".gitignore");
39 let res = find(path, name);
40 assert!(res.is_ok());
41 assert_eq!(res.unwrap(), Path::new(".gitignore"));
42 }
43}