Skip to content

Commit 8f667e6

Browse files
authored
Merge pull request #1 from gfnord/feat/help-topic-registry-local
Add HelpTopic inventory type for non-command help entries
2 parents 08db40d + 667b959 commit 8f667e6

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

sable_ircd/src/command/dispatcher.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,41 @@ pub struct CommandRegistration {
1414
pub(super) handler: CommandHandlerWrapper,
1515
}
1616

17+
/// A free-form help topic not tied to a command handler.
18+
///
19+
/// Use this for topics that describe concepts rather than commands — for example
20+
/// channel modes, user modes, or any other subject a user might query with `HELP`.
21+
///
22+
/// Register a topic at the call site with [`inventory::submit!`]:
23+
///
24+
/// ```rust,ignore
25+
/// inventory::submit!(HelpTopic {
26+
/// topic: "CMODE_SECRET",
27+
/// lines: &[
28+
/// "CMODE_SECRET (+s)",
29+
/// "",
30+
/// "Marks the channel as secret. Secret channels are hidden from /LIST",
31+
/// "and /WHOIS for users who are not members.",
32+
/// ],
33+
/// });
34+
/// ```
35+
///
36+
/// Topics are looked up case-insensitively via [`CommandDispatcher::get_help_topic`].
37+
pub struct HelpTopic {
38+
/// The name of the topic, matched case-insensitively against the argument to `HELP`.
39+
pub topic: &'static str,
40+
/// Lines of help text returned to the client.
41+
pub lines: &'static [&'static str],
42+
}
43+
1744
/// A command dispatcher. Collects registered command handlers and allows lookup by
1845
/// command name.
1946
pub struct CommandDispatcher {
2047
handlers: HashMap<String, CommandHandlerWrapper>,
2148
}
2249

2350
inventory::collect!(CommandRegistration);
51+
inventory::collect!(HelpTopic);
2452

2553
impl CommandDispatcher {
2654
/// Construct a default `CommandDispatcher`.
@@ -67,4 +95,19 @@ impl CommandDispatcher {
6795
}
6896
}
6997
}
98+
99+
/// Look up a free-form [`HelpTopic`] by name (case-insensitive).
100+
///
101+
/// Returns the topic's lines of text, or `None` if no topic with that name was registered.
102+
pub fn get_help_topic(&self, topic: &str) -> Option<&'static [&'static str]> {
103+
inventory::iter::<HelpTopic>
104+
.into_iter()
105+
.find(|t| t.topic.eq_ignore_ascii_case(topic))
106+
.map(|t| t.lines)
107+
}
108+
109+
/// Iterate over all registered free-form [`HelpTopic`] entries.
110+
pub fn iter_help_topics(&self) -> impl Iterator<Item = &'static HelpTopic> {
111+
inventory::iter::<HelpTopic>.into_iter()
112+
}
70113
}

sable_ircd/src/server/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,20 @@ impl ClientServer {
161161
&self.client_caps
162162
}
163163

164+
/// Look up a free-form help topic by name (case-insensitive).
165+
///
166+
/// Returns the help lines registered via [`command::HelpTopic`], or `None` if no matching
167+
/// topic was found. Command handlers that implement `HELP` should query this alongside
168+
/// the command registry to cover both command docs and concept topics (modes, etc.).
169+
pub fn get_help_topic(&self, topic: &str) -> Option<&'static [&'static str]> {
170+
self.command_dispatcher.get_help_topic(topic)
171+
}
172+
173+
/// Iterate over all free-form help topics registered via [`command::HelpTopic`].
174+
pub fn iter_help_topics(&self) -> impl Iterator<Item = &'static command::HelpTopic> {
175+
self.command_dispatcher.iter_help_topics()
176+
}
177+
164178
/// Store a [`MessageSink`] to use when processing updates caused by the given event
165179
pub(crate) fn store_response_sink(
166180
&self,

0 commit comments

Comments
 (0)