Co-authored-by: Jean-Gabriel Gill-Couture <jg@nationtech.io> Reviewed-on: https://git.nationtech.io/NationTech/harmony/pulls/61 Reviewed-by: johnride <jg@nationtech.io> Co-authored-by: Willem <wrolleman@nationtech.io> Co-committed-by: Willem <wrolleman@nationtech.io>
		
			
				
	
	
		
			74 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| pub trait MonitoringSystem {}
 | |
| 
 | |
| // 1. Modified AlertReceiver trait:
 | |
| //    - Removed the problematic `clone` method.
 | |
| //    - Added `box_clone` which returns a Box<dyn AlertReceiver>.
 | |
| pub trait AlertReceiver {
 | |
|     type M: MonitoringSystem;
 | |
|     fn install(&self, sender: &Self::M) -> Result<(), String>;
 | |
|     // This method allows concrete types to clone themselves into a Box<dyn AlertReceiver>
 | |
|     fn box_clone(&self) -> Box<dyn AlertReceiver<M = Self::M>>;
 | |
| }
 | |
| #[derive(Clone)]
 | |
| struct Prometheus{}
 | |
| impl MonitoringSystem for Prometheus {}
 | |
| 
 | |
| #[derive(Clone)] // Keep derive(Clone) for DiscordWebhook itself
 | |
| struct DiscordWebhook{}
 | |
| 
 | |
| impl AlertReceiver for DiscordWebhook {
 | |
|     type M = Prometheus;
 | |
|     fn install(&self, sender: &Self::M) -> Result<(), String> {
 | |
|         // Placeholder for actual installation logic
 | |
|         println!("DiscordWebhook installed for Prometheus monitoring.");
 | |
|         Ok(())
 | |
|     }
 | |
|     // 2. Implement `box_clone` for DiscordWebhook:
 | |
|     //    This uses the derived `Clone` for DiscordWebhook to create a new boxed instance.
 | |
|     fn box_clone(&self) -> Box<dyn AlertReceiver<M = Self::M>> {
 | |
|         Box::new(self.clone())
 | |
|     }
 | |
| }
 | |
| 
 | |
| // 3. Implement `std::clone::Clone` for `Box<dyn AlertReceiver<M= M>>`:
 | |
| //    This allows `Box<dyn AlertReceiver>` to be cloned.
 | |
| //    The `+ 'static` lifetime bound is often necessary for trait objects stored in collections,
 | |
| //    ensuring they live long enough.
 | |
| impl<M: MonitoringSystem + 'static> Clone for Box<dyn AlertReceiver<M= M>> {
 | |
|     fn clone(&self) -> Self {
 | |
|         self.box_clone() // Call the custom `box_clone` method
 | |
|     }
 | |
| }
 | |
| 
 | |
| // MonitoringConfig can now derive Clone because its `receivers` field
 | |
| // (Vec<Box<dyn AlertReceiver<M = M>>>) is now cloneable.
 | |
| #[derive(Clone)]
 | |
| struct MonitoringConfig <M: MonitoringSystem + 'static>{
 | |
|     receivers: Vec<Box<dyn AlertReceiver<M = M>>>
 | |
| }
 | |
| 
 | |
| // Example usage to demonstrate compilation and functionality
 | |
| fn main() {
 | |
|     let prometheus_instance = Prometheus{};
 | |
|     let discord_webhook_instance = DiscordWebhook{};
 | |
| 
 | |
|     let mut config = MonitoringConfig {
 | |
|         receivers: Vec::new()
 | |
|     };
 | |
| 
 | |
|     // Create a boxed alert receiver
 | |
|     let boxed_receiver: Box<dyn AlertReceiver<M = Prometheus>> = Box::new(discord_webhook_instance);
 | |
|     config.receivers.push(boxed_receiver);
 | |
| 
 | |
|     // Clone the config, which will now correctly clone the boxed receiver
 | |
|     let cloned_config = config.clone();
 | |
| 
 | |
|     println!("Original config has {} receivers.", config.receivers.len());
 | |
|     println!("Cloned config has {} receivers.", cloned_config.receivers.len());
 | |
| 
 | |
|     // Example of using the installed receiver
 | |
|     if let Some(receiver) = config.receivers.get(0) {
 | |
|         let _ = receiver.install(&prometheus_instance);
 | |
|     }
 | |
| }
 |