use std::fmt::Write; /// Everything that can go wrong talking to the instrument. #[derive(Debug, thiserror::Error)] pub enum Error { #[error("serial port: {0}")] Serial(#[from] serialport::Error), #[error("I/O: {0}")] Io(#[from] std::io::Error), /// A write command was not acknowledged with `8C `. #[error("no acknowledge for command 0x{cmd:02X} (got {got})")] NoAck { cmd: u8, got: String }, /// A read command answered with an unexpected header. #[error("bad response to command 0x{cmd:02X} (got {got})")] BadResponse { cmd: u8, got: String }, /// A data block ended early. #[error("{what} short ({got}/{want} bytes)")] Short { what: &'static str, got: usize, want: usize, }, #[error("timeout waiting for measurement data")] Timeout, /// The cancel flag (Ctrl+C) was raised during a wait. #[error("cancelled")] Cancelled, #[error("HPCS 6500 not found (no serial port with VID 0483 / PID 5741)")] NotFound, #[error("pcap: {0}")] Pcap(String), } pub type Result = std::result::Result; /// `8c 13 0f` style hex for error messages, `(nothing)` when empty. pub(crate) fn hex(b: &[u8]) -> String { if b.is_empty() { return "nothing".into(); } let mut s = String::new(); for (i, x) in b.iter().take(24).enumerate() { if i > 0 { s.push(' '); } let _ = write!(s, "{x:02x}"); } if b.len() > 24 { let _ = write!(s, " ... ({} bytes)", b.len()); } s }