cargo-governor 2.0.3

Machine-First, LLM-Ready, CI/CD-Native release automation tool for Rust crates
Documentation
//! Error types for cargo-governor

use std::process::ExitCode;

/// Command exit codes matching the specification
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CommandExitCode {
    /// Success
    Success = 0,
    /// General error
    GeneralError = 1,
    /// Invalid arguments
    InvalidArguments = 2,
    /// Config error
    ConfigError = 3,
    /// Git error
    GitError = 10,
    /// Registry error
    RegistryError = 11,
    /// Version error
    VersionError = 12,
    /// Check failed
    CheckFailed = 13,
    /// Security error
    SecurityError = 14,
    /// Network error
    NetworkError = 15,
    /// Pre-publish checks failed
    PrePublishChecksFailed = 16,
    /// Partial success
    PartialSuccess = 20,
    /// Rollback failed
    RollbackFailed = 21,
    /// Checkpoint created
    CheckpointCreated = 30,
    /// No changes
    NoChanges = 31,
    /// Drift detected in owners
    DriftDetected = 32,
}

impl From<CommandExitCode> for ExitCode {
    fn from(code: CommandExitCode) -> Self {
        Self::from(code as u8)
    }
}

/// Result type for commands
pub type Result<T> = std::result::Result<T, Error>;

/// Main error type
#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("CLI error: {0}")]
    Cli(String),

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

    #[error("Invalid arguments: {0}")]
    InvalidArguments(String),

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

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

    #[error("Core error: {0}")]
    Core(#[from] governor_core::Error),

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

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

impl From<String> for Error {
    fn from(s: String) -> Self {
        Self::Cli(s)
    }
}

impl From<governor_application::ApplicationError> for Error {
    fn from(error: governor_application::ApplicationError) -> Self {
        match error {
            governor_application::ApplicationError::InvalidArguments(message) => {
                Self::InvalidArguments(message)
            }
            governor_application::ApplicationError::Workspace(message) => Self::Config(message),
            governor_application::ApplicationError::SourceControl(error) => {
                Self::Git(error.to_string())
            }
            governor_application::ApplicationError::Registry(error) => {
                Self::Registry(error.to_string())
            }
            governor_application::ApplicationError::Checkpoint(error) => {
                Self::Config(error.to_string())
            }
            governor_application::ApplicationError::Io(error) => Self::StdIo(error),
        }
    }
}

impl Error {
    #[must_use]
    pub const fn exit_code(&self) -> CommandExitCode {
        match self {
            Self::Cli(_) | Self::InvalidArguments(_) => CommandExitCode::InvalidArguments,
            Self::Config(_) => CommandExitCode::ConfigError,
            Self::Git(_) => CommandExitCode::GitError,
            Self::Registry(_) => CommandExitCode::RegistryError,
            Self::Core(_) | Self::StdIo(_) | Self::Serialization(_) => {
                CommandExitCode::GeneralError
            }
        }
    }
}