#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum RtlSdrError {
#[error("USB error: {0}")]
Usb(#[from] rusb::Error),
#[error("device not found at index {0}")]
DeviceNotFound(u32),
#[error("no supported tuner found")]
NoTuner,
#[error("tuner error: {0}")]
Tuner(String),
#[error("invalid sample rate: {0} Hz")]
InvalidSampleRate(u32),
#[error("invalid parameter: {0}")]
InvalidParameter(String),
#[error("device busy")]
DeviceBusy,
#[error("device lost")]
DeviceLost,
#[error("register access failed")]
RegisterAccess,
}
impl RtlSdrError {
#[must_use]
pub fn is_disconnected(&self) -> bool {
matches!(self, Self::DeviceLost | Self::Usb(rusb::Error::NoDevice))
}
#[must_use]
pub fn is_timeout(&self) -> bool {
matches!(self, Self::Usb(rusb::Error::Timeout))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_disconnected_recognises_device_lost_and_no_device() {
assert!(RtlSdrError::DeviceLost.is_disconnected());
assert!(RtlSdrError::Usb(rusb::Error::NoDevice).is_disconnected());
}
#[test]
fn is_disconnected_returns_false_for_other_variants() {
assert!(!RtlSdrError::DeviceBusy.is_disconnected());
assert!(!RtlSdrError::Usb(rusb::Error::Timeout).is_disconnected());
assert!(!RtlSdrError::NoTuner.is_disconnected());
assert!(!RtlSdrError::DeviceNotFound(0).is_disconnected());
assert!(!RtlSdrError::Tuner("anything".to_string()).is_disconnected());
}
#[test]
fn is_timeout_recognises_only_usb_timeout() {
assert!(RtlSdrError::Usb(rusb::Error::Timeout).is_timeout());
}
#[test]
fn is_timeout_returns_false_for_other_variants() {
assert!(!RtlSdrError::DeviceLost.is_timeout());
assert!(!RtlSdrError::DeviceBusy.is_timeout());
assert!(!RtlSdrError::Usb(rusb::Error::NoDevice).is_timeout());
assert!(!RtlSdrError::Usb(rusb::Error::Io).is_timeout());
assert!(!RtlSdrError::RegisterAccess.is_timeout());
}
}