Skip to content

Commit 7d657a0

Browse files
add HELP command
1 parent d1a489d commit 7d657a0

3 files changed

Lines changed: 81 additions & 0 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use super::*;
2+
3+
use itertools::Itertools;
4+
5+
#[command_handler("HELP", "UHELP")]
6+
/// HELP [<topic>]
7+
///
8+
/// HELP displays information for topic requested.
9+
/// If no topic is requested, it will list available
10+
/// help topics.
11+
fn help_handler(
12+
command: &dyn Command,
13+
response: &dyn CommandResponse,
14+
server: &ClientServer,
15+
source: UserSource,
16+
topic: Option<&str>,
17+
) -> CommandResult {
18+
// TODO: oper help? (and if oper help is on the same command, UHELP like solanum?)
19+
// TODO: non-command help topics
20+
let is_oper = command.command().to_ascii_uppercase() != "UHELP" && source.is_oper();
21+
22+
match topic {
23+
Some(s) => {
24+
let topic = s.to_ascii_uppercase();
25+
let topic = topic
26+
.split_once(' ')
27+
.map_or(topic.clone(), |(t, _)| t.to_string());
28+
29+
if let Some(cmd) = server.get_command(&topic) {
30+
if cmd.docs.len() > 0 {
31+
// TODO
32+
if cmd.restricted && is_oper {
33+
response.numeric(make_numeric!(HelpNotFound, &topic));
34+
return Ok(());
35+
}
36+
let mut lines = cmd.docs.iter();
37+
response.numeric(make_numeric!(
38+
HelpStart,
39+
&topic,
40+
lines.next().unwrap_or(&topic.as_str())
41+
));
42+
for line in lines {
43+
response.numeric(make_numeric!(HelpText, &topic, line));
44+
}
45+
response.numeric(make_numeric!(EndOfHelp, &topic));
46+
return Ok(());
47+
}
48+
}
49+
response.numeric(make_numeric!(HelpNotFound, &topic));
50+
}
51+
None => {
52+
let topic = "*";
53+
response.numeric(make_numeric!(HelpStart, topic, "Available help topics:"));
54+
response.numeric(make_numeric!(HelpText, topic, ""));
55+
for chunk in &server
56+
.iter_commands()
57+
.filter_map(|(k, v)| {
58+
if !v.restricted || is_oper {
59+
Some(k.to_ascii_uppercase())
60+
} else {
61+
None
62+
}
63+
})
64+
.sorted()
65+
.chunks(4)
66+
{
67+
let line = format!("{:16}", chunk.format(" "));
68+
response.numeric(make_numeric!(HelpText, topic, &line));
69+
}
70+
response.numeric(make_numeric!(EndOfHelp, topic));
71+
}
72+
};
73+
Ok(())
74+
}

sable_ircd/src/command/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ mod handlers {
4242
mod ban;
4343
mod cap;
4444
mod chathistory;
45+
mod help;
4546
mod info;
4647
mod invite;
4748
mod join;

sable_ircd/src/messages/numeric.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ define_messages! {
7373
371(Info) => { (line: &str) => ":{line}" },
7474
374(EndOfInfo) => { () => ":End of /INFO list" },
7575

76+
704(HelpStart) => { (subj: &str, line: &str) => "{subj} :{line}" },
77+
705(HelpText) => { (subj: &str, line: &str) => "{subj} :{line}" },
78+
706(EndOfHelp) => { (subj: &str) => "{subj} :End of /HELP" },
79+
7680

7781
400(UnknownError) => { (reason: &str) => ":{reason}" },
7882
401(NoSuchTarget) => { (unknown: &str) => "{unknown} :No such nick/channel" },
@@ -130,6 +134,8 @@ define_messages! {
130134

131135
440(ServicesNotAvailable) => { () => ":Services are not available"},
132136

137+
524(HelpNotFound) => { (subj: &str) => "{subj} :No help available on this topic" },
138+
133139
// https://ircv3.net/specs/extensions/monitor
134140
730(MonOnline) => { (content: &str ) => ":{content}" },
135141
731(MonOffline) => { (content: &str ) => ":{content}" },

0 commit comments

Comments
 (0)