//! Error handling for the CLI. use std::path::PathBuf; use thiserror::Error; /// Exit codes for the CLI. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ExitCode { /// Successful execution. Success = 0, /// Simulation error (non-convergence, validation failure). SimulationError = 1, /// Configuration error (invalid JSON, missing fields). ConfigError = 2, /// I/O error (file not found, permission denied). IoError = 3, } impl From for i32 { fn from(code: ExitCode) -> i32 { code as i32 } } /// CLI-specific errors. #[derive(Error, Debug)] pub enum CliError { #[error("Configuration error: {0}")] Config(String), #[error("Configuration file not found: {0}")] ConfigNotFound(PathBuf), #[error("Invalid configuration file: {0}")] InvalidConfig(#[source] serde_json::Error), #[error("Simulation error: {0}")] Simulation(String), #[error("I/O error: {0}")] Io(#[from] std::io::Error), #[error("Batch directory not found: {0}")] BatchDirNotFound(PathBuf), #[error("No configuration files found in directory: {0}")] NoConfigFiles(PathBuf), #[error("Component error: {0}")] Component(#[from] entropyk_components::ComponentError), } impl CliError { pub fn exit_code(&self) -> ExitCode { match self { CliError::Config(_) | CliError::ConfigNotFound(_) | CliError::InvalidConfig(_) => { ExitCode::ConfigError } CliError::Simulation(_) | CliError::Component(_) => ExitCode::SimulationError, CliError::Io(_) | CliError::BatchDirNotFound(_) | CliError::NoConfigFiles(_) => { ExitCode::IoError } } } } /// Result type for CLI operations. pub type CliResult = Result;