use std::time::Duration;
use thiserror::Error;
use crate::InstrumentInterface;
pub struct Instrument<P: std::io::Read + std::io::Write> {
port: P,
terminator: String,
timeout: Duration,
}
impl<P: std::io::Read + std::io::Write> Instrument<P> {
pub fn new(port: P, timeout: Duration) -> Self {
Self {
port,
terminator: "\n".to_string(),
timeout,
}
}
}
impl<P: std::io::Read + std::io::Write> InstrumentInterface for Instrument<P> {
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), InstrumentError> {
self.port.read_exact(buf)?;
Ok(())
}
fn get_terminator(&self) -> &str {
self.terminator.as_str()
}
fn set_terminator(&mut self, terminator: &str) {
self.terminator = terminator.to_string();
}
fn get_timeout(&self) -> Duration {
self.timeout
}
fn write_raw(&mut self, data: &[u8]) -> Result<(), InstrumentError> {
self.port.write_all(data)?;
self.port.flush()?;
Ok(())
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum InstrumentError {
#[error("Instrument did not acknowledge the command sent, but responded with: {0}")]
NotAcknowledged(String),
#[error(
"Channel with index {idx} is out of range. Number of channels available: {nof_channels}"
)]
ChannelIndexOutOfRange {
idx: usize,
nof_channels: usize,
},
#[error("Float value {value} is out of range. Allowed range is [{min}, {max}]")]
FloatValueOutOfRange {
value: f64,
min: f64,
max: f64,
},
#[error("Integer value {value} is out of range. Allowed range is [{min}, {max}]")]
IntValueOutOfRange {
value: i64,
min: i64,
max: i64,
},
#[error("{0}")]
InvalidArgument(String),
#[error(transparent)]
Io(#[from] std::io::Error),
#[error("{0}")]
InstrumentStatus(String),
#[error("Response from instrument could not be parsed. Response was: {0}")]
ResponseParseError(String),
#[cfg(feature = "serial")]
#[error(transparent)]
Serialport(#[from] serialport::Error),
#[error(
"Timeout occured while waiting for a response from the instrument. Timeout was set to {0:?}."
)]
Timeout(Duration),
#[error(
"Timeout occured while waiting for a response to query: {query}. Timeout was set to {timeout:?}."
)]
TimeoutQuery {
query: String,
timeout: Duration,
},
}