@@ -3,7 +3,7 @@ use super::*;
33use itertools:: Itertools ;
44
55#[ command_handler( "HELP" , "UHELP" ) ]
6- /// HELP [ <topic> ]
6+ /// HELP \[\ <topic\>\ ]
77///
88/// HELP displays information for topic requested.
99/// If no topic is requested, it will list available
@@ -15,60 +15,119 @@ fn help_handler(
1515 source : UserSource ,
1616 topic : Option < & str > ,
1717) -> CommandResult {
18- // TODO: oper help? (and if oper help is on the same command, UHELP like solanum?)
18+ // TODO: better restricted mechanism?
1919 // TODO: non-command help topics
2020 let is_oper = command. command ( ) . to_ascii_uppercase ( ) != "UHELP" && source. is_oper ( ) ;
2121
2222 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 ( ) ) ;
23+ Some ( t) => {
24+ let topic = t. to_ascii_uppercase ( ) ;
25+ let topic = topic. split_once ( ' ' ) . map_or ( topic. clone ( ) , |( t, _) | t. to_string ( ) ) ;
26+ if let Some ( mut lines) = get_help ( & server. command_dispatcher , & topic, is_oper) {
27+ response. numeric ( make_numeric ! (
28+ HelpStart ,
29+ & topic,
30+ lines. next( ) . unwrap( ) . as_ref( )
31+ ) ) ;
32+ for line in lines {
33+ response. numeric ( make_numeric ! ( HelpText , & topic, line. as_ref( ) ) ) ;
34+ }
35+ response. numeric ( make_numeric ! ( EndOfHelp , & topic) ) ;
36+ return Ok ( ( ) ) ;
37+ } else {
38+ response. numeric ( make_numeric ! ( HelpNotFound , & topic) ) ;
39+ }
40+ }
41+ None => {
42+ let topic = "*" ;
43+ response. numeric ( make_numeric ! ( HelpStart , & topic, "Available help topics:" ) ) ;
44+ response. numeric ( make_numeric ! ( HelpText , & topic, "" ) ) ;
45+ for line in list_help ( & server. command_dispatcher , is_oper) {
46+ response. numeric ( make_numeric ! ( HelpText , & topic, line. as_ref( ) ) ) ;
47+ }
48+ response. numeric ( make_numeric ! ( EndOfHelp , & topic) ) ;
49+ }
50+ } ;
51+ Ok ( ( ) )
52+ }
2853
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 ( ( ) ) ;
54+ #[ command_handler( "HELP" , "UHELP" , in( "NS" ) ) ]
55+ /// NS HELP \[\<topic\>\]
56+ ///
57+ /// Displays information about the topic requested.
58+ fn ns_help_handler (
59+ command : & dyn Command ,
60+ response : & dyn CommandResponse ,
61+ server : & ClientServer ,
62+ source : UserSource ,
63+ topic : Option < & str > ,
64+ ) -> CommandResult {
65+ let is_oper = command. command ( ) . to_ascii_uppercase ( ) != "UHELP" && source. is_oper ( ) ;
66+ let dispatcher = CommandDispatcher :: with_category ( "NS" ) ;
67+
68+ match topic {
69+ Some ( t) => {
70+ let topic = t. to_ascii_uppercase ( ) ;
71+ let topic = topic. split_once ( ' ' ) . map_or ( topic. clone ( ) , |( t, _) | t. to_string ( ) ) ;
72+ if let Some ( mut lines) = get_help ( & dispatcher, & topic, is_oper) {
73+ response. numeric ( make_numeric ! (
74+ HelpStart ,
75+ & topic,
76+ lines. next( ) . unwrap( ) . as_ref( )
77+ ) ) ;
78+ for line in lines {
79+ response. numeric ( make_numeric ! ( HelpText , & topic, line. as_ref( ) ) ) ;
4780 }
81+ response. numeric ( make_numeric ! ( EndOfHelp , & topic) ) ;
82+ return Ok ( ( ) ) ;
83+ } else {
84+ response. numeric ( make_numeric ! ( HelpNotFound , & topic) ) ;
4885 }
49- response. numeric ( make_numeric ! ( HelpNotFound , & topic) ) ;
5086 }
5187 None => {
5288 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) ) ;
89+ response. numeric ( make_numeric ! ( HelpStart , & topic, "Available help topics:" ) ) ;
90+ response. numeric ( make_numeric ! ( HelpText , & topic, "" ) ) ;
91+ for line in list_help ( & dispatcher, is_oper) {
92+ response. numeric ( make_numeric ! ( HelpText , & topic, line. as_ref( ) ) ) ;
6993 }
70- response. numeric ( make_numeric ! ( EndOfHelp , topic) ) ;
94+ response. numeric ( make_numeric ! ( EndOfHelp , & topic) ) ;
7195 }
7296 } ;
7397 Ok ( ( ) )
7498}
99+
100+ fn get_help (
101+ dispatcher : & CommandDispatcher ,
102+ topic : & str ,
103+ is_oper : bool ,
104+ ) -> Option < impl Iterator < Item = impl AsRef < str > > > {
105+ if let Some ( cmd) = dispatcher. get_command ( & topic) {
106+ if cmd. docs . len ( ) > 0 {
107+ if cmd. restricted && !is_oper {
108+ return None ;
109+ }
110+ return Some ( cmd. docs . iter ( ) ) ;
111+ }
112+ }
113+ return None ;
114+ }
115+
116+ fn list_help ( dispatcher : & CommandDispatcher , is_oper : bool ) -> Vec < impl AsRef < str > > {
117+ let mut lines = vec ! [ ] ;
118+ for chunk in & dispatcher
119+ . iter_commands ( )
120+ . filter_map ( |( k, v) | {
121+ if ( !v. restricted || is_oper) && ( v. docs . len ( ) > 0 ) {
122+ Some ( k. to_ascii_uppercase ( ) )
123+ } else {
124+ None
125+ }
126+ } )
127+ . sorted ( )
128+ . chunks ( 4 )
129+ {
130+ lines. push ( format ! ( "{:16}" , chunk. format( " " ) ) ) ;
131+ }
132+ lines
133+ }
0 commit comments