//! Run with: cargo run --example printer_polymorphism //! //! Demonstrates the trait+enum pattern that stands in for inheritance: //! - `connect()` is called the same way regardless of vendor (polymorphism), //! but each vendor's `impl Printer` runs completely different code //! (override). //! - `dispatch_gcode_ftp()` only exists on `BambuPrinter` (extension) — you //! have to `match` the enum back down to the concrete type to reach it, //! which is the trade-off for not having implicit downcasting. use continuum_proxy::printer::{BambuPrinter, KlipperPrinter, Printer, PrinterHandle, PrusaPrinter}; #[tokio::main] async fn main() { tracing_subscriber::fmt::init(); let mut fleet: Vec = vec![ PrinterHandle::Bambu(BambuPrinter::new("p1", "X1 Carbon", "192.168.1.50:8883", "12345678")), PrinterHandle::Prusa(PrusaPrinter::new("p2", "MK4", "192.168.1.51", "prusa-api-key")), PrinterHandle::Klipper(KlipperPrinter::new("p3", "Voron 2.4", "192.168.1.52")), ]; // Uniform call site: every printer is connected the same way from the // caller's point of view, even though BambuPrinter::connect, // PrusaPrinter::connect and KlipperPrinter::connect are three unrelated // implementations. for printer in &mut fleet { match printer.connect().await { Ok(()) => println!("connected: {}", printer.display_name()), Err(err) => println!("connect failed: {err}"), } } // Vendor-only extension: reachable only after matching the concrete // variant back out of the enum. for printer in &mut fleet { if let PrinterHandle::Bambu(bambu) = printer { bambu .dispatch_gcode_ftp(std::path::Path::new("./part.gcode.3mf"), "part.gcode.3mf") .await .ok(); } } }