marlin_binary_transfer/lib.rs
1//! Host-side implementation of Marlin's Binary File Transfer Mark II protocol.
2//!
3//! Uploads G-code files to a 3D printer's SD card over serial, with framing
4//! checksums, sync acknowledgement, retransmit on timeout, and optional
5//! heatshrink payload compression.
6//!
7//! # Crate layout
8//!
9//! The core ([`codec`], [`session`], [`file_transfer`]) is **sans-I/O**:
10//! callers feed bytes in and pull events out, plumbing them through any
11//! transport. Optional adapter modules wrap the core for the common cases:
12//!
13//! - [`adapters::blocking`] — synchronous loop over a [`std::io::Read`] +
14//! [`std::io::Write`] transport. Behind the `blocking` feature.
15//! - [`adapters::tokio`] — async loop over a [`tokio::io::AsyncRead`] +
16//! [`tokio::io::AsyncWrite`] + [`Unpin`] transport. Behind the `tokio`
17//! feature.
18//! - [`adapters::serialport`] — convenience helpers for opening a
19//! [`serialport::SerialPort`], which already implements `Read + Write`
20//! and so plugs into the blocking adapter directly. Behind the `serial`
21//! feature (implies `blocking`).
22//!
23//! Heatshrink payload compression is gated behind the `heatshrink` feature
24//! and exposed via [`compression`].
25//!
26//! [`tokio::io::AsyncRead`]: https://docs.rs/tokio/latest/tokio/io/trait.AsyncRead.html
27//! [`tokio::io::AsyncWrite`]: https://docs.rs/tokio/latest/tokio/io/trait.AsyncWrite.html
28//! [`serialport::SerialPort`]: https://docs.rs/serialport/latest/serialport/trait.SerialPort.html
29//!
30//! # Quickstart
31//!
32//! ```no_run
33//! # #[cfg(all(feature = "blocking", feature = "serial"))]
34//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
35//! use marlin_binary_transfer::adapters::blocking::{upload, UploadOptions};
36//! use marlin_binary_transfer::adapters::serialport;
37//! use marlin_binary_transfer::file_transfer::Compression;
38//!
39//! let mut port = serialport::open("/dev/ttyUSB0", 250_000)?;
40//! let file = std::fs::File::open("model.gco")?;
41//!
42//! let stats = upload(&mut *port, file, UploadOptions {
43//! dest_filename: "model.gco".into(),
44//! compression: Compression::Auto,
45//! ..UploadOptions::default()
46//! })?;
47//! println!("uploaded {} bytes in {} chunks", stats.bytes_sent, stats.chunks_sent);
48//! # Ok(()) }
49//! # #[cfg(not(all(feature = "blocking", feature = "serial")))]
50//! # fn main() {}
51//! ```
52//!
53//! See the [README] for the tokio quickstart, sans-I/O usage, and a complete
54//! description of what the upload helpers handle on your behalf (binary-mode
55//! enter/exit, retransmit, error classification).
56//!
57//! [README]: https://github.com/J040M/marlin-binary-transfer#readme
58//!
59//! # Protocol reference
60//!
61//! <https://github.com/MarlinFirmware/Marlin/pull/14817>
62//!
63//! # Status
64//!
65//! Pre-1.0. The Marlin protocol is documented as experimental upstream and
66//! may evolve. Public API follows semver within 0.x — pin a minor version.
67
68#![cfg_attr(docsrs, feature(doc_cfg))]
69#![warn(missing_docs)]
70#![warn(rust_2018_idioms)]
71
72pub mod codec;
73pub mod compression;
74pub mod file_transfer;
75pub mod session;
76
77#[cfg(any(feature = "blocking", feature = "tokio", feature = "serial"))]
78pub mod adapters;