Skip to content

Commit 0088224

Browse files
committed
Add .help method to Commands and generate fancy new help menu and help commands
1 parent c008157 commit 0088224

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

src/commands.rs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ pub struct Args<'m> {
1717
pub(crate) struct Commands {
1818
state_machine: StateMachine,
1919
client: HttpClient,
20-
menu: Option<String>,
20+
menu: HashMap<&'static str, &'static str>,
2121
}
2222

2323
impl Commands {
2424
pub(crate) fn new() -> Self {
2525
Self {
2626
state_machine: StateMachine::new(),
2727
client: HttpClient::new(),
28-
menu: Some(String::new()),
28+
menu: HashMap::new(),
2929
}
3030
}
3131

@@ -100,16 +100,27 @@ impl Commands {
100100
self.state_machine.set_final_state(state);
101101
self.state_machine.set_handler(state, handler.clone());
102102
}
103+
}
104+
105+
pub(crate) fn help(
106+
&mut self,
107+
cmd: &'static str,
108+
desc: &'static str,
109+
handler: impl Fn(Args) -> Result<()> + Send + Sync + 'static,
110+
) {
111+
let base_cmd = &cmd[1..];
112+
info!("Adding command ?help {}", &base_cmd);
113+
let mut state = 0;
114+
115+
self.menu.insert(cmd, desc);
116+
state = add_help_menu(&mut self.state_machine, base_cmd, state);
103117

104-
self.menu.as_mut().map(|menu| {
105-
*menu += command;
106-
*menu += "\n"
107-
});
118+
self.state_machine.set_final_state(state);
119+
self.state_machine.set_handler(state, Arc::new(handler));
108120
}
109121

110-
pub(crate) fn menu(&mut self) -> Option<String> {
111-
self.menu.as_mut().map(|menu| *menu += "?help\n");
112-
self.menu.take()
122+
pub(crate) fn menu(&mut self) -> &HashMap<&'static str, &'static str> {
123+
&self.menu
113124
}
114125

115126
pub(crate) fn execute<'m>(&'m self, cx: Context, msg: Message) {
@@ -156,6 +167,24 @@ fn add_space(state_machine: &mut StateMachine, mut state: usize, i: usize) -> us
156167
state
157168
}
158169

170+
fn add_help_menu(
171+
mut state_machine: &mut StateMachine,
172+
cmd: &'static str,
173+
mut state: usize,
174+
) -> usize {
175+
state = state_machine.add(state, CharacterSet::from_char('?'));
176+
state = state_machine.add(state, CharacterSet::from_char('h'));
177+
state = state_machine.add(state, CharacterSet::from_char('e'));
178+
state = state_machine.add(state, CharacterSet::from_char('l'));
179+
state = state_machine.add(state, CharacterSet::from_char('p'));
180+
state = add_space(&mut state_machine, state, 1);
181+
cmd.chars().for_each(|ch| {
182+
state = state_machine.add(state, CharacterSet::from_char(ch));
183+
});
184+
185+
state
186+
}
187+
159188
fn add_dynamic_segment(
160189
state_machine: &mut StateMachine,
161190
name: &'static str,

src/main.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use diesel::prelude::*;
2424
use envy;
2525
use serde::Deserialize;
2626
use serenity::{model::prelude::*, prelude::*};
27+
use std::collections::HashMap;
2728

2829
pub(crate) type Result = crate::commands::Result<()>;
2930

@@ -90,19 +91,19 @@ fn app() -> Result {
9091
// Tags
9192
cmds.add("?tags delete {key}", tags::delete);
9293
cmds.add("?tags create {key} value...", tags::post);
93-
cmds.add("?tags help", tags::help);
94+
cmds.add("?tags {key}", tags::get);
9495
cmds.add("?tags", tags::get_all);
95-
cmds.add("?tag {key}", tags::get);
96+
cmds.help("?tags", "A key value store", tags::help);
9697
}
9798

9899
if config.crates {
99100
// crates.io
100-
cmds.add("?crate help", crates::help);
101101
cmds.add("?crate query...", crates::search);
102+
cmds.help("?crate", "Lookup crates on crates.io", crates::help);
102103

103104
// docs.rs
104-
cmds.add("?docs help", crates::doc_help);
105105
cmds.add("?docs query...", crates::doc_search);
106+
cmds.help("?docs", "Lookup documentation", crates::doc_help);
106107
}
107108

108109
// Slow mode.
@@ -113,14 +114,13 @@ fn app() -> Result {
113114
cmds.add("?kick {user}", api::kick);
114115

115116
// Ban
116-
cmds.add("?ban help", ban::help);
117117
cmds.add("?ban {user} {hours} reason...", ban::temp_ban);
118+
cmds.help("?ban", "Temporarily ban a user from the guild", ban::help);
118119

119120
// Post the welcome message to the welcome channel.
120121
cmds.add("?CoC {channel}", welcome::post_message);
121122

122-
let menu = cmds.menu().unwrap();
123-
123+
let menu = main_menu(cmds.menu());
124124
cmds.add("?help", move |args: Args| {
125125
api::send_reply(&args, &format!("```{}```", &menu))?;
126126
Ok(())
@@ -137,6 +137,25 @@ fn app() -> Result {
137137
Ok(())
138138
}
139139

140+
fn main_menu(commands: &HashMap<&str, &str>) -> String {
141+
let mut menu = format!("Commands:\n");
142+
143+
menu = commands
144+
.iter()
145+
.fold(menu, |mut menu, (base_cmd, description)| {
146+
menu += &format!(
147+
"\t{cmd:<8}{desc}\n",
148+
cmd = base_cmd,
149+
desc = description
150+
);
151+
menu
152+
});
153+
154+
menu += &format!("\t{help:<8}This menu\n", help = "?help");
155+
menu += "\nType ?help command for more info on a command.";
156+
menu
157+
}
158+
140159
fn main() {
141160
env_logger::init();
142161

0 commit comments

Comments
 (0)