tellaro-query-language 1.3.8

A flexible, human-friendly query language for searching and filtering structured data
Documentation
//! Error types for TQL operations.
//!
//! This module defines all error types that can occur during TQL parsing,
//! evaluation, and execution. Matches Python implementation's exception hierarchy.

use thiserror::Error;

/// Result type alias for TQL operations
pub type Result<T> = std::result::Result<T, TqlError>;

/// Main error type for TQL operations
#[derive(Error, Debug, Clone, PartialEq)]
pub enum TqlError {
    /// Parse error with position information
    #[error("Parse error at position {position}: {message}")]
    ParseError {
        message: String,
        position: usize,
        query: Option<String>,
    },

    /// Syntax error in query
    #[error("Syntax error: {message}")]
    SyntaxError {
        message: String,
        position: Option<usize>,
        query: Option<String>,
        suggestions: Vec<String>,
    },

    /// Field not found or invalid field access
    #[error("Field error: {0}")]
    FieldError(String),

    /// Type mismatch or type conversion error
    #[error("Type error: {0}")]
    TypeError(String),

    /// Invalid operator usage
    #[error("Operator error: {0}")]
    OperatorError(String),

    /// Invalid value
    #[error("Value error: {0}")]
    ValueError(String),

    /// Query execution error
    #[error("Execution error: {0}")]
    ExecutionError(String),

    /// Validation error
    #[error("Validation error: {0}")]
    ValidationError(String),

    /// Unsupported operation
    #[error("Unsupported operation: {0}")]
    UnsupportedOperation(String),

    /// I/O error
    #[error("I/O error: {0}")]
    IoError(String),

    /// Network error (DNS, GeoIP, etc.)
    #[error("Network error: {0}")]
    NetworkError(String),

    /// Mutator error
    #[error("Mutator error: {0}")]
    MutatorError(String),
}

impl From<std::io::Error> for TqlError {
    fn from(err: std::io::Error) -> Self {
        TqlError::IoError(err.to_string())
    }
}

impl From<serde_json::Error> for TqlError {
    fn from(err: serde_json::Error) -> Self {
        TqlError::ExecutionError(format!("JSON error: {}", err))
    }
}

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

    #[test]
    fn test_error_display() {
        let err = TqlError::ParseError {
            message: "Unexpected token".to_string(),
            position: 5,
            query: Some("field eq".to_string()),
        };
        assert!(err.to_string().contains("position 5"));
    }

    #[test]
    fn test_syntax_error_with_suggestions() {
        let err = TqlError::SyntaxError {
            message: "Missing value".to_string(),
            position: Some(8),
            query: Some("field eq".to_string()),
            suggestions: vec!["field eq 'value'".to_string()],
        };
        assert!(err.to_string().contains("Syntax error"));
    }

    #[test]
    fn test_io_error_conversion() {
        let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
        let tql_err: TqlError = io_err.into();
        assert!(matches!(tql_err, TqlError::IoError(_)));
    }
}