sklears_core/plugin/
mod.rs

1//! Plugin System Module
2//!
3//! This module provides a comprehensive plugin architecture for the SKLears framework,
4//! enabling dynamic loading, validation, and management of machine learning algorithms
5//! and data processing components.
6//!
7//! # Plugin System Architecture
8//!
9//! The plugin system is organized into several key components:
10//!
11//! ## Core Components
12//!
13//! - **[Core Traits](core_traits)**: Foundation traits that all plugins must implement
14//! - **[Types & Configuration](types_config)**: Type-safe parameter handling and plugin metadata
15//! - **[Registry](registry)**: Thread-safe plugin registration and discovery
16//! - **[Loader](loader)**: Dynamic library loading with cross-platform support
17//!
18//! ## Advanced Features
19//!
20//! - **[Factory & Builder](factory_builder)**: Factory patterns for plugin creation
21//! - **[Validation](validation)**: Comprehensive security and quality validation
22//! - **[Security](security)**: Permission management and digital signatures
23//! - **[Discovery & Marketplace](discovery_marketplace)**: Remote plugin discovery and community features
24//! - **[Testing Utilities](testing_utils)**: Complete testing framework for plugin development
25//!
26//! # Quick Start
27//!
28//! ## Creating a Simple Plugin
29//!
30//! ```rust,ignore
31//! use sklears_core::plugin::{Plugin, PluginMetadata, PluginConfig, PluginCategory};
32//! use sklears_core::error::Result;
33//! use std::any::{Any, TypeId};
34//!
35//! #[derive(Debug)]
36//! struct MyAlgorithm {
37//!     name: String,
38//! }
39//!
40//! impl Plugin for MyAlgorithm {
41//!     fn id(&self) -> &str {
42//!         &self.name
43//!     }
44//!
45//!     fn metadata(&self) -> PluginMetadata {
46//!         PluginMetadata {
47//!             name: "My Algorithm".to_string(),
48//!             version: "1.0.0".to_string(),
49//!             description: "An example machine learning algorithm".to_string(),
50//!             author: "Your Name".to_string(),
51//!             category: PluginCategory::Algorithm,
52//!             supported_types: vec![TypeId::of::<f64>()],
53//!             ..Default::default()
54//!         }
55//!     }
56//!
57//!     fn initialize(&mut self, _config: &PluginConfig) -> Result<()> {
58//!         println!("Initializing {}", self.name);
59//!         Ok(())
60//!     }
61//!
62//!     fn is_compatible(&self, input_type: TypeId) -> bool {
63//!         input_type == TypeId::of::<f64>()
64//!     }
65//!
66//!     fn as_any(&self) -> &dyn Any { self }
67//!     fn as_any_mut(&mut self) -> &mut dyn Any { self }
68//!     fn validate_config(&self, _config: &PluginConfig) -> Result<()> { Ok(()) }
69//!     fn cleanup(&mut self) -> Result<()> { Ok(()) }
70//! }
71//! ```
72//!
73//! ## Using the Plugin Registry
74//!
75//! ```rust,ignore
76//! use sklears_core::plugin::{PluginRegistry, Plugin};
77//!
78//! # use sklears_core::plugin::{PluginMetadata, PluginConfig, PluginCategory};
79//! # use sklears_core::error::Result;
80//! # use std::any::{Any, TypeId};
81//! # #[derive(Debug)]
82//! # struct MyAlgorithm { name: String }
83//! # impl Plugin for MyAlgorithm {
84//! #     fn id(&self) -> &str { &self.name }
85//! #     fn metadata(&self) -> PluginMetadata {
86//! #         PluginMetadata {
87//! #             name: "My Algorithm".to_string(),
88//! #             version: "1.0.0".to_string(),
89//! #             description: "An example algorithm".to_string(),
90//! #             author: "Your Name".to_string(),
91//! #             category: PluginCategory::Algorithm,
92//! #             supported_types: vec![TypeId::of::<f64>()],
93//! #             ..Default::default()
94//! #         }
95//! #     }
96//! #     fn initialize(&mut self, _config: &PluginConfig) -> Result<()> { Ok(()) }
97//! #     fn is_compatible(&self, input_type: TypeId) -> bool { input_type == TypeId::of::<f64>() }
98//! #     fn as_any(&self) -> &dyn Any { self }
99//! #     fn as_any_mut(&mut self) -> &mut dyn Any { self }
100//! #     fn validate_config(&self, _config: &PluginConfig) -> Result<()> { Ok(()) }
101//! #     fn cleanup(&mut self) -> Result<()> { Ok(()) }
102//! # }
103//! fn example() -> Result<(), Box<dyn std::error::Error>> {
104//!     let registry = PluginRegistry::new();
105//!
106//!     // Register a plugin
107//!     let plugin = MyAlgorithm { name: "my_algo".to_string() };
108//!     registry.register("my_algo", Box::new(plugin))?;
109//!
110//!     // List available plugins
111//!     let plugins = registry.list_plugins()?;
112//!     println!("Available plugins: {:?}", plugins);
113//!
114//!     // Search for plugins
115//!     let matches = registry.search_plugins("algorithm")?;
116//!     println!("Found {} matching plugins", matches.len());
117//!
118//!     Ok(())
119//! }
120//! ```
121//!
122//! ## Building Plugin Configurations
123//!
124//! ```rust,ignore
125//! use sklears_core::plugin::{PluginConfigBuilder, PluginParameter, LogLevel};
126//!
127//! let config = PluginConfigBuilder::new()
128//!     .with_parameter("learning_rate", PluginParameter::Float(0.01))
129//!     .with_parameter("max_iterations", PluginParameter::Int(1000))
130//!     .with_parameter("use_bias", PluginParameter::Bool(true))
131//!     .with_threads(4)
132//!     .with_memory_limit(1024 * 1024 * 1024) // 1GB
133//!     .with_gpu(true)
134//!     .with_log_level(LogLevel::Info)
135//!     .build();
136//! ```
137//!
138//! ## Dynamic Library Loading
139//!
140//! ```rust,ignore
141//! use sklears_core::plugin::{PluginLoader, PluginRegistry};
142//! use std::sync::Arc;
143//!
144//! # #[cfg(feature = "dynamic_loading")]
145//! fn example() -> Result<(), Box<dyn std::error::Error>> {
146//!     let registry = Arc::new(PluginRegistry::new());
147//!     let mut loader = PluginLoader::new(registry.clone());
148//!
149//!     // Load a single plugin
150//!     loader.load_from_library("./plugins/my_plugin.so", "my_plugin")?;
151//!
152//!     // Load all plugins from a directory
153//!     let loaded = loader.load_from_directory("./plugins/")?;
154//!     println!("Loaded {} plugins", loaded.len());
155//!
156//!     Ok(())
157//! }
158//! ```
159//!
160//! ## Plugin Validation and Security
161//!
162//! ```rust,ignore
163//! use sklears_core::plugin::{PluginValidator, SecurityPolicy, Permission};
164//!
165//! // Create a validator with custom security policy
166//! let mut validator = PluginValidator::new();
167//! let mut policy = SecurityPolicy::standard();
168//! policy.add_dangerous_permission("network_access".to_string());
169//!
170//! // Validate plugins before loading
171//! # /*
172//! let validation_report = validator.validate_comprehensive(&plugin, &manifest)?;
173//! if validation_report.has_errors() {
174//!     println!("Plugin validation failed: {:?}", validation_report.errors);
175//! }
176//! # */
177//! ```
178//!
179//! ## Plugin Discovery and Marketplace
180//!
181//! ```rust,ignore
182//! use sklears_core::plugin::{PluginDiscoveryService, PluginMarketplace, SearchQuery, PluginCategory};
183//!
184//! async fn example() -> Result<(), Box<dyn std::error::Error>> {
185//!     let marketplace = PluginMarketplace::new();
186//!
187//!     // Get featured plugins
188//!     let featured = marketplace.get_featured_plugins().await?;
189//!     println!("Featured plugins: {}", featured.len());
190//!
191//!     // Search for plugins
192//!     let discovery = PluginDiscoveryService::new();
193//!     let query = SearchQuery {
194//!         text: "classification".to_string(),
195//!         category: Some(PluginCategory::Algorithm),
196//!         capabilities: vec![],
197//!         limit: Some(10),
198//!         min_rating: Some(4.0),
199//!     };
200//!     let results = discovery.search(&query).await?;
201//!
202//!     // Install a plugin
203//!     if let Some(result) = results.first() {
204//!         let install_result = discovery.install_plugin(&result.plugin_id, None).await?;
205//!         println!("Installed plugin at: {}", install_result.install_path);
206//!     }
207//!
208//!     Ok(())
209//! }
210//! ```
211//!
212//! # Testing Plugins
213//!
214//! The plugin system includes comprehensive testing utilities:
215//!
216//! ```rust,ignore
217//! use sklears_core::plugin::{MockPlugin, ValidationTestRunner, PluginTestFixture};
218//!
219//! // Create mock plugins for testing
220//! let mut mock = MockPlugin::new("test_plugin");
221//! mock.set_initialization_error(Some("Test error"));
222//!
223//! // Run comprehensive validation tests
224//! let runner = ValidationTestRunner::new();
225//! let fixture = PluginTestFixture::new();
226//! let manifest = &fixture.create_test_manifests()[0];
227//!
228//! # /*
229//! let report = runner.run_validation_tests(&mock, manifest);
230//! println!("Validation passed: {}", !report.has_errors());
231//! # */
232//! ```
233
234// Core plugin functionality
235pub mod core_traits;
236pub mod loader;
237pub mod registry;
238pub mod types_config;
239
240// Advanced plugin features
241pub mod discovery_marketplace;
242pub mod factory_builder;
243pub mod security;
244pub mod validation;
245
246// Testing and development utilities
247pub mod testing_utils;
248
249// Re-export core traits and types for convenient access
250pub use core_traits::{AlgorithmPlugin, ClusteringPlugin, Plugin, TransformerPlugin};
251
252pub use types_config::{
253    LogLevel, PluginCapability, PluginCategory, PluginConfig, PluginMetadata, PluginParameter,
254    RuntimeSettings,
255};
256
257pub use registry::PluginRegistry;
258
259pub use loader::PluginLoader;
260
261// Factory and builder patterns
262pub use factory_builder::{PluginConfigBuilder, PluginFactory};
263
264// Validation framework
265pub use validation::{
266    ApiUsageInfo, CodeAnalysisInfo, Dependency, PluginManifest, PluginValidator, ValidationCheck,
267    ValidationError, ValidationReport, ValidationResult, ValidationWarning, Vulnerability,
268};
269
270// Security framework
271pub use security::{
272    CertificateInfo, DigitalSignature, Permission, PermissionSet, PublicKeyInfo, PublisherInfo,
273    SecurityPolicy, TrustStore,
274};
275
276// Discovery and marketplace
277pub use discovery_marketplace::{
278    FeaturedPlugin, MarketplaceInfo, MarketplaceSummary, PluginDiscoveryService,
279    PluginInstallResult, PluginMarketplace, PluginRepository, PluginReview, PluginSearchResult,
280    PluginStats, PricingInfo, RepositoryStats, SearchQuery, SubscriptionPeriod, SupportLevel,
281    TrendDirection, TrendingPlugin, UsageUnit,
282};
283
284// Testing utilities
285pub use testing_utils::{
286    CompatibilityTestResult, CompleteTestResult, MockPlugin, PerformanceResult,
287    PluginPerformanceTester, PluginTestFixture, ValidationTestRunner,
288};
289
290// Convenience re-exports for common patterns
291/// Common plugin development imports
292pub mod prelude {
293    pub use super::{
294        AlgorithmPlugin, ClusteringPlugin, LogLevel, Plugin, PluginCapability, PluginCategory,
295        PluginConfig, PluginConfigBuilder, PluginFactory, PluginMetadata, PluginParameter,
296        PluginRegistry, TransformerPlugin,
297    };
298}
299
300/// Security-focused imports for plugin validation
301pub mod security_prelude {
302    pub use super::{
303        DigitalSignature, Permission, PermissionSet, PluginValidator, SecurityPolicy, TrustStore,
304        ValidationReport,
305    };
306}
307
308/// Marketplace and discovery imports
309pub mod marketplace_prelude {
310    pub use super::{
311        FeaturedPlugin, PluginDiscoveryService, PluginMarketplace, PluginRepository, PluginStats,
312        SearchQuery,
313    };
314}
315
316/// Testing utilities imports
317pub mod testing_prelude {
318    pub use super::{
319        CompleteTestResult, MockPlugin, PluginPerformanceTester, PluginTestFixture,
320        ValidationTestRunner,
321    };
322}
323
324// Convenience type aliases for common use cases
325/// Type alias for a boxed plugin instance
326pub type BoxedPlugin = Box<dyn Plugin>;
327
328/// Type alias for plugin validation result
329pub type PluginValidationResult = Result<ValidationReport, crate::error::SklearsError>;
330
331/// Type alias for plugin creation function (for dynamic loading)
332pub type PluginCreateFn = fn() -> BoxedPlugin;
333
334// Module-level documentation and examples
335
336/// # Plugin Development Guide
337///
338/// ## Creating Custom Plugins
339///
340/// To create a custom plugin, implement the `Plugin` trait and any relevant
341/// specialized traits like `AlgorithmPlugin` or `TransformerPlugin`:
342///
343/// ```rust,ignore
344/// use sklears_core::plugin::prelude::*;
345/// use sklears_core::error::Result;
346/// use std::any::{Any, TypeId};
347/// use std::collections::HashMap;
348///
349/// #[derive(Debug)]
350/// struct LinearRegression {
351///     coefficients: Vec`<f64>`,
352///     intercept: f64,
353/// }
354///
355/// impl Plugin for LinearRegression {
356///     fn id(&self) -> &str { "linear_regression" }
357///
358///     fn metadata(&self) -> PluginMetadata {
359///         PluginMetadata {
360///             name: "Linear Regression".to_string(),
361///             version: "1.0.0".to_string(),
362///             description: "Simple linear regression algorithm".to_string(),
363///             author: "SKLears Team".to_string(),
364///             category: PluginCategory::Algorithm,
365///             supported_types: vec![TypeId::of::`<f64>`()],
366///             capabilities: vec![PluginCapability::Parallel],
367///             ..Default::default()
368///         }
369///     }
370///
371///     fn initialize(&mut self, config: &PluginConfig) -> Result<()> {
372///         // Initialize algorithm with configuration
373///         if let Some(param) = config.parameters.get("regularization") {
374///             let reg_strength = param.as_float()?;
375///             println!("Using regularization strength: {}", reg_strength);
376///         }
377///         Ok(())
378///     }
379///
380///     fn is_compatible(&self, input_type: TypeId) -> bool {
381///         input_type == TypeId::of::`<f64>`()
382///     }
383///
384///     fn as_any(&self) -> &dyn Any { self }
385///     fn as_any_mut(&mut self) -> &mut dyn Any { self }
386///     fn validate_config(&self, _config: &PluginConfig) -> Result<()> { Ok(()) }
387///     fn cleanup(&mut self) -> Result<()> { Ok(()) }
388/// }
389/// ```
390///
391/// ## Security Best Practices
392///
393/// When developing plugins, follow these security guidelines:
394///
395/// 1. **Minimize Permissions**: Only request permissions your plugin actually needs
396/// 2. **Validate Inputs**: Always validate configuration parameters and input data
397/// 3. **Handle Errors Gracefully**: Don't expose sensitive information in error messages
398/// 4. **Use Safe APIs**: Avoid unsafe code blocks unless absolutely necessary
399/// 5. **Sign Your Plugins**: Use digital signatures for distribution
400///
401/// ## Performance Considerations
402///
403/// - Implement efficient algorithms with O(n log n) or better complexity where possible
404/// - Use SIMD operations for numerical computations when available
405/// - Minimize memory allocations in hot paths
406/// - Support parallel processing through the `Parallel` capability
407/// - Use lazy initialization for expensive resources
408///
409/// ## Testing Your Plugins
410///
411/// Use the comprehensive testing framework:
412///
413/// ```rust,ignore
414/// use sklears_core::plugin::testing_prelude::*;
415///
416/// #[test]
417/// fn test_my_plugin() {
418///     let mut mock = MockPlugin::new("test_plugin");
419///     let runner = ValidationTestRunner::new();
420///     let fixture = PluginTestFixture::new();
421///
422///     // Run comprehensive tests
423///     let manifest = &fixture.create_test_manifests()[0];
424///     let mut test_results = runner.run_complete_test_suite(&mut mock, manifest);
425///
426///     assert!(test_results.test_passed);
427///     assert!(test_results.overall_score >= 80);
428/// }
429/// ```
430#[allow(non_snake_case)]
431#[cfg(test)]
432mod integration_tests {
433    use super::*;
434    use std::any::TypeId;
435
436    #[test]
437    fn test_plugin_system_integration() {
438        // Test basic plugin creation and registration
439        let registry = PluginRegistry::new();
440        let mock = testing_utils::MockPlugin::new("integration_test");
441
442        assert!(registry
443            .register("integration_test", Box::new(mock))
444            .is_ok());
445
446        let plugins = registry.list_plugins().unwrap();
447        assert!(plugins.contains(&"integration_test".to_string()));
448    }
449
450    #[test]
451    fn test_plugin_configuration_builder() {
452        let config = PluginConfigBuilder::new()
453            .with_parameter("test_param", PluginParameter::Float(1.0))
454            .with_threads(2)
455            .with_gpu(false)
456            .build();
457
458        assert_eq!(config.parameters.len(), 1);
459        assert_eq!(config.runtime_settings.num_threads, Some(2));
460        assert!(!config.runtime_settings.use_gpu);
461    }
462
463    #[test]
464    fn test_security_policy_levels() {
465        let strict = SecurityPolicy::strict();
466        let standard = SecurityPolicy::standard();
467        let permissive = SecurityPolicy::permissive();
468
469        assert!(strict.require_signatures);
470        assert!(standard.require_signatures);
471        assert!(!permissive.require_signatures);
472
473        assert!(!strict.allow_unsafe_code);
474        assert!(!standard.allow_unsafe_code);
475        assert!(permissive.allow_unsafe_code);
476    }
477
478    #[test]
479    fn test_plugin_validation_framework() {
480        let validator = PluginValidator::new();
481        let fixture = PluginTestFixture::new();
482        let mock = testing_utils::MockPlugin::new("validation_test");
483        let manifest = &fixture.create_test_manifests()[3]; // Signed manifest for validation
484
485        let report = validator.validate_comprehensive(&mock, manifest).unwrap();
486        assert!(!report.has_errors());
487    }
488
489    #[test]
490    fn test_permission_system() {
491        let fs_read = Permission::FileSystemRead;
492        let fs_write = Permission::FileSystemWrite;
493        let sys_cmd = Permission::SystemCommands;
494
495        assert_eq!(fs_read.risk_level(), 2);
496        assert_eq!(fs_write.risk_level(), 3);
497        assert_eq!(sys_cmd.risk_level(), 5);
498
499        assert!(!fs_read.requires_user_consent());
500        assert!(fs_write.requires_user_consent());
501        assert!(sys_cmd.requires_user_consent());
502    }
503
504    #[test]
505    fn test_plugin_categories() {
506        let categories = vec![
507            PluginCategory::Algorithm,
508            PluginCategory::Transformer,
509            PluginCategory::DataProcessor,
510            PluginCategory::Evaluator,
511            PluginCategory::Visualizer,
512        ];
513
514        for category in categories {
515            let mock = testing_utils::MockPlugin::for_category("test", category.clone());
516            assert_eq!(mock.metadata().category, category);
517        }
518    }
519
520    #[test]
521    fn test_type_compatibility() {
522        let mut mock = testing_utils::MockPlugin::new("type_test");
523
524        // Should support f64 by default
525        assert!(mock.is_compatible(TypeId::of::<f64>()));
526
527        // Add i32 support
528        mock.add_supported_type(TypeId::of::<i32>());
529        assert!(mock.is_compatible(TypeId::of::<i32>()));
530
531        // String should not be supported
532        assert!(!mock.is_compatible(TypeId::of::<String>()));
533    }
534
535    #[test]
536    fn test_performance_testing() {
537        let mut tester = PluginPerformanceTester::new();
538        let mut mock = testing_utils::MockPlugin::new("perf_test");
539
540        let result = tester.benchmark_initialization(&mut mock);
541        assert!(result.success);
542        assert_eq!(result.operation, "initialization");
543    }
544
545    #[test]
546    fn test_marketplace_components() {
547        let marketplace = PluginMarketplace::new();
548
549        // Test feature score calculation
550        let score = marketplace.calculate_feature_score(4.5, 1000, 50);
551        assert!(score > 0.0);
552        assert!(score <= 10.0);
553    }
554
555    #[test]
556    fn test_trust_store() {
557        let mut trust_store = TrustStore::new();
558
559        let key_info = PublicKeyInfo {
560            algorithm: "RSA".to_string(),
561            key_size: 2048,
562            added_timestamp: std::time::SystemTime::now(),
563            expires_at: None,
564            owner: "test@example.com".to_string(),
565        };
566
567        trust_store.add_trusted_key("test_key".to_string(), key_info);
568        assert!(!trust_store.is_key_revoked("test_key"));
569
570        trust_store.revoke_key("test_key".to_string());
571        assert!(trust_store.is_key_revoked("test_key"));
572    }
573}
574
575// Module feature gates for optional functionality
576// PluginLoader already exported above unconditionally
577
578// External dependencies documentation
579//
580// # External Dependencies
581//
582// This module uses several external crates for enhanced functionality:
583//
584// - `libloading` - For dynamic library loading (when `dynamic_loading` feature is enabled)
585// - `serde` - For serialization of plugin manifests and configurations
586// - `tokio` - For async functionality in discovery and marketplace features
587//
588// # Feature Flags
589//
590// - `dynamic_loading` - Enables dynamic library loading capabilities
591// - `async` - Enables async functionality for marketplace and discovery
592// - `serde` - Enables serialization support for plugin configurations
593//
594// # Platform Support
595//
596// The plugin system supports the following platforms:
597//
598// - **Linux**: Full support including dynamic loading (.so files)
599// - **macOS**: Full support including dynamic loading (.dylib files)
600// - **Windows**: Full support including dynamic loading (.dll files)
601//
602// # Safety Considerations
603//
604// Dynamic loading involves unsafe operations. The plugin system takes several
605// precautions to ensure safety:
606//
607// - Comprehensive validation before loading
608// - Digital signature verification
609// - Permission-based security model
610// - Sandboxed execution environment
611// - Memory safety checks
612//
613// However, users should only load plugins from trusted sources and always
614// validate plugin manifests before installation.