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
use std::io::{self, Write};
use std::process;
use crate::registry::Flag;
/// Print the names and descriptions of all the flags.
///
/// There is no built-in `-h` flag in gflags for help. If you want one, go ahead
/// and define your own and call this function to render the documentation of
/// all flags. Output goes to stdout if the exit code is zero, and stderr if
/// nonzero.
///
/// # Example
///
/// ```
/// gflags::define! {
/// -h, --help = false
/// }
///
/// fn main() {
/// gflags::parse();
/// if help.FLAG {
/// gflags::print_help_and_exit(0);
/// }
///
/// /* ... */
/// }
/// ```
///
/// # Output
///
/// For some of the flag definitions shown in [the crate level
/// documentation](index.html), the help text would be rendered as follows.
///
/// ```text
/// --big_menu
/// Include 'advanced' options in the menu listing.
///
/// -f, --file
/// Search for patterns from the given file, with one pattern per line.
///
/// -l, --language <LANG>
/// Comma-separated list of languages to offer in the 'lang' menu.
/// ```
///
/// The flags are listed in alphabetical order by long name.
///
/// **Tip:** You will likely want to print your own content above this including
/// the application name, version, author, introductory explanation, and usage
/// strings.
pub fn print_help_and_exit(code: i32) -> ! {
if code == 0 {
let _ = try_print_help(&mut io::stdout().lock());
} else {
let _ = try_print_help(&mut io::stderr().lock());
};
process::exit(code);
}
fn try_print_help(stream: &mut Write) -> io::Result<()> {
let mut flags = inventory::iter::<Flag>.into_iter().collect::<Vec<_>>();
flags.sort_by_key(|flag| flag.name);
let has_short = flags.iter().any(|flag| flag.short.is_some());
for flag in flags {
write!(stream, " ")?;
if has_short {
match flag.short {
Some(short) => write!(stream, "-{}, ", short)?,
None => write!(stream, " ")?,
}
}
write!(stream, "--{}", flag.name)?;
if let Some(placeholder) = flag.placeholder {
write!(stream, " <{}>", placeholder)?;
}
writeln!(stream)?;
for line in flag.doc {
let line = line.trim_end();
if line.is_empty() {
writeln!(stream)?;
} else {
writeln!(stream, " {}", line)?;
}
}
writeln!(stream)?;
}
Ok(())
}