#[cfg(feature = "flac")]
use crate::flac::error::FlacError;
#[cfg(feature = "wav")]
use crate::wav::error::WavError;
use core::fmt::{Display, Formatter, Result as FmtResult};
use std::io;
use thiserror::Error;
#[allow(clippy::result_large_err)]
pub type AudioIOResult<T> = Result<T, AudioIOError>;
#[derive(Debug, Error)]
pub enum AudioIOError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("AudioSamples error: {0}")]
AudioSamples(#[from] audio_samples::AudioSampleError),
#[error("Corrupted data at {position}: {description} - {details}")]
CorruptedData {
description: String,
details: String,
position: ErrorPosition,
},
#[cfg(feature = "wav")]
#[error("Wav error: {0}")]
WavError(#[from] WavError),
#[cfg(feature = "flac")]
#[error("FLAC error: {0}")]
FlacError(#[from] FlacError),
#[error("Seek error: {0}")]
SeekError(String),
#[error("End of stream: {0}")]
EndOfStream(String),
#[error("Missing feature: {0}")]
MissingFeature(String),
#[error("Unsupported format: {0}")]
UnsupportedFormat(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct ErrorPosition {
pub offset: usize,
pub description: String,
}
impl ErrorPosition {
pub fn new(offset: usize) -> Self {
Self {
offset,
description: format!("byte offset {offset}"),
}
}
pub fn with_description(mut self, description: impl Into<String>) -> Self {
self.description = description.into();
self
}
}
impl Display for ErrorPosition {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "{}", self.description)
}
}
impl AudioIOError {
pub fn corrupted_data(
description: impl Into<String>,
details: impl Into<String>,
position: ErrorPosition,
) -> Self {
AudioIOError::CorruptedData {
description: description.into(),
details: details.into(),
position,
}
}
pub fn corrupted_data_simple(
description: impl Into<String>,
details: impl Into<String>,
) -> Self {
AudioIOError::CorruptedData {
description: description.into(),
details: details.into(),
position: ErrorPosition::default(),
}
}
pub fn seek_error(message: impl Into<String>) -> Self {
AudioIOError::SeekError(message.into())
}
pub fn end_of_stream(message: impl Into<String>) -> Self {
AudioIOError::EndOfStream(message.into())
}
pub fn missing_feature(message: impl Into<String>) -> Self {
AudioIOError::MissingFeature(message.into())
}
pub fn unsupported_format(message: impl Into<String>) -> Self {
AudioIOError::UnsupportedFormat(message.into())
}
}