Skip to content

Commit

Permalink
WIP: implement HELP
Browse files Browse the repository at this point in the history
  • Loading branch information
internet-catte committed May 24, 2024
1 parent 5dec6b6 commit 6cdd411
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 2 deletions.
2 changes: 2 additions & 0 deletions sable_ircd/src/command/client_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ pub struct ClientCommand {
pub args: Vec<String>,
/// Tags provided by the client
pub tags: InboundTagSet,
/// Command help information
//cmd_help: CommandHelp,

// The response sink. labeled-response requires that this lives for the whole
// lifetime of the command, not just the handler duration, because even translated
Expand Down
1 change: 1 addition & 0 deletions sable_ircd/src/command/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct CommandRegistration {
pub(super) command: &'static str,
pub(super) dispatcher: Option<&'static str>,
pub(super) handler: CommandHandlerWrapper,
pub(super) help: Vec<&'static str>,
}

/// A command dispatcher. Collects registered command handlers and allows lookup by
Expand Down
62 changes: 62 additions & 0 deletions sable_ircd/src/command/handlers/help.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use super::*;

use std::collections::HashMap;

Check warning on line 3 in sable_ircd/src/command/handlers/help.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

unused import: `std::collections::HashMap`

use itertools::Itertools;

#[command_handler("HELP")]

Check failure on line 7 in sable_ircd/src/command/handlers/help.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

mismatched types
/// Syntax: HELP [<subject>]
fn help_handler(
response: &dyn CommandResponse,
server: &ClientServer,

Check warning on line 11 in sable_ircd/src/command/handlers/help.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

unused variable: `server`
subject: Option<&str>,
) -> CommandResult {
// TODO: oper help? (and if oper help is on the same command, UHELP like solanum?)
// TODO: get this from doc comments
// TODO: how to add non-command topics?
// TODO: or btreemap (presorted)?
//let mut help_topics = HashMap::from([
// ("HELP".to_string(), "HELP [<subject>]\n\nGet information about subject.\nIf subject is not given, list available topics."),
// ("INFO".to_string(), "INFO\n\nShow information about this server."),
// ("asdfadsf".to_string(), "INFO\n\nShow information about this server."),
// ("asdf".to_string(), "INFO\n\nShow information about this server."),
// ("hfasdfxdv".to_string(), "INFO\n\nShow information about this server."),
// ("dfadfNFO".to_string(), "INFO\n\nShow information about this server."),
// ("dfdfdf".to_string(), "INFO\n\nShow information about this server."),
// ("nxcnjvxc".to_string(), "INFO\n\nShow information about this server."),
//]);

match subject {
Some(s) => {
let subject = s.to_ascii_uppercase();
let subject = match subject.split_once(' ') {
Some((subj, _)) => subj.to_string(),
None => subject,
};

for reg in inventory::iter::<CommandRegistration> {
if reg.command == subject {
let mut lines = reg.help.iter();
response.numeric(make_numeric!(HelpStart, &subject, lines.next().unwrap_or(&subject.as_str())));
for line in lines {
response.numeric(make_numeric!(HelpText, &subject, line));
}
response.numeric(make_numeric!(EndOfHelp, &subject));
} else {
response.numeric(make_numeric!(HelpNotFound, &subject))
}
}
},
None => {
let subject = "*";
response.numeric(make_numeric!(HelpStart, subject, "Available help topics:"));
response.numeric(make_numeric!(HelpText, subject, ""));
for chunk in &inventory::iter::<CommandRegistration>.into_iter().map(|v| v.command.to_ascii_uppercase()).chunks(4) {
let line = format!("{:16}", chunk.format(" "));
response.numeric(make_numeric!(HelpText, subject, &line));
}
response.numeric(make_numeric!(EndOfHelp, subject));
},
};
Ok(())
}
1 change: 1 addition & 0 deletions sable_ircd/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ mod handlers {
mod ban;
mod cap;
mod chathistory;
mod help;
mod invite;
mod join;
mod kick;
Expand Down
6 changes: 6 additions & 0 deletions sable_ircd/src/messages/numeric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ define_messages! {

381(YoureOper) => { () => "You are now an IRC operator" },

704(HelpStart) => { (subj: &str, line: &str) => "{subj} :{line}" },
705(HelpText) => { (subj: &str, line: &str) => "{subj} :{line}" },
706(EndOfHelp) => { (subj: &str) => "{subj} :End of /HELP" },


401(NoSuchTarget) => { (unknown: &str) => "{unknown} :No such nick/channel" },
402(NoSuchServer) => { (server_name: &ServerName) => "{server_name} :No such server" },
Expand Down Expand Up @@ -122,6 +126,8 @@ define_messages! {

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

524(HelpNotFound) => { (subj: &str) => "{subj} :No help available on this topic" },

// https://ircv3.net/specs/extensions/monitor
730(MonOnline) => { (content: &str ) => ":{content}" },
731(MonOffline) => { (content: &str ) => ":{content}" },
Expand Down
16 changes: 14 additions & 2 deletions sable_macros/src/command_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::*;

use quote::{quote, quote_spanned};
use syn::{
parenthesized, parse::Parse, parse_macro_input, token::In, Ident, ItemFn, LitStr, Token,
parenthesized, parse::Parse, parse_macro_input, token::In, Ident, ItemFn, LitStr, Meta, MetaList, MetaNameValue, Token

Check warning on line 5 in sable_macros/src/command_handler.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

unused import: `MetaList`
};

struct CommandHandlerAttr {
Expand Down Expand Up @@ -43,6 +43,17 @@ pub fn command_handler(attr: TokenStream, item: TokenStream) -> TokenStream {
}
}

let help = item.attrs.clone().into_iter().filter(|a| a.path.is_ident("doc")).filter_map(|a| {
match a.parse_meta() {
Ok(Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. })) => Some(s),
//Ok(Meta::List(MetaList { path, .. })) if path.is_ident("hidden") => {
// hidden = true;
// None
//},
_ => None,
}
}).collect::<Vec<LitStr>>();

let dispatcher = match input.dispatcher {
Some(name) => quote!( Some( #name ) ),
None => quote!(None),
Expand Down Expand Up @@ -91,7 +102,8 @@ pub fn command_handler(attr: TokenStream, item: TokenStream) -> TokenStream {
inventory::submit!(crate::command::CommandRegistration {
command: #command_name,
dispatcher: #dispatcher,
handler: call_proxy
handler: call_proxy,
help: [#(#help,)*],
});
}
).into()
Expand Down

0 comments on commit 6cdd411

Please sign in to comment.