use std::io;
use audio_core_bsd::AudioError;
#[derive(Debug, thiserror::Error)]
pub enum ClockError {
#[error("clock source unavailable: {0}")]
Unavailable(String),
#[error("clock not yet synchronised: {0}")]
NotSynced(String),
#[error("invalid sample rate: {0} Hz")]
InvalidSampleRate(u32),
#[error("timestamp conversion overflow")]
ConversionOverflow,
#[error(transparent)]
Core(#[from] AudioError),
#[error(transparent)]
Io(#[from] io::Error),
}
pub type Result<T> = core::result::Result<T, ClockError>;
#[cfg(test)]
mod tests {
use std::io;
use audio_core_bsd::AudioError;
use super::{ClockError, Result};
#[test]
fn unavailable_display_carries_message() {
let msg = ClockError::Unavailable("no ptpd".into()).to_string();
assert_eq!(msg, "clock source unavailable: no ptpd");
}
#[test]
fn not_synced_display_carries_message() {
let msg = ClockError::NotSynced("ntp converging".into()).to_string();
assert_eq!(msg, "clock not yet synchronised: ntp converging");
}
#[test]
fn invalid_sample_rate_display_includes_value() {
let msg = ClockError::InvalidSampleRate(0).to_string();
assert_eq!(msg, "invalid sample rate: 0 Hz");
}
#[test]
fn conversion_overflow_display() {
assert_eq!(
ClockError::ConversionOverflow.to_string(),
"timestamp conversion overflow"
);
}
#[test]
fn core_variant_wraps_audio_error() {
let err = ClockError::from(AudioError::InvalidSampleRate(0));
assert_eq!(err.to_string(), "invalid sample rate: 0 Hz");
}
#[test]
fn core_from_audio_error_preserves_identity() {
let core = AudioError::InvalidChannelCount(0);
let wrapped: ClockError = core.clone().into();
assert!(matches!(wrapped, ClockError::Core(ref e) if *e == core));
}
#[test]
fn io_variant_wraps_std_io_error() {
let io_err = io::Error::new(io::ErrorKind::NotFound, "missing");
let err = ClockError::from(io_err);
assert!(err.to_string().contains("missing"));
}
#[test]
fn result_alias_ok_carries_value() {
let ok: Result<u32> = Ok(7);
assert_eq!(ok.map(|v| v + 1).unwrap(), 8);
}
#[test]
fn result_alias_err_carries_clock_error() {
let err: Result<u32> = Err(ClockError::Unavailable("x".into()));
assert!(err.is_err());
}
}