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
use std::env; use std::path::{Path, PathBuf}; pub struct Args { all: Vec<String>, target: Option<String>, manifest_path: Option<PathBuf>, } impl Args { pub fn new<A, S, T, P>(all: A, target: Option<T>, manifest_path: Option<P>) -> Self where A: IntoIterator<Item = S>, S: AsRef<str>, T: Into<String>, P: Into<PathBuf>, { Args { all: all.into_iter().map(|s| s.as_ref().to_string()).collect(), target: target.map(Into::into), manifest_path: manifest_path.map(Into::into) } } pub fn all(&self) -> &[String] { &self.all } pub fn target(&self) -> Option<&str> { self.target.as_ref().map(|s| &**s) } pub fn manifest_path(&self) -> Option<&Path> { self.manifest_path.as_ref().map(|s| &**s) } pub fn quiet(&self) -> bool { self.all.iter().any(|a| a == "--quiet" || a == "-q") } pub fn verbose(&self) -> bool { self.all .iter() .any(|a| a == "--verbose" || a == "-v" || a == "-vv") } } pub fn args(command_name: &str) -> Result<(Command, Args), String> { let mut args = env::args().skip(1); if args.next() != Some("x".to_string() + command_name) { Err(format!( "must be invoked as cargo subcommand: `cargo x{}`", command_name ))?; } let all = args.collect::<Vec<_>>(); let command = match all.first().map(|s| s.as_str()) { Some("-h") | Some("--help") => Command::Help, Some("-v") | Some("--version") => Command::Version, _ => Command::Build, }; let mut target: Option<String> = None; let mut manifest_path = None; { let mut args = all.iter(); while let Some(arg) = args.next() { if arg == "--target" { target = args.next().map(|s| s.to_owned()); } else if arg.starts_with("--target=") { target = arg.splitn(2, '=').nth(1).map(|s| s.to_owned()); } if arg == "--manifest-path" { manifest_path = args.next().map(|s| s.to_owned()); } else if arg.starts_with("--manifest-path=") { manifest_path = arg.splitn(2, '=').nth(1).map(|s| s.to_owned()); } } } let args = Args::new(all, target, manifest_path); Ok((command, args)) } #[derive(Clone, PartialEq)] pub enum Command { Build, Help, Version, }