chore: Move ADR helper files into folders with their corresponding ADR number
This commit is contained in:
183
adr/003-abstractions/topology2/src/main.rs
Normal file
183
adr/003-abstractions/topology2/src/main.rs
Normal file
@@ -0,0 +1,183 @@
|
||||
// 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<C: ?Sized> {
|
||||
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<dyn K8sCapability> for LAMPScore {
|
||||
fn execute(&self, capability: &dyn K8sCapability) -> String {
|
||||
todo!()
|
||||
// Implementation...
|
||||
}
|
||||
}
|
||||
|
||||
struct BinaryScore {}
|
||||
impl Score<dyn LinuxCapability> for BinaryScore {
|
||||
fn execute(&self, capability: &dyn LinuxCapability) -> String {
|
||||
todo!()
|
||||
// Implementation...
|
||||
}
|
||||
}
|
||||
|
||||
struct LoadBalancerScore {}
|
||||
impl Score<dyn LoadBalancerCapability> for LoadBalancerScore {
|
||||
fn execute(&self, capability: &dyn LoadBalancerCapability) -> String {
|
||||
todo!()
|
||||
// Implementation...
|
||||
}
|
||||
}
|
||||
|
||||
// Generic Maestro
|
||||
struct Maestro<T> {
|
||||
topology: T,
|
||||
scores: Vec<Box<dyn FnMut(&T) -> String>>,
|
||||
}
|
||||
|
||||
impl<T: 'static> Maestro<T> {
|
||||
fn new(topology: T) -> Self {
|
||||
Self {
|
||||
topology,
|
||||
scores: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn interpret_all(&mut self) -> Vec<String> {
|
||||
self.scores.iter_mut()
|
||||
.map(|score| score(&self.topology))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
// Capability-specific extensions
|
||||
impl<T: K8sCapability + 'static> Maestro<T> {
|
||||
fn register_k8s_score<S: Score<dyn K8sCapability> + '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<T: LinuxCapability + 'static> Maestro<T> {
|
||||
fn register_linux_score<S: Score<dyn LinuxCapability> + '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<T: LoadBalancerCapability + 'static> Maestro<T> {
|
||||
fn register_lb_score<S: Score<dyn LoadBalancerCapability> + '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 {});
|
||||
}
|
||||
Reference in New Issue
Block a user