rush_sync_server/commands/
handler.rs

1// =====================================================
2// FILE: src/commands/handler.rs - UNICODE-SAFE VERSION
3// =====================================================
4
5use super::registry::CommandRegistry;
6use crate::i18n;
7
8#[derive(Debug)]
9pub struct CommandResult {
10    pub message: String,
11    pub success: bool,
12    pub should_exit: bool,
13}
14
15pub struct CommandHandler {
16    registry: CommandRegistry,
17}
18
19impl CommandHandler {
20    pub fn new() -> Self {
21        Self {
22            registry: crate::create_default_registry(),
23        }
24    }
25
26    pub fn with_registry(registry: CommandRegistry) -> Self {
27        Self { registry }
28    }
29
30    pub fn handle_input(&self, input: &str) -> CommandResult {
31        let input = input.trim();
32        let parts: Vec<&str> = input.split_whitespace().collect();
33
34        if input.is_empty() {
35            return CommandResult {
36                message: String::new(),
37                success: false,
38                should_exit: false,
39            };
40        }
41
42        log::info!("🔧 CommandHandler processing: '{}'", input);
43
44        match self.registry.execute_sync(parts[0], &parts[1..]) {
45            Some(Ok(msg)) => {
46                // ✅ UNICODE-SAFE PREVIEW - nutzt char boundaries
47                let preview = if msg.chars().count() > 100 {
48                    format!("{}...", msg.chars().take(97).collect::<String>())
49                } else {
50                    msg.clone()
51                };
52
53                log::info!(
54                    "🔧 Command returned {} chars: '{}'",
55                    msg.chars().count(), // ✅ char count statt byte count
56                    preview
57                );
58
59                let should_exit = self.should_exit_on_message(&msg);
60                let result = CommandResult {
61                    message: msg,
62                    success: true,
63                    should_exit,
64                };
65
66                log::info!(
67                    "🔧 CommandResult: success={}, message_len={}, should_exit={}",
68                    result.success,
69                    result.message.chars().count(), // ✅ char count statt byte count
70                    result.should_exit
71                );
72
73                result
74            }
75            Some(Err(e)) => {
76                log::error!("🔧 Command error: {}", e);
77                CommandResult {
78                    message: e.to_string(),
79                    success: false,
80                    should_exit: false,
81                }
82            }
83            None => {
84                log::warn!("🔧 Unknown command: {}", input);
85                CommandResult {
86                    message: crate::i18n::get_command_translation(
87                        "system.commands.unknown",
88                        &[input],
89                    ),
90                    success: false,
91                    should_exit: false,
92                }
93            }
94        }
95    }
96
97    pub async fn handle_input_async(&self, input: &str) -> CommandResult {
98        let input = input.trim();
99        let parts: Vec<&str> = input.split_whitespace().collect();
100
101        if input.is_empty() {
102            return CommandResult {
103                message: String::new(),
104                success: false,
105                should_exit: false,
106            };
107        }
108
109        match self.registry.execute_async(parts[0], &parts[1..]).await {
110            Some(Ok(msg)) => {
111                let should_exit = self.should_exit_on_message(&msg);
112                CommandResult {
113                    message: msg,
114                    success: true,
115                    should_exit,
116                }
117            }
118            Some(Err(e)) => CommandResult {
119                message: e.to_string(),
120                success: false,
121                should_exit: false,
122            },
123            None => CommandResult {
124                message: i18n::get_command_translation("system.commands.unknown", &[input]),
125                success: false,
126                should_exit: false,
127            },
128        }
129    }
130
131    pub fn add_command<T: crate::commands::command::Command>(&mut self, command: T) {
132        self.registry.register(command);
133    }
134
135    pub fn list_commands(&self) -> Vec<(&str, &str)> {
136        self.registry.list_commands()
137    }
138
139    pub fn debug_info(&self) -> String {
140        self.registry.debug_info()
141    }
142
143    fn should_exit_on_message(&self, message: &str) -> bool {
144        message.starts_with("__EXIT__")
145            || message.starts_with("__CONFIRM_EXIT__")
146            || message.starts_with("__RESTART__")
147            || message.starts_with("__CONFIRM_RESTART__")
148    }
149}
150
151impl Default for CommandHandler {
152    fn default() -> Self {
153        Self::new()
154    }
155}