1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#![deny(missing_docs)]
use std::{path::{Path, PathBuf}, time::SystemTime};
use cargo_toml::{Error, Manifest};
pub const DIR_DEBUG: &str = "debug";
pub const DIR_RELEASE: &str = "release";
pub const DIR_TARGET: &str = "target";
pub const FILE_MANIFEST: &str = "Cargo.toml";
fn find_recursive(
path_dir: &Path,
path_sub: &Path,
results: &mut Vec<PathBuf>,
recurse: usize,
) -> std::io::Result<()> {
for sub in path_dir.read_dir()? {
if let Ok(entry) = sub {
let path: PathBuf = entry.path();
if path.is_dir() {
let mut path_file: PathBuf = path.clone();
path_file.push(path_sub);
if path_file.is_file() {
results.push(path_file);
}
if 0 < recurse {
find_recursive(&path, path_sub, results, recurse - 1)?;
}
}
}
}
Ok(())
}
pub enum Mode {
Debug,
Release,
Latest,
}
impl Mode {
pub fn make_path(
&self,
path_dir_target: impl Into<PathBuf>,
path_exe: impl AsRef<Path>,
) -> Option<PathBuf> {
let mut path: PathBuf = path_dir_target.into();
let path_exe: &Path = path_exe.as_ref();
match self {
Mode::Debug => {
path.push(DIR_DEBUG);
path.push(path_exe);
Some(path)
}
Mode::Release => {
path.push(DIR_RELEASE);
path.push(path_exe);
Some(path)
}
Mode::Latest => {
let mut paths = Vec::new();
if let Err(e) = find_recursive(&path, path_exe, &mut paths, 2) {
eprintln!(
"WARNING: An error occurred while searching in `{}`. \
Results may not be complete.\
\n Error: {}",
path.display(),
e
);
}
paths.sort_by_key(|path| {
path.metadata()
.and_then(|meta| meta.modified())
.unwrap_or(SystemTime::UNIX_EPOCH)
});
paths.pop()
}
}
}
}
pub fn path_project(dir_or_manifest: &Path) -> &Path {
if dir_or_manifest.is_file() {
match dir_or_manifest.parent() {
Some(parent) => parent,
None => ".".as_ref(),
}
} else {
dir_or_manifest
}
}
pub fn names_bin(path_manifest: impl AsRef<Path>) -> Result<Vec<String>, Error> {
let manifest = Manifest::from_path(path_manifest)?;
Ok(manifest.bin.into_iter().filter_map(|p| p.name).collect())
}