chaotic_semantic_memory 0.3.4

AI memory systems with hyperdimensional vectors and chaotic reservoirs
Documentation
use crate::error::MemoryError;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum CliError {
    #[error("Configuration error: {0}")]
    Config(String),

    #[error("Database error: {0}")]
    Database(String),

    #[error("Input error: {0}")]
    Input(String),

    #[error("Output error: {0}")]
    Output(String),

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

    #[error("Persistence error: {0}")]
    Persistence(String),

    #[error("{0}")]
    Memory(#[from] MemoryError),

    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),

    #[error("{0}")]
    Other(String),
}

impl From<anyhow::Error> for CliError {
    fn from(err: anyhow::Error) -> Self {
        CliError::Other(err.to_string())
    }
}

pub type Result<T> = std::result::Result<T, CliError>;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(i32)]
pub enum ExitCode {
    Success = 0,
    ConfigError = 1,
    DatabaseError = 2,
    InputError = 3,
    OutputError = 4,
    ValidationError = 5,
    MemoryError = 6,
    IoError = 7,
    UnknownError = 255,
}

impl From<&CliError> for ExitCode {
    fn from(error: &CliError) -> Self {
        match error {
            CliError::Config(_) => ExitCode::ConfigError,
            CliError::Database(_) => ExitCode::DatabaseError,
            CliError::Input(_) => ExitCode::InputError,
            CliError::Output(_) => ExitCode::OutputError,
            CliError::Validation(_) => ExitCode::ValidationError,
            CliError::Persistence(_) => ExitCode::DatabaseError,
            CliError::Memory(_) => ExitCode::MemoryError,
            CliError::Io(_) => ExitCode::IoError,
            CliError::Other(_) => ExitCode::UnknownError,
        }
    }
}

impl From<CliError> for ExitCode {
    fn from(error: CliError) -> Self {
        ExitCode::from(&error)
    }
}

impl CliError {
    pub fn exit_code(&self) -> i32 {
        ExitCode::from(self) as i32
    }
}

impl ExitCode {
    pub fn as_i32(self) -> i32 {
        self as i32
    }
}

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

    #[test]
    fn test_exit_code_mapping() {
        assert_eq!(CliError::Config("x".into()).exit_code(), 1);
        assert_eq!(CliError::Database("x".into()).exit_code(), 2);
        assert_eq!(CliError::Input("x".into()).exit_code(), 3);
        assert_eq!(CliError::Output("x".into()).exit_code(), 4);
        assert_eq!(CliError::Validation("x".into()).exit_code(), 5);
    }

    #[test]
    fn test_memory_error_conversion() {
        let cli_err: CliError = MemoryError::InvalidInput {
            field: "test".into(),
            reason: "invalid".into(),
        }
        .into();
        assert!(matches!(cli_err, CliError::Memory(_)));
        assert_eq!(cli_err.exit_code(), 6);
    }
}