use crate::error::*;
use crate::Parameter;
use yansi::Paint;
#[derive(Debug)]
pub struct HelpEntry {
pub command: String,
pub parameters: Vec<(String, bool)>,
pub summary: Option<String>,
}
impl HelpEntry {
pub(crate) fn new(
command_name: &str,
parameters: &[Parameter],
summary: &Option<String>,
) -> Self {
Self {
command: command_name.to_string(),
parameters: parameters
.iter()
.map(|pd| (pd.name.clone(), pd.required))
.collect(),
summary: summary.clone(),
}
}
}
pub struct HelpContext {
pub app_name: String,
pub app_version: String,
pub app_purpose: String,
pub help_entries: Vec<HelpEntry>,
}
impl HelpContext {
pub(crate) fn new(
app_name: &str,
app_version: &str,
app_purpose: &str,
help_entries: Vec<HelpEntry>,
) -> Self {
Self {
app_name: app_name.into(),
app_version: app_version.into(),
app_purpose: app_purpose.into(),
help_entries,
}
}
}
pub trait HelpViewer {
fn help_general(&self, context: &HelpContext) -> Result<()>;
fn help_command(&self, entry: &HelpEntry) -> Result<()>;
}
pub struct DefaultHelpViewer;
impl DefaultHelpViewer {
pub fn new() -> Self {
Self
}
}
impl HelpViewer for DefaultHelpViewer {
fn help_general(&self, context: &HelpContext) -> Result<()> {
self.print_help_header(context);
for entry in &context.help_entries {
print!("{}", entry.command);
if entry.summary.is_some() {
print!(" - {}", entry.summary.as_ref().unwrap());
}
println!();
}
Ok(())
}
fn help_command(&self, entry: &HelpEntry) -> Result<()> {
if entry.summary.is_some() {
println!("{}: {}", entry.command, entry.summary.as_ref().unwrap());
} else {
println!("{}:", entry.command);
}
println!("Usage:");
print!("\t{}", entry.command);
for param in &entry.parameters {
if param.1 {
print!(" {}", param.0);
} else {
print!(" [{}]", param.0);
}
}
println!();
Ok(())
}
}
impl DefaultHelpViewer {
fn print_help_header(&self, context: &HelpContext) {
let header = format!(
"{} {}: {}",
context.app_name, context.app_version, context.app_purpose
);
let underline = Paint::new(" ".repeat(header.len())).strikethrough();
println!("{}", header);
println!("{}", underline);
}
}