collet 0.1.1

Relentless agentic coding orchestrator with zero-drop agent loops
Documentation
//! Common error types for the collet project
//!
//! This module provides a unified error type that wraps all possible errors
//! that can occur in the application. It uses the `thiserror` crate for
//! ergonomic error handling.

use std::io;

use thiserror::Error;

/// Unified error type for the collet application
///
/// This enum represents all possible errors that can occur in the application.
/// It provides user-friendly error messages and supports conversion from
/// underlying error types using the `From` trait.
#[derive(Error, Debug)]
pub enum AgentError {
    /// I/O operation errors
    #[error("I/O error: {0}")]
    Io(#[from] io::Error),

    /// Transport layer errors (MCP, HTTP, etc.)
    #[error("Transport error: {0}")]
    Transport(String),

    /// Invalid argument or input errors
    #[error("Invalid argument: {0}")]
    InvalidArgument(String),

    /// Serialization/deserialization errors
    #[error("Serialization error: {0}")]
    Serialization(#[from] serde_json::Error),

    /// Parse errors (integers, etc.)
    #[error("Parse error: {0}")]
    ParseInt(#[from] std::num::ParseIntError),

    /// Configuration errors
    #[error("Configuration error: {0}")]
    Config(String),

    /// Command execution errors
    #[error("Command execution error: {0}")]
    Command(String),

    /// Timeout errors
    #[error("Operation timed out after {0}s")]
    Timeout(u64),

    /// HTTP client errors (reqwest)
    #[error("HTTP error: {0}")]
    Http(#[from] reqwest::Error),

    /// Internal errors that should not occur
    #[error("Internal error: {0}")]
    Internal(String),
}

/// Type alias for Result with AgentError
pub type Result<T> = std::result::Result<T, AgentError>;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_error_display() {
        let err = AgentError::InvalidArgument("test error".to_string());
        assert_eq!(err.to_string(), "Invalid argument: test error");
    }

    #[test]
    fn test_io_error_conversion() {
        let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
        let agent_err = AgentError::from(io_err);
        assert!(matches!(agent_err, AgentError::Io(_)));
    }

    #[test]
    fn test_serialization_error_conversion() {
        let serde_err = serde_json::from_str::<serde_json::Value>("invalid json").unwrap_err();
        let agent_err = AgentError::from(serde_err);
        assert!(matches!(agent_err, AgentError::Serialization(_)));
    }
}