sdoc/commands/
help.rs

1use config::Context;
2use dto::{Request, Response};
3use model::{Command, Section};
4use workflow::Work;
5use workflow::Instruction::Display;
6use commands::util::build_auto_complete;
7
8pub fn execute(request: Request, context: &Context) -> Work {
9    let request = request.next();
10    build_help(&request, context)
11}
12
13pub fn auto_complete(request: Request, context: &Context) -> Work {
14    let request = request.next();
15    Work::instruction(Display(auto_complete_build(request, context), Response::Ok))
16}
17
18fn auto_complete_build(request: Request, context: &Context) -> String {
19    request.current
20        .and_then(|rc| context.find(&rc, false))
21        .map(|_| s!())
22        .unwrap_or_else(|| build_auto_complete(context))
23}
24
25pub fn build_help(request: &Request, context: &Context) -> Work {
26    Work::instruction(match request.current {
27        Some(rc) => {
28            context.find(&rc, true)
29                .map(|c| Display(c.build_command_usage(&context.build_command_chain()), Response::Ok))
30                .unwrap_or_else(|| Display(build_full_help(context), Response::Err(1)))
31        }
32        _ => Display(build_full_help(context), Response::Ok)
33    })
34}
35
36pub fn execute_help(request: &Request, context: &Context) -> Work {
37    let response = match request.current {
38        Some(_) => Response::Err(1),
39        _ => Response::Ok
40    };
41
42    Work::instruction(Display(build_help_without_builtins(context), response))
43}
44
45pub fn build_full_help(context: &Context) -> String {
46    format_help(&context.resolved_commands, &context.config.iter().collect())
47}
48
49pub fn build_help_without_builtins(context: &Context) -> String {
50    let sections: Vec<&Section> = context.config.iter()
51        .filter(|s| !s.core)
52        .collect();
53    return format!("{}\nRun \'{} help\' for more information\n", format_help(&context.resolved_commands, &sections), context.resolved_commands.join(" "))
54}
55
56fn format_help(resolved_commands: &Vec<String>, sections: &Vec<&Section>) -> String {
57    let formatted_sections: Vec<String> = sections.iter()
58        .map(|s| format_section(s))
59        .collect();
60    format!("\n{}\n\n{}",
61            format!("Usage: {} <command> [args]", resolved_commands.join(" ")),
62            formatted_sections.join("\n"))
63}
64
65fn format_section(section: &Section) -> String {
66    let commands: Vec<String> = section.commands.iter()
67        .map(|c| format_command(c))
68        .collect();
69    format!("{}:\n  {}\n", section.heading, commands.join("\n  "))
70}
71
72fn format_command(command: &Command) -> String {
73    format!("{:12}{:6}{}",
74            command.name,
75            command.alias.as_ref().unwrap_or(&String::new()),
76            command.description)
77}