// Clean capability-based design using type parameters trait Capability {} trait K8sCapability: Capability { fn deploy_k8s_resource(&self, resource_yaml: &str); fn execute_kubectl(&self, command: &str) -> String; } trait LinuxCapability: Capability { fn execute_command(&self, command: &str, args: &[&str]); fn download_file(&self, url: &str, destination: &str) -> Result<(), String>; } trait LoadBalancerCapability: Capability { fn configure_load_balancer(&self, services: &[&str], port: u16); fn get_load_balancer_status(&self) -> String; } // Score trait with capability type parameter trait Score { fn execute(&self, capability: &C) -> String; } // Topology implementations with marker trait trait Topology {} struct K3DTopology {} impl Topology for K3DTopology {} impl Capability for K3DTopology {} impl K8sCapability for K3DTopology { fn deploy_k8s_resource(&self, resource_yaml: &str) { todo!() } fn execute_kubectl(&self, command: &str) -> String { todo!() } // Implementation... } struct LinuxTopology {} impl Topology for LinuxTopology {} impl Capability for LinuxTopology {} impl LinuxCapability for LinuxTopology { fn execute_command(&self, command: &str, args: &[&str]) { todo!() } fn download_file(&self, url: &str, destination: &str) -> Result<(), String> { todo!() } // Implementation... } struct OKDHaClusterTopology {} impl Topology for OKDHaClusterTopology {} impl Capability for OKDHaClusterTopology {} impl K8sCapability for OKDHaClusterTopology { fn deploy_k8s_resource(&self, resource_yaml: &str) { todo!() } fn execute_kubectl(&self, command: &str) -> String { todo!() } // Implementation... } impl LinuxCapability for OKDHaClusterTopology { fn execute_command(&self, command: &str, args: &[&str]) { todo!() } fn download_file(&self, url: &str, destination: &str) -> Result<(), String> { todo!() } // Implementation... } impl LoadBalancerCapability for OKDHaClusterTopology { fn configure_load_balancer(&self, services: &[&str], port: u16) { todo!() } fn get_load_balancer_status(&self) -> String { todo!() } // Implementation... } // Score implementations struct LAMPScore {} impl Score for LAMPScore { fn execute(&self, capability: &dyn K8sCapability) -> String { todo!() // Implementation... } } struct BinaryScore {} impl Score for BinaryScore { fn execute(&self, capability: &dyn LinuxCapability) -> String { todo!() // Implementation... } } struct LoadBalancerScore {} impl Score for LoadBalancerScore { fn execute(&self, capability: &dyn LoadBalancerCapability) -> String { todo!() // Implementation... } } // Generic Maestro struct Maestro { topology: T, scores: Vec String>>, } impl Maestro { fn new(topology: T) -> Self { Self { topology, scores: Vec::new(), } } fn interpret_all(&mut self) -> Vec { self.scores.iter_mut() .map(|score| score(&self.topology)) .collect() } } // Capability-specific extensions impl Maestro { fn register_k8s_score + 'static>(&mut self, score: S) { let score_box = Box::new(move |topology: &T| { score.execute(topology as &dyn K8sCapability) }); self.scores.push(score_box); } } impl Maestro { fn register_linux_score + 'static>(&mut self, score: S) { let score_box = Box::new(move |topology: &T| { score.execute(topology as &dyn LinuxCapability) }); self.scores.push(score_box); } } impl Maestro { fn register_lb_score + 'static>(&mut self, score: S) { let score_box = Box::new(move |topology: &T| { score.execute(topology as &dyn LoadBalancerCapability) }); self.scores.push(score_box); } } fn main() { // Example usage let k3d = K3DTopology {}; let mut k3d_maestro = Maestro::new(k3d); // These will compile because K3D implements K8sCapability k3d_maestro.register_k8s_score(LAMPScore {}); // This would not compile because K3D doesn't implement LoadBalancerCapability // k3d_maestro.register_lb_score(LoadBalancerScore {}); let linux = LinuxTopology {}; let mut linux_maestro = Maestro::new(linux); // This will compile because Linux implements LinuxCapability linux_maestro.register_linux_score(BinaryScore {}); // This would not compile because Linux doesn't implement K8sCapability // linux_maestro.register_k8s_score(LAMPScore {}); }