graph_d 1.3.2

A native graph database implementation in Rust with built-in JSON support and SQLite-like simplicity
Documentation
//! Error types and result handling for the graph database.
//!
//! This module provides the [`GraphError`] enum and [`Result`] type alias used throughout
//! the graph database. All operations that can fail return a [`Result<T>`] which wraps
//! either the success value or a [`GraphError`].
//!
//! # Error Categories
//!
//! The error types are organized by functional area:
//! - **Storage**: File I/O, memory mapping, persistence errors
//! - **NotFound**: Missing nodes, relationships, or properties
//! - **Invalid**: Malformed data, invalid parameters, constraint violations
//! - **Serialization**: JSON parsing and encoding errors
//! - **Transaction**: ACID violation, deadlock, rollback errors
//! - **Concurrency**: Lock contention, race conditions
//! - **Memory**: Memory allocation, pool exhaustion, cache errors
//! - **Io**: Low-level I/O operations and file system errors
//!
//! # Example
//!
//! ```rust
//! use graph_d::{Graph, GraphError, Result};
//! use std::collections::HashMap;
//!
//! fn example_error_handling() -> Result<()> {
//!     let mut graph = Graph::new()?;
//!     
//!     // This will succeed
//!     let node_id = graph.create_node(HashMap::new())?;
//!     
//!     // This will return a NotFound error
//!     match graph.get_node(999) {
//!         Ok(Some(node)) => println!("Found node: {:?}", node),
//!         Ok(None) => println!("Node doesn't exist"),
//!         Err(GraphError::Storage(msg)) => eprintln!("Storage error: {}", msg),
//!         Err(e) => eprintln!("Other error: {}", e),
//!     }
//!     
//!     Ok(())
//! }
//! ```

use std::fmt;

/// Result type alias for the graph database.
///
/// This is a convenience type alias that wraps [`std::result::Result`] with
/// [`GraphError`] as the error type. All fallible operations in the graph
/// database return this type.
///
/// # Example
///
/// ```rust
/// use graph_d::Result;
/// use std::collections::HashMap;
///
/// fn create_test_node() -> Result<u64> {
///     let mut graph = graph_d::Graph::new()?;
///     let node_id = graph.create_node(HashMap::new())?;
///     Ok(node_id)
/// }
/// ```
pub type Result<T> = std::result::Result<T, GraphError>;

/// Main error type for graph database operations.
///
/// This enum represents all possible error conditions that can occur during
/// graph database operations. Each variant contains a descriptive message
/// that provides context about the specific error.
///
/// # Variants
///
/// - [`Storage`]: Issues with the underlying storage layer (files, memory)
/// - [`NotFound`]: Requested entity (node/relationship) doesn't exist
/// - [`Invalid`]: Invalid parameters or constraint violations
/// - [`Serialization`]: JSON parsing or encoding failures
/// - [`Transaction`]: Transaction integrity or concurrency issues
/// - [`Concurrency`]: Multi-threaded access conflicts
/// - [`Io`]: Low-level I/O and file system errors
///
/// # Error Conversion
///
/// The error type implements [`From`] for common error types:
/// - [`serde_json::Error`] → [`GraphError::Serialization`]
/// - [`std::io::Error`] → [`GraphError::Io`]
///
/// # Example
///
/// ```rust
/// use graph_d::{Graph, GraphError};
/// use std::collections::HashMap;
///
/// let mut graph = Graph::new().unwrap();
///
/// // This will return a NotFound error
/// match graph.get_node(999) {
///     Ok(Some(node)) => println!("Found: {:?}", node),
///     Ok(None) => println!("Node doesn't exist"),
///     Err(GraphError::NotFound(msg)) => println!("Not found: {}", msg),
///     Err(GraphError::Storage(msg)) => println!("Storage issue: {}", msg),
///     Err(e) => println!("Other error: {}", e),
/// }
/// ```
///
/// [`Storage`]: GraphError::Storage
/// [`NotFound`]: GraphError::NotFound
/// [`Invalid`]: GraphError::Invalid
/// [`Serialization`]: GraphError::Serialization
/// [`Transaction`]: GraphError::Transaction
/// [`Concurrency`]: GraphError::Concurrency
/// [`Io`]: GraphError::Io
#[derive(Debug, Clone, PartialEq)]
pub enum GraphError {
    /// Storage-related errors.
    ///
    /// Covers issues with the storage backend such as file corruption,
    /// memory mapping failures, or persistent storage problems.
    ///
    /// # Examples
    /// - Failed to open database file
    /// - Memory mapping error
    /// - Disk full during write operation
    Storage(String),

