Skip to content

Commit

Permalink
feat(ArgMatches): add method to get default usage string
Browse files Browse the repository at this point in the history
  • Loading branch information
kbknapp committed Apr 9, 2015
1 parent 64e5392 commit 0246215
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 18 deletions.
52 changes: 36 additions & 16 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::path::Path;
use std::vec::IntoIter;
use std::borrow::ToOwned;
use std::process;
use std::fmt::Write;

use args::{ ArgMatches, Arg, SubCommand };
use args::{FlagArg, FlagBuilder};
Expand Down Expand Up @@ -60,6 +61,7 @@ pub struct App<'a, 'v, 'ab, 'u, 'ar> {
long_list: HashSet<&'ar str>,
blacklist: HashSet<&'ar str>,
usage_str: Option<&'u str>,
usage: Option<String>,
bin_name: Option<String>

}
Expand Down Expand Up @@ -96,6 +98,7 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
short_list: HashSet::new(),
long_list: HashSet::new(),
usage_str: None,
usage: None,
blacklist: HashSet::new(),
bin_name: None,
}
Expand Down Expand Up @@ -399,11 +402,13 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
self
}

fn print_usage(&self, more_info: bool) {
fn create_usage(&self) -> String {
let tab = " ";
println!("USAGE:");
let mut usage = String::with_capacity(75);
usage.push_str("USAGE:\n");
usage.push_str(tab);
if let Some(u) = self.usage_str {
println!("{}{}",tab,u);
usage.push_str(u);
} else {
let flags = !self.flags.is_empty();
let pos = !self.positionals_idx.is_empty();
Expand Down Expand Up @@ -433,7 +438,7 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
}
} else {
None
})
} )
.fold(String::new(), |acc, ref name| acc + &format!("{} ", name)[..]);
let mut num_req_opts = 0;
let req_opts = self.opts.values().filter_map(|x| if x.required || self.matched_reqs.contains(x.name) {
Expand All @@ -448,29 +453,43 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
format!("{} ",o.short.unwrap())
},o.name));

print!("{}{} {} {} {} {}",tab, self.bin_name.clone().unwrap_or(self.name.clone()),
if flags {"[FLAGS]"} else {""},
if opts {
// usage.push_str(tab);
usage.push_str(&self.bin_name.clone().unwrap_or(self.name.clone())[..]);
// usage.push_str(tab);
if flags {
usage.push_str(" [FLAGS]");
}
if opts {
write!(&mut usage," {}",
if num_req_opts != self.opts.len() && !req_opts.is_empty() {
format!("[OPTIONS] {}", &req_opts[..])
} else if req_opts.is_empty() {
"[OPTIONS]".to_owned()
} else {
req_opts
}
} else { "".to_owned() },
if pos {
req_opts
});
}
if pos {
write!(&mut usage, " {}",
if num_req_pos != self.positionals_idx.len() && !req_pos.is_empty() {
format!("[POSITIONAL] {}", &req_pos[..])
} else if req_pos.is_empty() {
"[POSITIONAL]".to_owned()
"[POSITIONAL]".to_owned()
} else {
req_pos
}
} else {"".to_owned()},
if subcmds {"[SUBCOMMANDS]"} else {""});
req_pos
} );
}
if subcmds {
usage.push_str(" [SUBCOMMANDS]");
}
}

usage.shrink_to_fit();
usage
}

fn print_usage(&self, more_info: bool) {
print!("{}",self.create_usage());
if more_info {
println!("\nFor more information try --help");
}
Expand Down Expand Up @@ -689,6 +708,7 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
}
}
}
matches.usage = Some(self.create_usage());
self.get_matches_from(&mut matches, &mut it );

matches
Expand Down
22 changes: 20 additions & 2 deletions src/args/argmatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ pub struct ArgMatches<'a> {
pub flags: HashMap<&'a str, FlagArg>,
pub opts: HashMap<&'a str, OptArg>,
pub positionals: HashMap<&'a str, PosArg>,
pub subcommand: Option<Box<SubCommand<'a>>>
pub subcommand: Option<Box<SubCommand<'a>>>,
pub usage: Option<String>
}

impl<'a> ArgMatches<'a> {
Expand All @@ -83,7 +84,8 @@ impl<'a> ArgMatches<'a> {
flags: HashMap::new(),
opts: HashMap::new(),
positionals: HashMap::new(),
subcommand: None
subcommand: None,
usage: None
}
}

Expand Down Expand Up @@ -264,4 +266,20 @@ impl<'a> ArgMatches<'a> {
("", None)
}

/// Returns a slice of the default usage for the *top level parent App only*
///
///
/// # Example
///
/// ```no_run
/// # use clap::{App, Arg, SubCommand};
/// # let app_matches = App::new("myapp").subcommand(SubCommand::new("test")).get_matches();
/// println!(matches.usage());
/// ```
pub fn usage(&self) -> Option<&str> {
if let Some( ref u ) = self.usage {
return Some(&u[..]);
}
None
}
}

0 comments on commit 0246215

Please sign in to comment.