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
use docopt::Docopt; use docopt::Value::{self, Counted, List, Plain, Switch}; use std::error::Error; fn key_string(x: &str) -> &str { if x.starts_with("--") { &x[2..] } else if x.starts_with('<') { let l = x.len(); &x[1..(l - 1)] } else { x } } fn value_string(x: &Value) -> String { match x { Switch(b) => format!("{}", b), Counted(n) => format!("'{}'", n), Plain(o) => match o { Some(y) => format!("'{}'", y), None => "".to_owned(), }, List(v) => { let mut s = String::from("("); let quoted_values: Vec<String> = v.iter().map(|y| format!("'{}'", y)).collect(); s.push_str("ed_values.join(" ")); s.push_str(")"); s } } } enum Data<'a> { Unknown, Help(String), Parse(String, &'a [String]), } fn get_data(argv: &[String]) -> Result<Data, Box<dyn Error>> { match argv.get(0).as_ref().map(|s| s.as_str()) { Some("--help") | Some("-h") => {} _ => return Ok(Data::Unknown), } let help_msg: String; match argv.get(1) { Some(msg) => help_msg = msg.to_owned(), _ => return Ok(Data::Unknown), } match argv.get(2).as_ref().map(|s| s.as_str()) { Some(":") => {} _ => return Ok(Data::Unknown), } match argv.get(3).as_ref().map(|s| s.as_str()) { Some("--help") | Some("-h") => Ok(Data::Help(help_msg)), _ => Ok(Data::Parse(help_msg, &argv[2..])), } } pub fn gen_eval_string(argv: &[String]) -> Result<(), Box<dyn Error>> { let data = get_data(argv)?; match data { Data::Help(msg) => { println!( r#"cat << DOCPARSEOF {} DOCPARSEOF exit 0"#, msg ); } Data::Parse(msg, args) => { let parsed_args = Docopt::new(msg) .and_then(|d| d.argv(args).parse()) .unwrap_or_else(|e| { if e.fatal() { println!("exit 1"); e.exit(); } else { e.exit(); } }); for (k, v) in parsed_args.map.iter() { println!("{}={}", key_string(k).replace("-", "_"), value_string(v)); } } _ => { println!("Usage: docpars -h <docopt> : <args>..."); } } Ok(()) }