use std::fmt;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, PartialEq)]
pub enum Error {
InvalidRange {
min: f64,
max: f64,
},
InvalidBitWidth(u8),
InvalidCanId(u32),
PayloadTooLong {
len: usize,
},
PayloadTooShort {
expected: usize,
actual: usize,
},
InvalidPayloadLength {
expected: usize,
actual: usize,
},
InvalidNodeId(u8),
NonFiniteValue(&'static str),
UnsupportedMode(u32),
UnknownParameter(String),
ReadOnlyParameter(&'static str),
ParameterTypeMismatch {
parameter: &'static str,
expected: &'static str,
actual: &'static str,
},
InvalidParameterValue {
parameter: &'static str,
constraint: &'static str,
},
InvalidModeTransition {
from: u8,
to: u8,
},
UnsafeOperation {
operation: &'static str,
required: &'static str,
actual_mode: u8,
},
InvalidRefreshRate(f64),
DuplicateMotorId(u8),
UnknownMotorId(u8),
UnknownMotorLabel(String),
InvalidTraceLine {
line: usize,
reason: String,
},
Transport(String),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidRange { min, max } => {
write!(
f,
"invalid range: max ({max}) must be greater than min ({min})"
)
}
Self::InvalidBitWidth(bits) => write!(f, "invalid bit width: {bits}"),
Self::InvalidCanId(id) => write!(f, "invalid CAN id: 0x{id:X}"),
Self::PayloadTooLong { len } => write!(f, "CAN payload too long: {len} bytes"),
Self::PayloadTooShort { expected, actual } => {
write!(
f,
"payload too short: expected {expected} bytes, got {actual}"
)
}
Self::InvalidPayloadLength { expected, actual } => {
write!(
f,
"invalid payload length: expected exactly {expected} bytes, got {actual}"
)
}
Self::InvalidNodeId(id) => {
write!(f, "invalid Knott Dynamics node id: {id}; expected 1..63")
}
Self::NonFiniteValue(field) => write!(f, "{field} must be finite"),
Self::UnsupportedMode(mode) => {
write!(f, "mode 0x{mode:02X} cannot be requested over CAN")
}
Self::UnknownParameter(parameter) => {
write!(f, "unknown Knott Dynamics parameter: {parameter}")
}
Self::ReadOnlyParameter(parameter) => {
write!(f, "Knott Dynamics parameter {parameter} is read-only")
}
Self::ParameterTypeMismatch {
parameter,
expected,
actual,
} => write!(
f,
"Knott Dynamics parameter {parameter} expects {expected}, got {actual}"
),
Self::InvalidParameterValue {
parameter,
constraint,
} => write!(
f,
"invalid Knott Dynamics value for {parameter}; expected {constraint}"
),
Self::InvalidModeTransition { from, to } => write!(
f,
"invalid Knott Dynamics mode transition from 0x{from:02X} to 0x{to:02X}"
),
Self::UnsafeOperation {
operation,
required,
actual_mode,
} => write!(
f,
"unsafe Knott Dynamics {operation}: requires {required}, current mode is 0x{actual_mode:02X}"
),
Self::InvalidRefreshRate(rate) => write!(f, "invalid refresh rate: {rate} Hz"),
Self::DuplicateMotorId(id) => write!(f, "duplicate motor id: 0x{id:02X}"),
Self::UnknownMotorId(id) => write!(f, "unknown motor id: 0x{id:02X}"),
Self::UnknownMotorLabel(label) => write!(f, "unknown motor label: {label}"),
Self::InvalidTraceLine { line, reason } => {
write!(f, "invalid CAN trace line {line}: {reason}")
}
Self::Transport(message) => write!(f, "CAN transport error: {message}"),
}
}
}
impl std::error::Error for Error {}