1use scirs2_core::ndarray::{Array1, Array2, ArrayView1, ArrayView2};
6use sklears_core::{
7 error::{Result as SklResult, SklearsError},
8 traits::Estimator,
9 types::Float,
10};
11use std::any::Any;
12use std::collections::{HashMap, HashSet};
13use std::fmt::Debug;
14use std::path::PathBuf;
15use std::sync::{Arc, RwLock};
16
17use super::types::{
18 ComponentConfig, ComponentContext, ComponentSchema, ConfigValue, ExampleRegressor,
19 ExampleScaler, ExampleTransformerFactory, ExampleTransformerPlugin, PluginCapability,
20 PluginConfig, PluginContext, PluginLoader, PluginMetadata, PluginRegistry,
21};
22
23pub trait Plugin: Send + Sync + Debug {
25 fn metadata(&self) -> &PluginMetadata;
27 fn initialize(&mut self, context: &PluginContext) -> SklResult<()>;
29 fn shutdown(&mut self) -> SklResult<()>;
31 fn capabilities(&self) -> Vec<PluginCapability>;
33 fn create_component(
35 &self,
36 component_type: &str,
37 config: &ComponentConfig,
38 ) -> SklResult<Box<dyn PluginComponent>>;
39 fn validate_config(&self, config: &ComponentConfig) -> SklResult<()>;
41 fn get_component_schema(&self, component_type: &str) -> Option<ComponentSchema>;
43}
44pub trait PluginComponent: Send + Sync + Debug {
46 fn component_type(&self) -> &str;
48 fn config(&self) -> &ComponentConfig;
50 fn initialize(&mut self, context: &ComponentContext) -> SklResult<()>;
52 fn clone_component(&self) -> Box<dyn PluginComponent>;
54 fn as_any(&self) -> &dyn Any;
56 fn as_any_mut(&mut self) -> &mut dyn Any;
58}
59pub trait PluginTransformer: PluginComponent {
61 fn fit(
63 &mut self,
64 x: &ArrayView2<'_, Float>,
65 y: Option<&ArrayView1<'_, Float>>,
66 ) -> SklResult<()>;
67 fn transform(&self, x: &ArrayView2<'_, Float>) -> SklResult<Array2<f64>>;
69 fn fit_transform(
71 &mut self,
72 x: &ArrayView2<'_, Float>,
73 y: Option<&ArrayView1<'_, Float>>,
74 ) -> SklResult<Array2<f64>> {
75 self.fit(x, y)?;
76 self.transform(x)
77 }
78 fn is_fitted(&self) -> bool;
80 fn get_feature_names_out(&self, input_features: Option<&[String]>) -> Vec<String>;
82}
83pub trait PluginEstimator: PluginComponent {
85 fn fit(&mut self, x: &ArrayView2<'_, Float>, y: &ArrayView1<'_, Float>) -> SklResult<()>;
87 fn predict(&self, x: &ArrayView2<'_, Float>) -> SklResult<Array1<f64>>;
89 fn predict_proba(&self, x: &ArrayView2<'_, Float>) -> SklResult<Array2<f64>> {
91 Err(SklearsError::InvalidOperation(
92 "predict_proba not implemented for this estimator".to_string(),
93 ))
94 }
95 fn score(&self, x: &ArrayView2<'_, Float>, y: &ArrayView1<'_, Float>) -> SklResult<f64>;
97 fn is_fitted(&self) -> bool;
99 fn feature_importances(&self) -> Option<Array1<f64>> {
101 None
102 }
103}
104pub trait ComponentFactory: Send + Sync + Debug {
106 fn create(
108 &self,
109 component_type: &str,
110 config: &ComponentConfig,
111 ) -> SklResult<Box<dyn PluginComponent>>;
112 fn available_types(&self) -> Vec<String>;
114 fn get_schema(&self, component_type: &str) -> Option<ComponentSchema>;
116}
117#[allow(non_snake_case)]
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use scirs2_core::ndarray::array;
122 #[test]
123 fn test_plugin_registry_creation() {
124 let config = PluginConfig::default();
125 let registry = PluginRegistry::new(config);
126 assert!(registry.list_plugins().unwrap_or_default().is_empty());
127 }
128 #[test]
129 fn test_plugin_registration() {
130 let config = PluginConfig::default();
131 let registry = PluginRegistry::new(config);
132 let plugin = Box::new(ExampleTransformerPlugin::new());
133 let factory = Box::new(ExampleTransformerFactory::new());
134 registry
135 .register_plugin("test_plugin", plugin, factory)
136 .unwrap_or_default();
137 let plugins = registry.list_plugins().unwrap_or_default();
138 assert_eq!(plugins.len(), 1);
139 assert!(plugins.contains(&"test_plugin".to_string()));
140 }
141 #[test]
142 fn test_component_creation() {
143 let config = PluginConfig::default();
144 let registry = PluginRegistry::new(config);
145 let plugin = Box::new(ExampleTransformerPlugin::new());
146 let factory = Box::new(ExampleTransformerFactory::new());
147 registry
148 .register_plugin("test_plugin", plugin, factory)
149 .unwrap_or_default();
150 let component_config = ComponentConfig {
151 component_type: "example_scaler".to_string(),
152 parameters: {
153 let mut params = HashMap::new();
154 params.insert("scale_factor".to_string(), ConfigValue::Float(2.0));
155 params
156 },
157 metadata: HashMap::new(),
158 };
159 let component = registry
160 .create_component("test_plugin", "example_scaler", &component_config)
161 .expect("operation should succeed");
162 assert_eq!(component.component_type(), "example_scaler");
163 }
164 #[test]
165 fn test_example_scaler() {
166 let config = ComponentConfig {
167 component_type: "example_scaler".to_string(),
168 parameters: {
169 let mut params = HashMap::new();
170 params.insert("scale_factor".to_string(), ConfigValue::Float(2.0));
171 params
172 },
173 metadata: HashMap::new(),
174 };
175 let mut scaler = ExampleScaler::new(config);
176 let x = array![[1.0, 2.0], [3.0, 4.0]];
177 scaler.fit(&x.view(), None).unwrap_or_default();
178 assert!(scaler.is_fitted());
179 let transformed = scaler.transform(&x.view()).unwrap_or_default();
180 assert_eq!(transformed, array![[2.0, 4.0], [6.0, 8.0]]);
181 }
182 #[test]
183 fn test_example_regressor() {
184 let config = ComponentConfig {
185 component_type: "example_regressor".to_string(),
186 parameters: {
187 let mut params = HashMap::new();
188 params.insert("learning_rate".to_string(), ConfigValue::Float(0.001));
189 params
190 },
191 metadata: HashMap::new(),
192 };
193 let mut regressor = ExampleRegressor::new(config);
194 let x = array![[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]];
195 let y = array![3.0, 7.0, 11.0];
196 regressor.fit(&x.view(), &y.view()).unwrap_or_default();
197 assert!(regressor.is_fitted());
198 let predictions = regressor.predict(&x.view()).unwrap_or_default();
199 assert_eq!(predictions.len(), 3);
200 let score = regressor.score(&x.view(), &y.view()).unwrap_or_default();
201 assert!(score > -1.0);
202 }
203 #[test]
204 fn test_plugin_loader() {
205 let config = PluginConfig::default();
206 let registry = PluginRegistry::new(config.clone());
207 let mut loader = PluginLoader::new(config);
208 loader.load_example_plugins(®istry).unwrap_or_default();
209 let plugins = registry.list_plugins().unwrap_or_default();
210 assert_eq!(plugins.len(), 2);
211 assert!(plugins.contains(&"example_transformer".to_string()));
212 assert!(plugins.contains(&"example_estimator".to_string()));
213 }
214 #[test]
215 fn test_component_schema() {
216 let plugin = ExampleTransformerPlugin::new();
217 let schema = plugin
218 .get_component_schema("example_scaler")
219 .expect("operation should succeed");
220 assert_eq!(schema.name, "ExampleScaler");
221 assert_eq!(schema.required_parameters.len(), 0);
222 assert_eq!(schema.optional_parameters.len(), 1);
223 assert_eq!(schema.optional_parameters[0].name, "scale_factor");
224 }
225 #[test]
226 fn test_plugin_dependencies() {
227 let config = PluginConfig::default();
228 let registry = PluginRegistry::new(config);
229 let metadata = PluginMetadata {
230 name: "Dependent Plugin".to_string(),
231 version: "1.0.0".to_string(),
232 description: "Plugin with dependencies".to_string(),
233 author: "Test".to_string(),
234 license: "MIT".to_string(),
235 min_api_version: "1.0.0".to_string(),
236 dependencies: vec!["nonexistent_plugin".to_string()],
237 capabilities: vec!["transformer".to_string()],
238 tags: vec![],
239 documentation_url: None,
240 source_url: None,
241 };
242 let plugin = ExampleTransformerPlugin::with_metadata(metadata);
243 let factory = Box::new(ExampleTransformerFactory::new());
244 let result = registry.register_plugin("dependent_plugin", Box::new(plugin), factory);
245 assert!(result.is_err());
246 }
247}
248pub mod advanced_plugin_system {
250 use super::{
251 Arc, Debug, HashMap, HashSet, PathBuf, PluginConfig, PluginLoader, PluginRegistry, RwLock,
252 SklResult, SklearsError,
253 };
254 use std::sync::atomic::{AtomicBool, Ordering};
255 use std::thread;
256 use std::time::{Duration, SystemTime};
257 pub struct AdvancedPluginManager {
259 registry: Arc<PluginRegistry>,
260 loader: PluginLoader,
261 watcher: Option<PluginWatcher>,
262 version_manager: VersionManager,
263 security_manager: SecurityManager,
264 performance_monitor: PerformanceMonitor,
265 marketplace: PluginMarketplace,
266 }
267 pub struct PluginWatcher {
269 watched_dirs: Vec<PathBuf>,
270 running: Arc<AtomicBool>,
271 poll_interval: Duration,
272 }
273 #[derive(Debug)]
275 pub struct VersionManager {
276 installed_versions: HashMap<String, Vec<SemanticVersion>>,
277 active_versions: HashMap<String, SemanticVersion>,
278 compatibility_matrix: HashMap<String, Vec<VersionConstraint>>,
279 }
280 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
282 pub struct SemanticVersion {
283 pub major: u32,
284 pub minor: u32,
285 pub patch: u32,
286 pub pre_release: Option<String>,
287 pub build_metadata: Option<String>,
288 }
289 #[derive(Debug, Clone)]
291 pub struct VersionConstraint {
292 pub plugin_name: String,
293 pub constraint_type: ConstraintType,
294 pub version: SemanticVersion,
295 }
296 #[derive(Debug, Clone, PartialEq)]
298 pub enum ConstraintType {
299 Exact,
301 GreaterThan,
303 GreaterOrEqual,
305 LessThan,
307 LessOrEqual,
309 Compatible,
311 Tilde,
313 }
314 #[derive(Debug)]
316 pub struct SecurityManager {
317 sandbox_enabled: bool,
318 allowed_capabilities: HashSet<String>,
319 security_policies: HashMap<String, SecurityPolicy>,
320 threat_detection: ThreatDetector,
321 }
322 #[derive(Debug, Clone)]
324 pub struct SecurityPolicy {
325 pub plugin_name: String,
326 pub allowed_operations: HashSet<PluginOperation>,
327 pub resource_limits: SecurityResourceLimits,
328 pub network_access: NetworkAccess,
329 pub file_system_access: FileSystemAccess,
330 }
331 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
333 pub enum PluginOperation {
334 ReadData,
336 WriteData,
338 NetworkRequest,
340 FileRead,
342 FileWrite,
344 ProcessSpawn,
346 SystemCall,
348 DatabaseAccess,
350 EnvironmentAccess,
352 }
353 #[derive(Debug, Clone)]
355 pub struct SecurityResourceLimits {
356 pub max_memory: Option<usize>,
357 pub max_cpu_time: Option<Duration>,
358 pub max_network_bandwidth: Option<usize>,
359 pub max_file_descriptors: Option<usize>,
360 }
361 #[derive(Debug, Clone)]
363 pub enum NetworkAccess {
364 None,
365 Limited(Vec<String>),
367 Full,
369 }
370 #[derive(Debug, Clone)]
372 pub enum FileSystemAccess {
373 None,
374 ReadOnly(Vec<PathBuf>),
376 Limited(Vec<PathBuf>),
378 Full,
380 }
381 #[derive(Debug)]
383 pub struct ThreatDetector {
384 suspicious_patterns: Vec<ThreatPattern>,
385 monitoring_enabled: bool,
386 alert_callback: Option<fn(&ThreatAlert)>,
387 }
388 #[derive(Debug, Clone)]
390 pub struct ThreatPattern {
391 pub pattern_type: ThreatType,
392 pub pattern: String,
393 pub severity: ThreatSeverity,
394 pub description: String,
395 }
396 #[derive(Debug, Clone, PartialEq)]
398 pub enum ThreatType {
399 SuspiciousCode,
401 UnauthorizedAccess,
403 ResourceAbuse,
405 DataExfiltration,
407 MaliciousPayload,
409 }
410 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
412 pub enum ThreatSeverity {
413 Low,
414 Medium,
415 High,
416 Critical,
417 }
418 #[derive(Debug)]
420 pub struct ThreatAlert {
421 pub plugin_name: String,
422 pub threat_type: ThreatType,
423 pub severity: ThreatSeverity,
424 pub description: String,
425 pub timestamp: SystemTime,
426 pub details: HashMap<String, String>,
427 }
428 #[derive(Debug)]
430 pub struct PerformanceMonitor {
431 metrics: Arc<RwLock<HashMap<String, PluginMetrics>>>,
432 monitoring_enabled: bool,
433 collection_interval: Duration,
434 }
435 #[derive(Debug, Clone)]
437 pub struct PluginMetrics {
438 pub plugin_name: String,
439 pub execution_count: u64,
440 pub total_execution_time: Duration,
441 pub average_execution_time: Duration,
442 pub memory_usage: MemoryUsageStats,
443 pub error_rate: f64,
444 pub last_execution: Option<SystemTime>,
445 }
446 #[derive(Debug, Clone)]
448 pub struct MemoryUsageStats {
449 pub current_usage: usize,
450 pub peak_usage: usize,
451 pub average_usage: usize,
452 pub allocation_count: u64,
453 }
454 #[derive(Debug)]
456 pub struct PluginMarketplace {
457 repositories: Vec<PluginRepository>,
458 cache: Arc<RwLock<HashMap<String, MarketplaceEntry>>>,
459 update_interval: Duration,
460 last_update: Option<SystemTime>,
461 }
462 #[derive(Debug, Clone)]
464 pub struct PluginRepository {
465 pub url: String,
466 pub name: String,
467 pub auth_token: Option<String>,
468 pub trusted: bool,
469 pub priority: u32,
470 }
471 #[derive(Debug, Clone)]
473 pub struct MarketplaceEntry {
474 pub plugin_name: String,
475 pub versions: Vec<PluginVersion>,
476 pub description: String,
477 pub tags: Vec<String>,
478 pub downloads: u64,
479 pub rating: f64,
480 pub last_updated: SystemTime,
481 }
482 #[derive(Debug, Clone)]
484 pub struct PluginVersion {
485 pub version: SemanticVersion,
486 pub download_url: String,
487 pub checksum: String,
488 pub size: usize,
489 pub release_notes: String,
490 pub compatibility: Vec<String>,
491 }
492 impl AdvancedPluginManager {
493 pub fn new(config: PluginConfig) -> SklResult<Self> {
495 let registry = Arc::new(PluginRegistry::new(config.clone()));
496 let loader = PluginLoader::new(config.clone());
497 let version_manager = VersionManager::new();
498 let security_manager = SecurityManager::new(config.sandbox);
499 let performance_monitor = PerformanceMonitor::new();
500 let marketplace = PluginMarketplace::new();
501 let watcher = if config.auto_load {
502 Some(PluginWatcher::new(config.plugin_dirs))
503 } else {
504 None
505 };
506 Ok(Self {
507 registry,
508 loader,
509 watcher,
510 version_manager,
511 security_manager,
512 performance_monitor,
513 marketplace,
514 })
515 }
516 pub fn start(&mut self) -> SklResult<()> {
518 self.loader.load_plugins(&self.registry)?;
519 self.registry.initialize_all()?;
520 if let Some(ref mut watcher) = self.watcher {
521 watcher.start(Arc::clone(&self.registry))?;
522 }
523 self.performance_monitor.start_monitoring()?;
524 self.marketplace.update_cache()?;
525 Ok(())
526 }
527 pub fn stop(&mut self) -> SklResult<()> {
529 if let Some(ref mut watcher) = self.watcher {
530 watcher.stop();
531 }
532 self.performance_monitor.stop_monitoring()?;
533 self.registry.shutdown_all()?;
534 Ok(())
535 }
536 pub fn install_from_marketplace(
538 &mut self,
539 plugin_name: &str,
540 version: Option<&SemanticVersion>,
541 ) -> SklResult<()> {
542 let entry = self.marketplace.find_plugin(plugin_name)?;
543 let target_version = version.unwrap_or(&entry.versions[0].version);
544 self.security_manager
545 .validate_plugin_security(plugin_name)?;
546 let plugin_data = self
547 .marketplace
548 .download_plugin(plugin_name, target_version)?;
549 self.security_manager.scan_plugin(&plugin_data)?;
550 self.version_manager
551 .install_version(plugin_name, target_version.clone())?;
552 Ok(())
553 }
554 pub fn upgrade_plugin(
556 &mut self,
557 plugin_name: &str,
558 target_version: &SemanticVersion,
559 ) -> SklResult<()> {
560 self.version_manager
561 .check_upgrade_compatibility(plugin_name, target_version)?;
562 self.registry.unregister_plugin(plugin_name)?;
563 self.install_from_marketplace(plugin_name, Some(target_version))?;
564 Ok(())
565 }
566 #[must_use]
568 pub fn get_plugin_metrics(&self, plugin_name: &str) -> Option<PluginMetrics> {
569 self.performance_monitor.get_metrics(plugin_name)
570 }
571 #[must_use]
573 pub fn get_security_report(&self, plugin_name: &str) -> SecurityReport {
574 self.security_manager.generate_report(plugin_name)
575 }
576 #[must_use]
578 pub fn search_marketplace(&self, query: &str, tags: &[String]) -> Vec<MarketplaceEntry> {
579 self.marketplace.search(query, tags)
580 }
581 }
582 #[derive(Debug)]
584 pub struct SecurityReport {
585 pub plugin_name: String,
586 pub security_level: SecurityLevel,
587 pub violations: Vec<SecurityViolation>,
588 pub recommendations: Vec<String>,
589 pub last_scan: Option<SystemTime>,
590 }
591 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
593 pub enum SecurityLevel {
594 Safe,
596 LowRisk,
598 MediumRisk,
600 HighRisk,
602 Critical,
604 }
605 #[derive(Debug)]
607 pub struct SecurityViolation {
608 pub violation_type: ViolationType,
609 pub description: String,
610 pub severity: ThreatSeverity,
611 pub detected_at: SystemTime,
612 }
613 #[derive(Debug)]
615 pub enum ViolationType {
616 UnauthorizedFileAccess,
618 SuspiciousNetworkActivity,
620 ExcessiveResourceUsage,
622 PolicyViolation,
624 MaliciousCode,
626 }
627 impl PluginWatcher {
628 #[must_use]
629 pub fn new(dirs: Vec<PathBuf>) -> Self {
630 Self {
631 watched_dirs: dirs,
632 running: Arc::new(AtomicBool::new(false)),
633 poll_interval: Duration::from_secs(5),
634 }
635 }
636 pub fn start(&mut self, registry: Arc<PluginRegistry>) -> SklResult<()> {
637 self.running.store(true, Ordering::SeqCst);
638 let running = Arc::clone(&self.running);
639 let dirs = self.watched_dirs.clone();
640 let interval = self.poll_interval;
641 thread::spawn(move || {
642 while running.load(Ordering::SeqCst) {
643 for dir in &dirs {
644 if dir.exists() {}
645 }
646 thread::sleep(interval);
647 }
648 });
649 Ok(())
650 }
651 pub fn stop(&mut self) {
652 self.running.store(false, Ordering::SeqCst);
653 }
654 }
655 impl Default for VersionManager {
656 fn default() -> Self {
657 Self::new()
658 }
659 }
660 impl VersionManager {
661 #[must_use]
662 pub fn new() -> Self {
663 Self {
664 installed_versions: HashMap::new(),
665 active_versions: HashMap::new(),
666 compatibility_matrix: HashMap::new(),
667 }
668 }
669 pub fn install_version(
670 &mut self,
671 plugin_name: &str,
672 version: SemanticVersion,
673 ) -> SklResult<()> {
674 self.installed_versions
675 .entry(plugin_name.to_string())
676 .or_default()
677 .push(version.clone());
678 self.active_versions
679 .insert(plugin_name.to_string(), version);
680 Ok(())
681 }
682 pub fn check_upgrade_compatibility(
683 &self,
684 plugin_name: &str,
685 target_version: &SemanticVersion,
686 ) -> SklResult<()> {
687 if let Some(constraints) = self.compatibility_matrix.get(plugin_name) {
688 for constraint in constraints {
689 if !self.version_satisfies_constraint(target_version, constraint) {
690 return Err(SklearsError::InvalidInput(format!(
691 "Version {} does not satisfy constraint {:?}",
692 self.version_to_string(target_version),
693 constraint
694 )));
695 }
696 }
697 }
698 Ok(())
699 }
700 fn version_satisfies_constraint(
701 &self,
702 version: &SemanticVersion,
703 constraint: &VersionConstraint,
704 ) -> bool {
705 match constraint.constraint_type {
706 ConstraintType::Exact => version == &constraint.version,
707 ConstraintType::GreaterThan => version > &constraint.version,
708 ConstraintType::GreaterOrEqual => version >= &constraint.version,
709 ConstraintType::LessThan => version < &constraint.version,
710 ConstraintType::LessOrEqual => version <= &constraint.version,
711 ConstraintType::Compatible => {
712 version.major == constraint.version.major && version >= &constraint.version
713 }
714 ConstraintType::Tilde => {
715 version.major == constraint.version.major
716 && version.minor == constraint.version.minor
717 && version >= &constraint.version
718 }
719 }
720 }
721 fn version_to_string(&self, version: &SemanticVersion) -> String {
722 format!("{}.{}.{}", version.major, version.minor, version.patch)
723 }
724 }
725 impl SecurityManager {
726 #[must_use]
727 pub fn new(sandbox_enabled: bool) -> Self {
728 Self {
729 sandbox_enabled,
730 allowed_capabilities: HashSet::new(),
731 security_policies: HashMap::new(),
732 threat_detection: ThreatDetector::new(),
733 }
734 }
735 pub fn validate_plugin_security(&self, plugin_name: &str) -> SklResult<()> {
736 if let Some(policy) = self.security_policies.get(plugin_name) {
737 Ok(())
738 } else {
739 Ok(())
740 }
741 }
742 pub fn scan_plugin(&self, plugin_data: &[u8]) -> SklResult<()> {
743 self.threat_detection.scan_data(plugin_data)
744 }
745 #[must_use]
746 pub fn generate_report(&self, plugin_name: &str) -> SecurityReport {
747 SecurityReport {
749 plugin_name: plugin_name.to_string(),
750 security_level: SecurityLevel::Safe,
751 violations: Vec::new(),
752 recommendations: Vec::new(),
753 last_scan: Some(SystemTime::now()),
754 }
755 }
756 }
757 impl Default for ThreatDetector {
758 fn default() -> Self {
759 Self::new()
760 }
761 }
762 impl ThreatDetector {
763 #[must_use]
764 pub fn new() -> Self {
765 Self {
766 suspicious_patterns: Vec::new(),
767 monitoring_enabled: true,
768 alert_callback: None,
769 }
770 }
771 pub fn scan_data(&self, data: &[u8]) -> SklResult<()> {
772 let data_str = String::from_utf8_lossy(data);
773 for pattern in &self.suspicious_patterns {
774 if data_str.contains(&pattern.pattern) {
775 let alert = ThreatAlert {
776 plugin_name: "unknown".to_string(),
777 threat_type: pattern.pattern_type.clone(),
778 severity: pattern.severity.clone(),
779 description: pattern.description.clone(),
780 timestamp: SystemTime::now(),
781 details: HashMap::new(),
782 };
783 if let Some(callback) = self.alert_callback {
784 callback(&alert);
785 }
786 if pattern.severity >= ThreatSeverity::High {
787 return Err(SklearsError::InvalidInput(format!(
788 "Security threat detected: {}",
789 pattern.description
790 )));
791 }
792 }
793 }
794 Ok(())
795 }
796 }
797 impl Default for PerformanceMonitor {
798 fn default() -> Self {
799 Self::new()
800 }
801 }
802 impl PerformanceMonitor {
803 #[must_use]
804 pub fn new() -> Self {
805 Self {
806 metrics: Arc::new(RwLock::new(HashMap::new())),
807 monitoring_enabled: false,
808 collection_interval: Duration::from_secs(60),
809 }
810 }
811 pub fn start_monitoring(&mut self) -> SklResult<()> {
812 self.monitoring_enabled = true;
813 Ok(())
814 }
815 pub fn stop_monitoring(&mut self) -> SklResult<()> {
816 self.monitoring_enabled = false;
817 Ok(())
818 }
819 #[must_use]
820 pub fn get_metrics(&self, plugin_name: &str) -> Option<PluginMetrics> {
821 self.metrics.read().ok()?.get(plugin_name).cloned()
822 }
823 pub fn record_execution(&self, plugin_name: &str, execution_time: Duration) {
824 if let Ok(mut metrics) = self.metrics.write() {
825 let plugin_metrics =
826 metrics
827 .entry(plugin_name.to_string())
828 .or_insert_with(|| PluginMetrics {
829 plugin_name: plugin_name.to_string(),
830 execution_count: 0,
831 total_execution_time: Duration::from_secs(0),
832 average_execution_time: Duration::from_secs(0),
833 memory_usage: MemoryUsageStats {
834 current_usage: 0,
835 peak_usage: 0,
836 average_usage: 0,
837 allocation_count: 0,
838 },
839 error_rate: 0.0,
840 last_execution: None,
841 });
842 plugin_metrics.execution_count += 1;
843 plugin_metrics.total_execution_time += execution_time;
844 plugin_metrics.average_execution_time =
845 plugin_metrics.total_execution_time / plugin_metrics.execution_count as u32;
846 plugin_metrics.last_execution = Some(SystemTime::now());
847 }
848 }
849 }
850 impl Default for PluginMarketplace {
851 fn default() -> Self {
852 Self::new()
853 }
854 }
855 impl PluginMarketplace {
856 #[must_use]
857 pub fn new() -> Self {
858 Self {
859 repositories: Vec::new(),
860 cache: Arc::new(RwLock::new(HashMap::new())),
861 update_interval: Duration::from_secs(3600),
862 last_update: None,
863 }
864 }
865 pub fn add_repository(&mut self, repository: PluginRepository) {
866 self.repositories.push(repository);
867 }
868 pub fn update_cache(&mut self) -> SklResult<()> {
869 self.last_update = Some(SystemTime::now());
870 Ok(())
871 }
872 pub fn find_plugin(&self, plugin_name: &str) -> SklResult<MarketplaceEntry> {
873 if let Ok(cache) = self.cache.read() {
874 cache.get(plugin_name).cloned().ok_or_else(|| {
875 SklearsError::InvalidInput(format!(
876 "Plugin {plugin_name} not found in marketplace"
877 ))
878 })
879 } else {
880 Err(SklearsError::InvalidOperation(
881 "Failed to read marketplace cache".to_string(),
882 ))
883 }
884 }
885 pub fn download_plugin(
886 &self,
887 _plugin_name: &str,
888 _version: &SemanticVersion,
889 ) -> SklResult<Vec<u8>> {
890 Ok(vec![])
891 }
892 #[must_use]
893 pub fn search(&self, query: &str, tags: &[String]) -> Vec<MarketplaceEntry> {
894 if let Ok(cache) = self.cache.read() {
895 cache
896 .values()
897 .filter(|entry| {
898 entry.plugin_name.contains(query)
899 || entry.description.contains(query)
900 || tags.iter().any(|tag| entry.tags.contains(tag))
901 })
902 .cloned()
903 .collect()
904 } else {
905 Vec::new()
906 }
907 }
908 }
909 impl SemanticVersion {
910 #[must_use]
911 pub fn new(major: u32, minor: u32, patch: u32) -> Self {
912 Self {
913 major,
914 minor,
915 patch,
916 pre_release: None,
917 build_metadata: None,
918 }
919 }
920 pub fn parse(version_str: &str) -> SklResult<Self> {
921 let parts: Vec<&str> = version_str.split('.').collect();
922 if parts.len() < 3 {
923 return Err(SklearsError::InvalidInput(
924 "Invalid version format".to_string(),
925 ));
926 }
927 let major = parts[0]
928 .parse()
929 .map_err(|_| SklearsError::InvalidInput("Invalid major version".to_string()))?;
930 let minor = parts[1]
931 .parse()
932 .map_err(|_| SklearsError::InvalidInput("Invalid minor version".to_string()))?;
933 let patch = parts[2]
934 .parse()
935 .map_err(|_| SklearsError::InvalidInput("Invalid patch version".to_string()))?;
936 Ok(Self::new(major, minor, patch))
937 }
938 }
939}