patchy/flags.rs
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
use std::env;
use colored::Colorize;
use indexmap::IndexSet;
use once_cell::sync::Lazy;
use crate::{commands::help::format_description, types::CommandArgs};
pub struct Flag<'a> {
pub short: &'a str,
pub long: &'a str,
pub description: &'a str,
}
/// Extracts value out of a `flag` which can have an assignment
///
/// # Examples
///
/// ```rust
/// use patchy::flags::{extract_value_from_flag, Flag};
///
/// let my_flag = Flag {
/// short: "-r=",
/// long: "--remote-name=",
/// description: "some flag",
/// };
///
/// let long_version = extract_value_from_flag("--remote-name=abc", &my_flag);
/// let short_version = extract_value_from_flag("-r=abcdefg", &my_flag);
/// let invalid = extract_value_from_flag("-m=abcdefg", &my_flag);
///
/// assert_eq!(long_version, Some("abc".into()));
/// assert_eq!(short_version, Some("abcdefg".into()));
/// assert_eq!(invalid, None);
/// ```
pub fn extract_value_from_flag(arg: &str, flag: &Flag) -> Option<String> {
if arg.starts_with(flag.short) {
arg.get(flag.short.len()..).map(|value| value.into())
} else if arg.starts_with(flag.long) {
arg.get(flag.long.len()..).map(|value| value.into())
} else {
None
}
}
pub fn contains_flag(args: &IndexSet<String>, flag: &Flag) -> bool {
args.contains(flag.short) || args.contains(flag.long)
}
/// Checks whether an input argument is a valid flag
pub fn is_valid_flag(arg: &str, available_flags: &[&Flag]) -> bool {
// TODO: flags that don't end in "=" should be compared fully, not just the beginning
available_flags
.iter()
.flat_map(|flag| [flag.short, flag.long])
.any(|flag| arg.starts_with(flag))
}
/// Formats a flag into a colored format with a description, printable to the terminal
pub fn format_flag(flag: &Flag) -> String {
format!(
"{}{}{}\n {}",
flag.short.bright_magenta(),
", ".bright_black(),
flag.long.bright_magenta(),
format_description(flag.description)
)
}
pub static IS_VERBOSE: Lazy<bool> = Lazy::new(|| {
let args: CommandArgs = env::args().collect();
args.contains("--verbose")
});