rush_sync_server/commands/help/
command.rs1use crate::commands::command::Command;
2use crate::core::prelude::*;
3
4#[derive(Debug, Default)]
5pub struct HelpCommand;
6
7impl HelpCommand {
8 pub fn new() -> Self {
9 Self
10 }
11}
12
13impl Command for HelpCommand {
14 fn name(&self) -> &'static str {
15 "help"
16 }
17
18 fn description(&self) -> &'static str {
19 "Show all available commands"
20 }
21
22 fn matches(&self, command: &str) -> bool {
23 let cmd = command.trim().to_lowercase();
24 cmd == "help" || cmd == "?" || cmd == "commands" || cmd == "list-commands"
25 }
26
27 fn execute_sync(&self, args: &[&str]) -> Result<String> {
28 let handler = crate::commands::CommandHandler::new();
29
30 match args.first() {
31 Some(&"--simple" | &"-s") => Ok(self.create_simple_list(&handler)),
32 Some(&"--detailed" | &"-d") => Ok(self.create_detailed_list(&handler)),
33 None => Ok(self.create_formatted_list(&handler)),
34 Some(&command_name) => Ok(self.show_command_help(command_name, &handler)),
35 }
36 }
37
38 fn priority(&self) -> u8 {
39 95
40 }
41}
42
43impl HelpCommand {
44 fn get_localized_description(&self, command_name: &str, original_description: &str) -> String {
46 let normalized_name = command_name.replace("-", "_");
48 let description_key = format!("system.commands.{}.description", normalized_name);
49
50 if crate::i18n::has_translation(&description_key) {
52 get_command_translation(&description_key, &[])
53 } else {
54 log::debug!(
56 "No translation found for key '{}', using original description",
57 description_key
58 );
59 original_description.to_string()
60 }
61 }
62
63 fn create_formatted_list(&self, handler: &crate::commands::CommandHandler) -> String {
65 let commands = handler.list_commands();
66
67 if commands.is_empty() {
68 return get_command_translation("system.commands.help.no_commands", &[]);
69 }
70
71 let mut result = String::new();
72 result.push_str(&get_command_translation("system.commands.help.header", &[]));
73 result.push_str("\n\n");
74
75 let mut categorized = std::collections::BTreeMap::new();
77
78 for (name, original_description) in commands {
79 let category_key = self.determine_category(name);
80 let localized_description = self.get_localized_description(name, original_description);
81
82 categorized
83 .entry(category_key)
84 .or_insert_with(Vec::new)
85 .push((name, localized_description));
86 }
87
88 for (category_key, commands) in categorized {
90 let category_translation_key =
91 format!("system.commands.help.category.{}", category_key);
92
93 let category_name = if crate::i18n::has_translation(&category_translation_key) {
95 get_command_translation(&category_translation_key, &[])
96 } else {
97 log::debug!(
98 "No translation for category '{}', using fallback",
99 category_key
100 );
101 self.get_fallback_category_name(category_key)
102 };
103
104 result.push_str(&format!("{}:\n", category_name));
105
106 for (name, description) in commands {
107 result.push_str(&format!(" {:12} - {}\n", name, description));
108 }
109 result.push('\n');
110 }
111
112 result.push_str(&get_command_translation("system.commands.help.footer", &[]));
113 result
114 }
115
116 fn determine_category(&self, command_name: &str) -> &'static str {
118 match command_name {
119 name if name.starts_with("start")
120 || name.starts_with("stop")
121 || name.starts_with("restart") =>
122 {
123 "server_control"
124 }
125 name if name.starts_with("create") || name.starts_with("list") => "server_management",
126 name if name.starts_with("cleanup") || name.starts_with("recover") => "maintenance",
127 name if name.starts_with("theme")
128 || name.starts_with("lang")
129 || name.starts_with("log-level") =>
130 {
131 "configuration"
132 }
133 name if name.starts_with("help")
134 || name.starts_with("version")
135 || name.starts_with("history") =>
136 {
137 "information"
138 }
139 name if name.starts_with("exit") || name.starts_with("clear") => "system",
140 _ => "other",
141 }
142 }
143
144 fn get_fallback_category_name(&self, category_key: &str) -> String {
146 match category_key {
147 "server_control" => "Server Control".to_string(),
148 "server_management" => "Server Management".to_string(),
149 "maintenance" => "Maintenance".to_string(),
150 "configuration" => "Configuration".to_string(),
151 "information" => "Information".to_string(),
152 "system" => "System".to_string(),
153 "other" => "Other".to_string(),
154 _ => category_key.to_string(),
155 }
156 }
157
158 fn create_simple_list(&self, handler: &crate::commands::CommandHandler) -> String {
160 let commands = handler.list_commands();
161 let names: Vec<&str> = commands.iter().map(|(name, _)| *name).collect();
162 let names_str = names.join(", ");
163
164 get_command_translation("system.commands.help.simple_list", &[&names_str])
165 }
166
167 fn create_detailed_list(&self, handler: &crate::commands::CommandHandler) -> String {
169 let commands = handler.list_commands();
170 let mut result = String::new();
171
172 result.push_str(&get_command_translation(
173 "system.commands.help.detailed_header",
174 &[],
175 ));
176 result.push('\n');
177 result.push_str(&get_command_translation(
178 "system.commands.help.detailed_separator",
179 &[],
180 ));
181 result.push_str("\n\n");
182
183 for (name, original_description) in commands {
184 let localized_description = self.get_localized_description(name, original_description);
185
186 let command_label = get_command_translation("system.commands.help.command_label", &[]);
187 let description_label =
188 get_command_translation("system.commands.help.description_label", &[]);
189 let usage_label = get_command_translation("system.commands.help.usage_label", &[]);
190 let separator = get_command_translation("system.commands.help.command_separator", &[]);
191
192 result.push_str(&format!("{} {}\n", command_label, name.to_uppercase()));
193 result.push_str(&format!(
194 "{} {}\n",
195 description_label, localized_description
196 ));
197 result.push_str(&format!("{} {} [options]\n", usage_label, name));
198 result.push_str(&format!("{}\n", separator));
199 }
200
201 result
202 }
203
204 fn show_command_help(
206 &self,
207 command_name: &str,
208 handler: &crate::commands::CommandHandler,
209 ) -> String {
210 let commands = handler.list_commands();
211
212 for (name, original_description) in commands {
213 if name.eq_ignore_ascii_case(command_name) {
214 let localized_description =
215 self.get_localized_description(name, original_description);
216
217 return get_command_translation(
218 "system.commands.help.specific_help_template",
219 &[name, &localized_description, name, name],
220 );
221 }
222 }
223
224 get_command_translation("system.commands.help.command_not_found", &[command_name])
225 }
226}