cargo/util/
mod.rs
1use std::path::{Path, PathBuf};
2use std::time::Duration;
3
4pub use self::canonical_url::CanonicalUrl;
5pub use self::context::{homedir, ConfigValue, GlobalContext};
6pub(crate) use self::counter::MetricsCounter;
7pub use self::dependency_queue::DependencyQueue;
8pub use self::diagnostic_server::RustfixDiagnosticServer;
9pub use self::edit_distance::{closest, closest_msg, edit_distance};
10pub use self::errors::CliError;
11pub use self::errors::{internal, CargoResult, CliResult};
12pub use self::flock::{FileLock, Filesystem};
13pub use self::graph::Graph;
14pub use self::hasher::StableHasher;
15pub use self::hex::{hash_u64, short_hash, to_hex};
16pub use self::hostname::hostname;
17pub use self::into_url::IntoUrl;
18pub use self::into_url_with_base::IntoUrlWithBase;
19pub(crate) use self::io::LimitErrorReader;
20pub use self::lockserver::{LockServer, LockServerClient, LockServerStarted};
21pub use self::progress::{Progress, ProgressStyle};
22pub use self::queue::Queue;
23pub use self::rustc::Rustc;
24pub use self::semver_ext::{OptVersionReq, VersionExt};
25pub use self::vcs::{existing_vcs_repo, FossilRepo, GitRepo, HgRepo, PijulRepo};
26pub use self::workspace::{
27 add_path_args, path_args, print_available_benches, print_available_binaries,
28 print_available_examples, print_available_packages, print_available_tests,
29};
30
31pub mod auth;
32pub mod cache_lock;
33mod canonical_url;
34pub mod command_prelude;
35pub mod context;
36mod counter;
37pub mod cpu;
38pub mod credential;
39mod dependency_queue;
40pub mod diagnostic_server;
41pub mod edit_distance;
42pub mod errors;
43mod flock;
44pub mod graph;
45mod hasher;
46pub mod hex;
47mod hostname;
48pub mod important_paths;
49pub mod interning;
50pub mod into_url;
51mod into_url_with_base;
52mod io;
53pub mod job;
54pub mod lints;
55mod lockserver;
56pub mod machine_message;
57pub mod network;
58mod progress;
59mod queue;
60pub mod restricted_names;
61pub mod rustc;
62mod semver_eval_ext;
63mod semver_ext;
64pub mod sqlite;
65pub mod style;
66pub mod toml;
67pub mod toml_mut;
68mod vcs;
69mod workspace;
70
71pub fn is_rustup() -> bool {
72 #[allow(clippy::disallowed_methods)]
75 std::env::var_os("RUSTUP_HOME").is_some()
76}
77
78pub fn elapsed(duration: Duration) -> String {
79 let secs = duration.as_secs();
80
81 if secs >= 60 {
82 format!("{}m {:02}s", secs / 60, secs % 60)
83 } else {
84 format!("{}.{:02}s", secs, duration.subsec_nanos() / 10_000_000)
85 }
86}
87
88pub fn human_readable_bytes(bytes: u64) -> (f32, &'static str) {
91 static UNITS: [&str; 7] = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"];
92 let bytes = bytes as f32;
93 let i = ((bytes.log2() / 10.0) as usize).min(UNITS.len() - 1);
94 (bytes / 1024_f32.powi(i as i32), UNITS[i])
95}
96
97pub fn indented_lines(text: &str) -> String {
98 text.lines()
99 .map(|line| {
100 if line.is_empty() {
101 String::from("\n")
102 } else {
103 format!(" {}\n", line)
104 }
105 })
106 .collect()
107}
108
109pub fn truncate_with_ellipsis(s: &str, max_width: usize) -> String {
110 let mut chars = s.chars();
114 let mut prefix = (&mut chars).take(max_width - 1).collect::<String>();
115 if chars.next().is_some() {
116 prefix.push('…');
117 }
118 prefix
119}
120
121#[cfg(not(windows))]
122#[inline]
123pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> std::io::Result<PathBuf> {
124 std::fs::canonicalize(&path)
125}
126
127#[cfg(windows)]
128#[inline]
129pub fn try_canonicalize<P: AsRef<Path>>(path: P) -> std::io::Result<PathBuf> {
130 use std::io::Error;
131 use std::io::ErrorKind;
132
133 std::fs::canonicalize(&path).or_else(|_| {
135 if !path.as_ref().try_exists()? {
137 return Err(Error::new(ErrorKind::NotFound, "the path was not found"));
138 }
139 std::path::absolute(&path)
140 })
141}
142
143#[cfg(unix)]
147pub fn get_umask() -> u32 {
148 use std::sync::OnceLock;
149 static UMASK: OnceLock<libc::mode_t> = OnceLock::new();
150 *UMASK.get_or_init(|| unsafe {
155 let umask = libc::umask(0o022);
156 libc::umask(umask);
157 umask
158 }) as u32 }
160
161#[cfg(test)]
162mod test {
163 use super::*;
164
165 #[test]
166 fn test_human_readable_bytes() {
167 assert_eq!(human_readable_bytes(0), (0., "B"));
168 assert_eq!(human_readable_bytes(8), (8., "B"));
169 assert_eq!(human_readable_bytes(1000), (1000., "B"));
170 assert_eq!(human_readable_bytes(1024), (1., "KiB"));
171 assert_eq!(human_readable_bytes(1024 * 420 + 512), (420.5, "KiB"));
172 assert_eq!(human_readable_bytes(1024 * 1024), (1., "MiB"));
173 assert_eq!(
174 human_readable_bytes(1024 * 1024 + 1024 * 256),
175 (1.25, "MiB")
176 );
177 assert_eq!(human_readable_bytes(1024 * 1024 * 1024), (1., "GiB"));
178 assert_eq!(
179 human_readable_bytes((1024. * 1024. * 1024. * 1.2345) as u64),
180 (1.2345, "GiB")
181 );
182 assert_eq!(human_readable_bytes(1024 * 1024 * 1024 * 1024), (1., "TiB"));
183 assert_eq!(
184 human_readable_bytes(1024 * 1024 * 1024 * 1024 * 1024),
185 (1., "PiB")
186 );
187 assert_eq!(
188 human_readable_bytes(1024 * 1024 * 1024 * 1024 * 1024 * 1024),
189 (1., "EiB")
190 );
191 assert_eq!(human_readable_bytes(u64::MAX), (16., "EiB"));
192 }
193}