Skip to content

Add HelpTopic inventory type for non-command help entries#189

Closed
gfnord wants to merge 1 commit into
Libera-Chat:masterfrom
gfnord:feat/help-topic-registry
Closed

Add HelpTopic inventory type for non-command help entries#189
gfnord wants to merge 1 commit into
Libera-Chat:masterfrom
gfnord:feat/help-topic-registry

Conversation

@gfnord

@gfnord gfnord commented Apr 18, 2026

Copy link
Copy Markdown

Context

PR #129 is implementing the HELP command and identified an open question: command docs (extracted from doc comments by the command_handler macro) cover command-specific topics, but there is no place to register help text for concepts — channel modes, user modes, ISUPPORT tokens, and so on.

What this PR adds

A HelpTopic type using the same inventory pattern already used by CommandRegistration, providing a compile-time registry for free-form help entries.

Usage

Register a topic anywhere in the codebase with inventory::submit!:

inventory::submit!(HelpTopic {
    topic: "CMODE_SECRET",
    lines: &[
        "CMODE_SECRET (+s)",
        "",
        "Marks the channel as secret. Secret channels are hidden from /LIST",
        "and /WHOIS for users who are not members.",
    ],
});

Look it up in a command handler:

// check command docs first, then fall back to free-form topics
if let Some(lines) = server.get_help_topic(&topic) {
    // send 704/705/706 numerics
}

New API

CommandDispatcher

  • get_help_topic(topic: &str) -> Option<&'static [&'static str]> — case-insensitive lookup
  • iter_help_topics() -> impl Iterator<Item = &'static HelpTopic> — enumerate all topics (for listing)

ClientServer — thin forwards to the above, so command handlers don't need to reach into the dispatcher directly.

How a HELP handler should combine both registries

// 1. Check command registry (populated by #[command_handler] doc comments — see #129)
// 2. Fall back to HelpTopic registry (this PR)
let lines = server.get_command_docs(&topic)   // added by #129
    .or_else(|| server.get_help_topic(&topic));

match lines {
    Some(lines) => { /* send 704/705/706 */ }
    None        => { /* send 524 HelpNotFound */ }
}

Changes

  • sable_ircd/src/command/dispatcher.rsHelpTopic struct, inventory::collect!(HelpTopic), two methods on CommandDispatcher
  • sable_ircd/src/server/mod.rs — forwarding methods on ClientServer

Introduces a compile-time registry for free-form help topics that are
not tied to a command handler — channel modes, user modes, or any other
concept a user might query with HELP <topic>.

Topics are registered at the call site via inventory::submit!:

    inventory::submit!(HelpTopic {
        topic: "CMODE_SECRET",
        lines: &[
            "CMODE_SECRET (+s)",
            "",
            "Marks the channel as secret.",
        ],
    });

CommandDispatcher gains two new methods:
  - get_help_topic(topic) -> Option<&'static [&'static str]>
  - iter_help_topics()    -> impl Iterator<Item = &'static HelpTopic>

ClientServer forwards both so command handlers can call them directly.

A HELP handler (see Libera-Chat#129) should query the command registry for
command docs and fall back to get_help_topic() for concept entries,
giving full coverage with no runtime I/O.
@progval

progval commented Apr 18, 2026

Copy link
Copy Markdown
Collaborator

Sounds good, but this doesn't seem to be actually exposed to users.

And don't we want to use files instead? It has the extra benefit of being configurable

@internet-catte

Copy link
Copy Markdown
Contributor

my plan, when I get back to it, was probably files.

@gfnord

gfnord commented Apr 18, 2026

Copy link
Copy Markdown
Author

Hi,

The main reason for the inventory approach is consistency — CommandRegistration already uses the same pattern, so HelpTopic fits naturally alongside it with no new conventions to introduce. Help text registered this way lives next to the code it describes (e.g. a mode's doc sits in the same file as its implementation), which makes it easier to keep in sync when the implementation changes.

A file-based approach would add runtime I/O, deployment concerns (where do files live, are they bundled, what if they're missing), and a separate configuration surface that the rest of the codebase doesn't have. That said, this is just the registry infrastructure — if the consensus is to go file-based, it's straightforward to swap the backend later without changing how HelpTopic is used from command handlers.

What do you guys think?

@progval

progval commented Apr 18, 2026

Copy link
Copy Markdown
Collaborator

CommandRegistration is not configurable because it would require users to change the code.

A file-based approach would add runtime I/O, deployment concerns (where do files live, are they bundled, what if they're missing)

Solanum loads them on startup and rehash by listing a directory.

@gfnord

gfnord commented Apr 18, 2026

Copy link
Copy Markdown
Author

I'll rework it to be file-based. Will work on it this weekend.

@internet-catte

Copy link
Copy Markdown
Contributor

who will work on it, you or claudegpt?

@gfnord

gfnord commented Apr 18, 2026 via email

Copy link
Copy Markdown
Author

@spb

spb commented Apr 18, 2026

Copy link
Copy Markdown
Collaborator

As mentioned above, this is the wrong way to do this.

@spb spb closed this Apr 18, 2026
@gfnord gfnord deleted the feat/help-topic-registry branch April 19, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants