about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-02-06 00:01:34 -0800
committerbors <bors@rust-lang.org>2014-02-06 00:01:34 -0800
commitd8c4e78603eb1f658516dde08868abbe6c06bd35 (patch)
tree1693ae845c9f328905e31bce657c14546ae05b2d
parent8dc06802b241ea30a8aadca1f8451a646f2bc3c0 (diff)
parent65a6c7c12cba28ba41c64d7e6a6d66502aeeeb52 (diff)
downloadrust-d8c4e78603eb1f658516dde08868abbe6c06bd35.tar.gz
rust-d8c4e78603eb1f658516dde08868abbe6c06bd35.zip
auto merge of #12001 : yuriks/rust/getopts-tweaks, r=brson
This complements `usage` by auto-generating a short one-liner summary
of the options.

(First timer here, be gentle... :)
-rw-r--r--src/libextra/getopts.rs64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs
index 4293f04795e..f29caec5d33 100644
--- a/src/libextra/getopts.rs
+++ b/src/libextra/getopts.rs
@@ -675,6 +675,51 @@ pub mod groups {
         ::getopts::getopts(args, opts.map(|x| x.long_to_short()))
     }
 
+    fn format_option(opt: &OptGroup) -> ~str {
+        let mut line = ~"";
+
+        if opt.occur != Req {
+            line.push_char('[');
+        }
+
+        // Use short_name is possible, but fallback to long_name.
+        if opt.short_name.len() > 0 {
+            line.push_char('-');
+            line.push_str(opt.short_name);
+        } else {
+            line.push_str("--");
+            line.push_str(opt.long_name);
+        }
+
+        if opt.hasarg != No {
+            line.push_char(' ');
+            if opt.hasarg == Maybe {
+                line.push_char('[');
+            }
+            line.push_str(opt.hint);
+            if opt.hasarg == Maybe {
+                line.push_char(']');
+            }
+        }
+
+        if opt.occur != Req {
+            line.push_char(']');
+        }
+        if opt.occur == Multi {
+            line.push_str("..");
+        }
+
+        line
+    }
+
+    /// Derive a short one-line usage summary from a set of long options.
+    pub fn short_usage(program_name: &str, opts: &[OptGroup]) -> ~str {
+        let mut line = ~"Usage: " + program_name + " ";
+        line.push_str(opts.iter().map(format_option).to_owned_vec().connect(" "));
+
+        line
+    }
+
     /// Derive a usage message from a set of long options.
     pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
 
@@ -1637,4 +1682,23 @@ Options:
         debug!("generated: <<{}>>", usage);
         assert!(usage == expected)
     }
+
+    #[test]
+    fn test_short_usage() {
+        let optgroups = ~[
+            groups::reqopt("b", "banana", "Desc", "VAL"),
+            groups::optopt("a", "012345678901234567890123456789",
+                             "Desc", "VAL"),
+            groups::optflag("k", "kiwi", "Desc"),
+            groups::optflagopt("p", "", "Desc", "VAL"),
+            groups::optmulti("l", "", "Desc", "VAL"),
+        ];
+
+        let expected = ~"Usage: fruits -b VAL [-a VAL] [-k] [-p [VAL]] [-l VAL]..";
+        let generated_usage = groups::short_usage("fruits", optgroups);
+
+        debug!("expected: <<{}>>", expected);
+        debug!("generated: <<{}>>", generated_usage);
+        assert_eq!(generated_usage, expected);
+    }
 }