use thiserror::Error;
#[derive(Debug, Error)]
pub enum ToolError {
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("invalid path: {0}")]
InvalidPath(String),
#[error("out of bounds: {0}")]
OutOfBounds(String),
#[error("invalid pattern: {0}")]
InvalidPattern(String),
#[error("HTTP error: {0}")]
Http(String),
#[error("execution error: {0}")]
Execution(String),
#[error("timeout: {0}")]
Timeout(String),
#[error("validation error: {0}")]
Validation(String),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
}
pub type ToolResult<T> = Result<T, ToolError>;
impl From<globset::Error> for ToolError {
fn from(e: globset::Error) -> Self {
ToolError::InvalidPattern(e.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn tool_error_displays_io_error() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let err: ToolError = io_err.into();
assert!(err.to_string().contains("I/O error"));
}
#[test]
fn tool_error_displays_invalid_path() {
let err = ToolError::InvalidPath("not absolute".into());
assert!(err.to_string().contains("invalid path"));
}
#[test]
fn tool_error_from_glob_pattern_error() {
let glob_err = globset::Glob::new("[invalid").unwrap_err();
let err: ToolError = glob_err.into();
assert!(matches!(err, ToolError::InvalidPattern(_)));
}
}