Refactor argument documentation into generic function

finchie
Nov 25, 2023, 9:12 AM
6FCEG2XLAD5DCU7NQK2A7LIRQU7JHO2LO467RNK3RDOLXFAOBXCAC

Dependencies

  • [2] SM7AIPUZ Create `command` module
  • [3] ZVDBFCW7 Display arguments when input is invalid
  • [4] NSWIJUHG Add support for subcommands
  • [5] MT5RA7VY Increase sidebar density
  • [6] LEJN3E4Q Generate more semantic HTML
  • [7] MIY7QPYK Refactor argument handling into a separate file
  • [*] C73UJ7ZY Create simple `xilem_html` demo

Change contents

  • file addition: util.rs (----------)
    [9.15]
    use clap::builder::StyledStr;
    use xilem_html::{elements as el, ViewSequence};
    fn empty_string(text: &String) -> bool {
    let empty = text.chars().all(|c| c.is_whitespace());
    if empty {
    tracing::debug!("Rejecting empty string of length {:?}", text.len());
    }
    empty
    }
    pub fn collapsible_docs<T>(
    short_help: Option<&StyledStr>,
    long_help: Option<&StyledStr>,
    ) -> impl ViewSequence<T> {
    let short_help = short_help.map(|s| s.to_string());
    let long_help = long_help.map(|s| s.to_string());
    if short_help.is_none() && long_help.is_none() {
    None
    } else {
    // When both help messages are set, short_help is sometimes a prefix
    // of long_help
    let long_help = 'prefix: {
    if let Some(ref short_help) = short_help {
    if let Some(ref long_help) = long_help {
    // Check if it's a valid prefix
    if let Some(stripped_help) = long_help.strip_prefix(short_help.as_str()) {
    let stripped_help = stripped_help.to_string();
    if empty_string(&stripped_help) {
    break 'prefix None;
    } else {
    break 'prefix Some(stripped_help);
    }
    }
    }
    }
    long_help
    };
    Some(el::details((
    short_help
    .filter(|text| !empty_string(text))
    .map(el::summary),
    long_help
    .filter(|text| !empty_string(text))
    .map(el::blockquote),
    )))
    }
    }
  • edit in src/main.rs at line 4
    [2.17]
    [2.17]
    pub mod util;
  • file addition: command.rs (----------)
    [9.15]
    use crate::AppState;
    use clap::{ArgMatches, Command};
    use xilem_html::{elements as el, ViewSequence};
    fn about(command: &Command) -> impl ViewSequence<AppState> {
    if let Some(short_about) = command.get_about() {
    if let Some(long_about) = command.get_long_about() {
    return Some(el::details((
    el::summary(short_about.to_string()),
    el::blockquote(long_about.to_string()),
    )));
    }
    }
    None
    }
    pub fn command_view(
    command: &Command,
    arg_matches: Option<&ArgMatches>,
    ) -> impl ViewSequence<AppState> {
    el::section((
    el::h2(command.get_name().to_string()),
    crate::util::collapsible_docs(command.get_about(), command.get_long_about()),
    crate::arg::args_view(command, arg_matches),
    ))
    }
  • edit in src/arg.rs at line 142
    [3.3010][3.3010:3013](),[3.3013][3.244:423](),[3.423][3.136:453](),[3.453][3.673:717](),[3.673][3.673:717]()
    }
    fn documentation(arg: &Arg) -> impl ViewSequence<Arg> {
    if let Some(short_help) = arg.get_help() {
    Some(el::details((
    el::summary(short_help.to_string()),
    el::blockquote(
    arg.get_long_help()
    .map(ToString::to_string)
    .unwrap_or_default()
    .strip_prefix(&short_help.to_string())
    .unwrap_or("No description provided")
    .to_string(),
    ),
    )))
    } else {
    None
    }
  • replacement in src/arg.rs at line 181
    [3.4148][3.781:809]()
    documentation(arg),
    [3.4148]
    [3.4456]
    crate::util::collapsible_docs(arg.get_help(), arg.get_long_help()),
  • edit in index.html at line 53
    [3.767]
    [3.767]
    h2,