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);
 | 
						|
    }
 | 
						|
}
 |