use std::io;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("unsupported format: {0}")]
UnsupportedFormat(String),
#[error("unsupported operation: {0}")]
UnsupportedOperation(String),
#[error("parse error: {0}")]
ParseError(String),
#[error("missing dependency `{name}`: {details}")]
MissingDependency {
name: String,
details: String,
},
#[error("sidecar `{name}` failed with exit code {code:?}: {stderr}")]
SidecarFailure {
name: String,
code: Option<i32>,
stderr: String,
},
#[error("{0}")]
Other(String),
}
impl Error {
pub fn parse(msg: impl Into<String>) -> Self {
Self::ParseError(msg.into())
}
pub fn other(msg: impl Into<String>) -> Self {
Self::Other(msg.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn io_errors_convert_via_from() {
let io_err = io::Error::new(io::ErrorKind::NotFound, "missing");
let err: Error = io_err.into();
assert!(matches!(err, Error::Io(_)));
assert!(err.to_string().contains("missing"));
}
#[test]
fn unsupported_format_renders_path() {
let err = Error::UnsupportedFormat(".xyz".into());
assert!(err.to_string().contains(".xyz"));
}
#[test]
fn missing_dependency_renders_name_and_details() {
let err = Error::MissingDependency {
name: "pandoc".into(),
details: "binary not found in PATH".into(),
};
let s = err.to_string();
assert!(s.contains("pandoc"));
assert!(s.contains("PATH"));
}
}