use thiserror::Error;
pub type WemResult<T> = Result<T, WemError>;
#[derive(Debug, Error)]
pub enum WemError {
#[error("Error opening {filename}")]
FileOpen {
filename: String,
},
#[error("Parse error: {message}")]
Parse {
message: String,
},
#[error("Parse error: expected {expected} bytes, read {actual} - likely wrong codebook")]
SizeMismatch {
expected: u64,
actual: u64,
},
#[error("Parse error: invalid codebook id {id}, try --inline-codebooks")]
InvalidCodebookId {
id: i32,
},
#[error("{message}")]
Codebook {
message: String,
},
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("Unexpected end of stream: {message}")]
EndOfStream {
message: String,
},
}
impl WemError {
pub fn parse(message: impl Into<String>) -> Self {
WemError::Parse {
message: message.into(),
}
}
pub fn codebook(message: impl Into<String>) -> Self {
WemError::Codebook {
message: message.into(),
}
}
pub fn file_open(filename: impl Into<String>) -> Self {
WemError::FileOpen {
filename: filename.into(),
}
}
pub fn size_mismatch(expected: u64, actual: u64) -> Self {
WemError::SizeMismatch { expected, actual }
}
pub fn invalid_codebook_id(id: i32) -> Self {
WemError::InvalidCodebookId { id }
}
pub fn end_of_stream(message: impl Into<String>) -> Self {
WemError::EndOfStream {
message: message.into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_error() {
let err = WemError::parse("test message");
assert!(matches!(err, WemError::Parse { .. }));
assert!(err.to_string().contains("test message"));
}
#[test]
fn test_codebook_error() {
let err = WemError::codebook("codebook issue");
assert!(matches!(err, WemError::Codebook { .. }));
assert!(err.to_string().contains("codebook issue"));
}
#[test]
fn test_file_open_error() {
let err = WemError::file_open("test.wem");
assert!(matches!(err, WemError::FileOpen { .. }));
assert!(err.to_string().contains("test.wem"));
}
#[test]
fn test_size_mismatch_error() {
let err = WemError::size_mismatch(100, 50);
assert!(matches!(err, WemError::SizeMismatch { .. }));
let msg = err.to_string();
assert!(msg.contains("100"));
assert!(msg.contains("50"));
}
#[test]
fn test_invalid_codebook_id_error() {
let err = WemError::invalid_codebook_id(42);
assert!(matches!(err, WemError::InvalidCodebookId { .. }));
assert!(err.to_string().contains("42"));
}
#[test]
fn test_end_of_stream_error() {
let err = WemError::end_of_stream("reading header");
assert!(matches!(err, WemError::EndOfStream { .. }));
assert!(err.to_string().contains("reading header"));
}
#[test]
fn test_io_error_from() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let wem_err: WemError = io_err.into();
assert!(matches!(wem_err, WemError::Io(_)));
}
#[test]
fn test_error_display() {
let errors: Vec<WemError> = vec![
WemError::parse("parse"),
WemError::codebook("codebook"),
WemError::file_open("file"),
WemError::size_mismatch(1, 2),
WemError::invalid_codebook_id(1),
WemError::end_of_stream("eos"),
];
for err in errors {
let _ = err.to_string();
}
}
}