+enum CargoTargets {
+ All,
+ Filtered { lib: bool, bin: Vec<String>, test: Vec<String> },
+}
+
+impl CargoTargets {
+ fn matches(&self, kind: &str, name: &str) -> bool {
+ match self {
+ CargoTargets::All => true,
+ CargoTargets::Filtered { lib, bin, test } => match kind {
+ "lib" => *lib,
+ "bin" => bin.iter().any(|n| n == name),
+ "test" => test.iter().any(|n| n == name),
+ _ => false,
+ },
+ }
+ }
+}
+
+fn parse_cargo_miri_args(
+ mut args: impl Iterator<Item = String>,
+) -> (CargoTargets, Vec<String>, Vec<String>) {
+ let mut lib_present = false;
+ let mut bin_targets = Vec::new();
+ let mut test_targets = Vec::new();
+ let mut additional_args = Vec::new();
+ while let Some(arg) = args.next() {
+ match arg {
+ arg if arg == "--" => break,
+ arg if arg == "--lib" => lib_present = true,
+ arg if arg == "--bin" => {
+ if let Some(binary) = args.next() {
+ if binary == "--" {
+ show_error(format!("\"--bin\" takes one argument."));
+ } else {
+ bin_targets.push(binary)
+ }
+ } else {
+ show_error(format!("\"--bin\" takes one argument."));
+ }
+ }
+ arg if arg == "--test" => {
+ if let Some(test) = args.next() {
+ if test == "--" {
+ show_error(format!("\"--test\" takes one argument."));
+ } else {
+ test_targets.push(test)
+ }
+ } else {
+ show_error(format!("\"--test\" takes one argument."));
+ }
+ }
+ other => additional_args.push(other),
+ }
+ }
+ let targets = if !lib_present && bin_targets.len() == 0 && test_targets.len() == 0 {
+ CargoTargets::All
+ } else {
+ CargoTargets::Filtered { lib: lib_present, bin: bin_targets, test: test_targets }
+ };
+ (targets, additional_args, args.collect())
+}
+