Files
continuum-proxy/examples/printer_polymorphism.rs
T
octoturgeandClaude Sonnet 5 94484bb190 Update docs and prune examples superseded by real functionality
README/certs/README/.env.example/printers.example.toml were all still
describing this as a learning-stage stub with no real printer protocol
clients - rewritten to reflect the real Bambu MQTT client, cert
auto-pinning, and marlin serial connection that now exist.

- Remove examples/fetch_bambu_cert.rs: its manual fetch-and-save workflow
  is now what BambuPrinter::connect()'s ensure_trusted does automatically
  on every connect, so it has no remaining use case.
- Fix examples/printer_polymorphism.rs, which no longer compiled -
  dispatch_gcode was replaced by real methods earlier this session;
  swapped in print_status() as the vendor-only-extension example.
- Remove Config::bambu_ca_cert_overrides/bambu_require_valid_cert and the
  .env vars documenting them - confirmed dead (nothing read them),
  fully superseded by printers.toml's per-printer ca_cert_path/
  require_valid_cert plus automatic trust-on-first-connect pinning.
- Fix stale doc comments in printer/mod.rs and printer/bambu.rs that
  described certificate trust and MQTT as not built yet, or referencing
  the now-removed example.

No behavior change in the daemon itself - verified with cargo build
--examples and a live run of printer_polymorphism and auto_connect_bambu
against the real P1P/H2C printers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 16:17:15 +00:00

79 lines
3.3 KiB
Rust

//! 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 variant's `impl GenericPrinter` runs completely different
//! code (override).
//! - `dispatch_gcode()` only exists on the Bambu struct (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, BambuProtocolPreference, BambuTls, GenericPrinter, KlipperPrinter, PrinterHandle,
PrusaLinkPrinter, PrusaSerialPrinter,
};
#[tokio::main]
async fn main() {
let mut fleet: Vec<PrinterHandle> = vec![
// Forced: a known-old printer.
PrinterHandle::Bambu(BambuPrinter::new(
"p1",
"P1S",
"192.168.1.49",
"87654321",
"01P00A000000000",
BambuTls::BundledCa,
BambuProtocolPreference::ForceV1,
)),
// Auto: the recommended default - see bambu.rs's doc comment.
PrinterHandle::Bambu(BambuPrinter::new(
"p2",
"X1 Carbon",
"192.168.1.50",
"12345678",
"00M00A000000000",
BambuTls::BundledCa,
BambuProtocolPreference::Auto,
)),
PrinterHandle::PrusaLink(PrusaLinkPrinter::new("p3", "MK4", "192.168.1.51", "prusa-api-key")),
PrinterHandle::PrusaSerial(PrusaSerialPrinter::new("p4", "MK3S+", "/dev/ttyACM0", 115_200)),
PrinterHandle::Klipper(KlipperPrinter::new("p5", "Voron 2.4", "192.168.1.52")),
// No host configured - this one will hit the Err path.
PrinterHandle::Klipper(KlipperPrinter::new("p6", "Broken Voron", "")),
];
// Uniform call site: every printer connects the same way from the
// caller's point of view, even though each variant's `connect()` body
// is an unrelated implementation.
for printer in &mut fleet {
match printer.connect().await {
Ok(()) => println!(" -> connected: {}\n", printer.display_name()),
Err(err) => println!(" -> failed: {err}\n"),
}
}
// Vendor-only extension: reachable only after matching the concrete
// variant back out of the enum - one arm now that Bambu is a single
// type regardless of which protocol version `connect()` settled on.
// `print_status()` is real Bambu-only behavior with no equivalent on
// `GenericPrinter` (no other vendor here has an in-memory report
// cache) - none of these connected above (fake IPs), so it's always
// `None`, but the point is the downcast, not a live reading.
for printer in &fleet {
match printer {
PrinterHandle::Bambu(bambu) => println!(" {}: cached print_status = {:?}", bambu.sn, bambu.print_status().await),
_ => {}
}
}
// A second trait method, same uniform call site as connect(): every
// vendor sends "50%" a completely different way - an MQTT gcode
// command, Moonraker's native API, gcode over HTTP, gcode over serial
// - but the caller doesn't need to know or care which.
println!();
for printer in &mut fleet {
let _ = printer.set_fan_speed(50).await;
}
}