rush_sync_server/commands/
plugins.rs

1// =====================================================
2// FILE: commands/plugins.rs - OBJECT-SAFE PLUGIN SYSTEM
3// =====================================================
4
5use super::command::Command;
6use super::registry::CommandRegistry;
7
8/// ✅ PLUGIN SYSTEM für externe Commands - JETZT OBJECT-SAFE!
9pub trait CommandPlugin {
10    /// Lädt alle Commands des Plugins
11    fn load_commands(&self) -> Vec<Box<dyn Command>>;
12
13    /// Plugin Name
14    fn name(&self) -> &'static str;
15
16    /// Plugin Version (optional)
17    fn version(&self) -> &'static str {
18        "1.0.0"
19    }
20
21    /// Plugin ist verfügbar? (für conditional loading)
22    fn is_available(&self) -> bool {
23        true
24    }
25}
26
27/// Plugin Manager verwaltet alle Plugins
28pub struct PluginManager {
29    plugins: Vec<Box<dyn CommandPlugin>>,
30}
31
32impl PluginManager {
33    /// Neuer Plugin Manager
34    pub fn new() -> Self {
35        Self {
36            plugins: Vec::new(),
37        }
38    }
39
40    /// Plugin laden
41    pub fn load_plugin<T: CommandPlugin + 'static>(&mut self, plugin: T) -> &mut Self {
42        if plugin.is_available() {
43            log::debug!("Loading plugin: {} v{}", plugin.name(), plugin.version());
44            self.plugins.push(Box::new(plugin));
45        } else {
46            log::warn!("Plugin not available: {}", plugin.name());
47        }
48        self
49    }
50
51    /// Alle Plugin-Commands zur Registry hinzufügen
52    pub fn apply_to_registry(&mut self, registry: &mut CommandRegistry) {
53        for plugin in &self.plugins {
54            log::debug!("Applying plugin: {}", plugin.name());
55
56            for command in plugin.load_commands() {
57                registry.register_boxed(command);
58            }
59        }
60
61        // Registry nach Plugin-Loading neu initialisieren
62        registry.initialize();
63    }
64
65    /// Plugin-Statistiken
66    pub fn stats(&self) -> (usize, usize) {
67        let total = self.plugins.len();
68        let available = self.plugins.iter().filter(|p| p.is_available()).count();
69        (total, available)
70    }
71
72    /// Alle geladenen Plugins auflisten
73    pub fn list_plugins(&self) -> Vec<(&str, &str, bool)> {
74        self.plugins
75            .iter()
76            .map(|p| (p.name(), p.version(), p.is_available()))
77            .collect()
78    }
79}
80
81impl Default for PluginManager {
82    fn default() -> Self {
83        Self::new()
84    }
85}
86
87// =====================================================
88// BEISPIEL-IMPLEMENTIERUNG - Network Plugin
89// =====================================================
90
91/*
92use crate::commands::command::Command;
93use crate::core::prelude::*;
94
95// Beispiel: Ping Command
96#[derive(Debug)]
97pub struct PingCommand;
98
99impl Command for PingCommand {
100    fn name(&self) -> &'static str { "ping" }
101    fn description(&self) -> &'static str { "Ping a host" }
102
103    fn matches(&self, command: &str) -> bool {
104        command.trim().to_lowercase().starts_with("ping")
105    }
106
107    fn execute_sync(&self, args: &[&str]) -> Result<String> {
108        match args.first() {
109            Some(host) => Ok(format!("Pinging {}...", host)),
110            None => Ok("Usage: ping <host>".to_string()),
111        }
112    }
113
114    fn priority(&self) -> u8 { 30 }
115}
116
117// Network Plugin
118pub struct NetworkPlugin;
119
120impl CommandPlugin for NetworkPlugin {
121    fn name(&self) -> &'static str {
122        "network"
123    }
124
125    fn version(&self) -> &'static str {
126        "1.0.0"
127    }
128
129    fn load_commands(&self) -> Vec<Box<dyn Command>> {
130        vec![
131            Box::new(PingCommand),
132            // Box::new(WgetCommand),
133            // Box::new(CurlCommand),
134        ]
135    }
136
137    fn is_available(&self) -> bool {
138        cfg!(feature = "network") // Nur mit network feature
139    }
140}
141
142// NUTZUNG:
143// let mut plugin_manager = PluginManager::new();
144// plugin_manager.load_plugin(NetworkPlugin);
145// plugin_manager.apply_to_registry(&mut registry);
146*/