Skip to main content

audiobox/
error.rs

1use std::fmt;
2
3/// Stable error categories. Match on the code rather than the message.
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5#[non_exhaustive]
6pub enum ErrorCode {
7    UnsupportedFormat,
8    DecodeError,
9    EncodeError,
10    InvalidArgument,
11    LimitExceeded,
12    Io,
13    /// Malformed text, such as a synthesizer score.
14    Syntax,
15    /// A nonblocking source temporarily has no frames; retry later.
16    Underrun,
17}
18
19/// An error with a stable category and human-readable context.
20#[derive(Debug)]
21pub struct Error {
22    pub code: ErrorCode,
23    pub message: String,
24}
25
26impl Error {
27    pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
28        Self {
29            code,
30            message: message.into(),
31        }
32    }
33    pub(crate) fn invalid(message: impl Into<String>) -> Self {
34        Self::new(ErrorCode::InvalidArgument, message)
35    }
36    pub(crate) fn decode(message: impl Into<String>) -> Self {
37        Self::new(ErrorCode::DecodeError, message)
38    }
39    pub(crate) fn encode(message: impl Into<String>) -> Self {
40        Self::new(ErrorCode::EncodeError, message)
41    }
42    pub(crate) fn limit(message: impl Into<String>) -> Self {
43        Self::new(ErrorCode::LimitExceeded, message)
44    }
45}
46impl fmt::Display for Error {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        f.write_str(&self.message)
49    }
50}
51impl std::error::Error for Error {}
52impl From<std::io::Error> for Error {
53    fn from(value: std::io::Error) -> Self {
54        Self::new(ErrorCode::Io, value.to_string())
55    }
56}
57pub type Result<T> = std::result::Result<T, Error>;