Skip to content

Rust SDK

The Rust SDK provides type safety, low runtime overhead, and cross-platform command construction. The implementation is in the rust/ workspace of prtmax/psdk, and the SDK crates are published on crates.io.

The Rust SDK uses Cargo to manage dependencies. Add the crates you need:

[dependencies]
psdk-father = "0.0.1"
psdk-fruit-cpcl = "0.0.1"
psdk-fruit-tspl = "0.0.1"
psdk-fruit-esc = "0.0.1"

For example, a CPCL-only application usually needs the core write workflow and the CPCL command crate:

[dependencies]
psdk-father = "0.0.1"
psdk-fruit-cpcl = "0.0.1"
CrateDescription
psdk-fatherCore commands, devices, and write workflow
psdk-toolkitUtility functions
psdk-extensionImage conversion and extensions
psdk-frame-otaOTA packets and upgrade workflow
psdk-fruit-cpclCPCL commands
psdk-fruit-tsplTSPL commands
psdk-fruit-escESC commands
psdk-fruit-rgbRGB series commands
psdk-fruit-wifiWi-Fi / Bluetooth configuration commands
psdk-fruit-emapiEMAPI protocol commands

psdk-extension-export-c, psdk-extension-export-jni, and psdk-compatible-hjinfo are C/JNI/compatibility-layer build packages, not regular SDK packages published on crates.io.

This example uses the built-in FakeConnectedDevice to demonstrate command construction and writing. In a real project, implement ConnectedDevice and connect write / read to a Bluetooth, USB, serial, or network transport.

use std::sync::{Arc, Mutex};
use psdk_father::{device::FakeConnectedDevice, psdk::Psdk};
use psdk_fruit_cpcl::{args::CPrint, BaseCpcl};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let device = Arc::new(Mutex::new(FakeConnectedDevice::new()));
let mut cpcl = BaseCpcl::with_connected_device(device);
let reporter = cpcl
.page((400, 576))?
.text((50, 50, "商品标签"))?
.bar((50, 150, "1234567890", 2, 50))?
.print(CPrint::default())?
.write()?;
println!("write ok: {}, bytes: {}", reporter.ok, reporter.binary.len());
Ok(())
}

Custom devices must implement ConnectedDevice:

use psdk_father::{
device::{ConnectedDevice, ConnectionState, DeviceWriteOptions, ReadOptions},
errors::PsdkFatherResult,
};
struct MyDevice;
impl ConnectedDevice for MyDevice {
fn device_name(&self) -> String {
"Printer".to_string()
}
fn connection_state(&self) -> ConnectionState {
ConnectionState::Connected
}
fn disconnect(&self) -> PsdkFatherResult<()> {
Ok(())
}
fn can_read(&self) -> bool {
true
}
fn write(&self, binary: &[u8]) -> PsdkFatherResult<()> {
// Send bytes to printer transport.
Ok(())
}
fn write_with_options(
&self,
binary: &[u8],
options: DeviceWriteOptions,
) -> PsdkFatherResult<()> {
self.write(binary)
}
fn read(&self, _options: Option<ReadOptions>) -> PsdkFatherResult<Vec<u8>> {
Ok(Vec::new())
}
fn flush(&self) -> PsdkFatherResult<()> {
Ok(())
}
}

CPCL is used by portable label printers. See the CPCL command reference for details.

use psdk_father::psdk::Psdk;
use psdk_fruit_cpcl::{
args::{CPrint, CQRCode},
BaseCpcl,
};
cpcl
.page((400, 576))?
.text((30, 40, "商品标签"))?
.bar((30, 120, "6901234567890", 2, 60))?
.qr_code((380, 80, "https://example.com", 5))?
.print(CPrint::default())?
.write()?;

Common methods include:

MethodDescription
page / page_height / page_widthPage dimensions
textText
bar1D barcode
qr_codeQR code
line / box_ / inverseGraphics and reverse printing
image / image_pixels / image_bytesImage commands
status / sn / model / version / battery_volumeQuery commands
printPrint

TSPL is used by label and barcode printers. See the TSPL command reference for details.

use psdk_father::psdk::Psdk;
use psdk_fruit_tspl::BaseTspl;
tspl
.page((60, 40))?
.gap(true)?
.direction(0)?
.cls()?
.text((50, 50, 1, 1, false, "标签内容"))?
.bar((30, 90, 300, 2))?
.qr_code((320, 90, 4, "https://example.com", "M"))?
.print(1)?
.write()?;

Common methods include page, gap, direction, cls, text, bar, line, box_, circle, ellipse, bar_code, qr_code, image, put_image, print, status, sn, version, and battery_volume.

ESC is used by thermal receipt and label printers. See the ESC command reference for details.

use psdk_father::psdk::Psdk;
use psdk_fruit_esc::BaseEsc;
esc
.wakeup()?
.enable()?
.line_dot(16)?
.stop_job()?
.write()?;

Common methods include wakeup, enable, image, image_bytes, position, stop_job, line_dot, paper_type, set_current_time, set_shutdown_time, state, sn, model, printer_version, and battery_volume.

psdk-fruit-cpcl, psdk-fruit-tspl, and psdk-fruit-esc enable image-plus by default, providing image byte helpers. Disable default features for minimal dependencies:

[dependencies]
psdk-fruit-cpcl = { version = "0.0.1", default-features = false }
  • Rust method names follow Rust conventions: box_ avoids a keyword, while qr_code / bar_code use snake case.
  • write() builds the current buffered commands and writes them to the device, then clears the command buffer on success.
  • rust/Cargo.lock is currently not committed to the repository. Application projects can manage their own lockfiles.