    /// Node or relationship not found.
    ///
    /// Indicates that a requested entity doesn't exist in the graph.
    /// This is not necessarily an error condition - it may be expected
    /// behavior in many query scenarios.
    ///
    /// # Examples
    /// - Querying a node ID that doesn't exist
    /// - Attempting to create a relationship with non-existent nodes
    /// - Property lookup on missing entities
    NotFound(String),

    /// Invalid operation or data.
    ///
    /// Represents constraint violations, malformed input, or operations
    /// that violate the graph's integrity rules.
    ///
    /// # Examples
    /// - Invalid node or relationship ID (e.g., negative values)
    /// - Malformed property keys or values
    /// - Constraint violations in transactions
    Invalid(String),

    /// Serialization/deserialization errors.
    ///
    /// Occurs when JSON properties cannot be parsed or encoded properly.
    /// This typically indicates malformed JSON data or incompatible types.
    ///
    /// # Examples
    /// - Invalid JSON in property values
    /// - Type conversion failures during deserialization
    /// - Encoding errors when persisting to storage
    Serialization(String),

    /// Transaction-related errors.
    ///
    /// Covers issues with ACID compliance, transaction boundaries,
    /// and atomicity guarantees in multi-operation sequences.
    ///
    /// # Examples
    /// - Transaction rollback due to constraint violation
    /// - Deadlock detection and prevention
    /// - Isolation level violations
    Transaction(String),

    /// Concurrency-related errors.
    ///
    /// Represents conflicts that arise from concurrent access patterns
    /// in multi-threaded environments.
    ///
    /// # Examples
    /// - Lock contention between threads
    /// - Race conditions in index updates
    /// - Inconsistent reads due to concurrent writes
    Concurrency(String),

    /// I/O errors.
    ///
    /// Low-level input/output errors from the operating system,
    /// typically related to file system operations.
    ///
    /// # Examples
    /// - Permission denied accessing database files
    /// - Disk I/O errors during read/write operations
    /// - Network I/O issues in distributed scenarios
    Io(String),

    /// Memory management errors.
    ///
    /// Represents issues with memory allocation, pool management,
    /// and cache operations in the advanced memory management system.
    ///
    /// # Examples
    /// - Memory pool exhaustion
    /// - Cache eviction failures
    /// - Arena allocation failures
    /// - Memory pressure threshold exceeded
    Memory(String),

    /// Query parsing and execution errors.
    ///
    /// Specific to Graph Query Language (GQL) parsing, validation,
    /// and execution failures.
    ///
    /// # Examples
    /// - Invalid GQL syntax
    /// - Query compilation failures
    /// - Runtime query execution errors
    /// - Query timeout or resource limits exceeded
    Query(String),

    /// Index operation errors.
    ///
    /// Errors related to secondary indexing operations, including
    /// index creation, maintenance, and lookup failures.
    ///
    /// # Examples
    /// - Index corruption or inconsistency
    /// - Index rebuild failures
    /// - Property indexing constraint violations
    /// - Index lookup optimization failures
    Index(String),

    /// Configuration and initialization errors.
    ///
    /// Issues with system configuration, initialization sequences,
    /// and parameter validation during startup.
    ///
    /// # Examples
    /// - Invalid configuration parameters
    /// - System initialization failures
    /// - Resource allocation during startup
    /// - Environment setup errors
    Config(String),

    /// Network and distributed operation errors.
    ///
    /// Errors related to network operations and distributed
    /// graph database scenarios (future extensions).
    ///
    /// # Examples
    /// - Network connectivity issues
    /// - Distributed consensus failures
    /// - Replication synchronization errors
    /// - Cluster coordination problems
    Network(String),
}

impl fmt::Display for GraphError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            GraphError::Storage(msg) => write!(f, "Storage error: {msg}"),
            GraphError::NotFound(msg) => write!(f, "Not found: {msg}"),
            GraphError::Invalid(msg) => write!(f, "Invalid: {msg}"),
            GraphError::Serialization(msg) => write!(f, "Serialization error: {msg}"),
            GraphError::Transaction(msg) => write!(f, "Transaction error: {msg}"),
            GraphError::Concurrency(msg) => write!(f, "Concurrency error: {msg}"),
            GraphError::Io(msg) => write!(f, "I/O error: {msg}"),
            GraphError::Memory(msg) => write!(f, "Memory error: {msg}"),
            GraphError::Query(msg) => write!(f, "Query error: {msg}"),
            GraphError::Index(msg) => write!(f, "Index error: {msg}"),
            GraphError::Config(msg) => write!(f, "Configuration error: {msg}"),
            GraphError::Network(msg) => write!(f, "Network error: {msg}"),
        }
    }
}

impl std::error::Error for GraphError {}

impl From<serde_json::Error> for GraphError {
    fn from(err: serde_json::Error) -> Self {
        GraphError::Serialization(err.to_string())
    }
}

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