use thiserror::Error;
#[derive(Error, Debug, Clone, PartialEq)]
pub enum TimeError {
#[error("Hardware error: {0}")]
Hardware(String),
#[error("Invalid sample rate: {0}")]
InvalidSampleRate(f32),
#[error("Clock not started")]
NotStarted,
#[error("Clock already started")]
AlreadyStarted,
#[error("Clock underflow")]
Underflow,
#[error("Clock overflow")]
Overflow,
#[error("Invalid tempo: {0}")]
InvalidTempo(f32),
#[error("Timing error: {0}")]
Timing(String),
}
#[allow(dead_code)]
pub type TimeResult<T> = Result<T, TimeError>;
impl TimeError {
pub fn hardware(msg: impl Into<String>) -> Self {
Self::Hardware(msg.into())
}
pub fn invalid_sample_rate(rate: f32) -> Self {
Self::InvalidSampleRate(rate)
}
pub fn invalid_tempo(tempo: f32) -> Self {
Self::InvalidTempo(tempo)
}
pub fn is_recoverable(&self) -> bool {
match self {
Self::Underflow | Self::Overflow => true,
_ => false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_time_error_creation() {
let err = TimeError::hardware("ALSA error");
assert!(matches!(err, TimeError::Hardware(_)));
let err = TimeError::invalid_sample_rate(96000.0);
assert!(matches!(err, TimeError::InvalidSampleRate(_)));
}
#[test]
fn test_time_error_recoverable() {
assert!(TimeError::Underflow.is_recoverable());
assert!(TimeError::Overflow.is_recoverable());
assert!(!TimeError::NotStarted.is_recoverable());
}
}