//! repeats until the queue is empty.
use std::collections::{BTreeSet, HashMap, HashSet};
+use std::fmt::Write;
use std::hash::{Hash, Hasher};
use std::sync::Arc;
};
if proposals.is_empty() {
- let targets = packages.iter().flat_map(|pkg| {
- pkg.targets()
- .iter()
- .filter(|target| is_expected_kind(target))
- });
- let suggestion = closest_msg(target_name, targets, |t| t.name());
- anyhow::bail!(
- "no {} target {} `{}`{}",
- target_desc,
- if is_glob { "matches pattern" } else { "named" },
- target_name,
- suggestion
- );
+ let targets = packages
+ .iter()
+ .flat_map(|pkg| {
+ pkg.targets()
+ .iter()
+ .filter(|target| is_expected_kind(target))
+ })
+ .collect::<Vec<_>>();
+ let suggestion = closest_msg(target_name, targets.iter(), |t| t.name());
+ if !suggestion.is_empty() {
+ anyhow::bail!(
+ "no {} target {} `{}`{}",
+ target_desc,
+ if is_glob { "matches pattern" } else { "named" },
+ target_name,
+ suggestion
+ );
+ } else {
+ let mut msg = String::new();
+ writeln!(
+ msg,
+ "no {} target {} `{}`.",
+ target_desc,
+ if is_glob { "matches pattern" } else { "named" },
+ target_name,
+ )?;
+ if !targets.is_empty() {
+ writeln!(msg, "Available {} targets:", target_desc)?;
+ for target in targets {
+ writeln!(msg, " {}", target.name())?;
+ }
+ }
+ anyhow::bail!(msg);
+ }
}
Ok(proposals)
}