arcature-cli 2026.1.0

Developer lifecycle CLI for Arcature applications.
Documentation
use std::fmt;

use arcature_templates::TemplateError;

use crate::process::ProcessError;
use crate::project::ProjectError;
use crate::script::ScriptError;
use crate::tool::ToolError;

#[derive(Debug)]
pub(crate) enum CommandError {
    Generation(TemplateError),
    Process(ProcessError),
    Project(ProjectError),
    Script(ScriptError),
    Tool(ToolError),
    Report(serde_json::Error),
    Contract(String),
    Metadata(String),
    Unhealthy(&'static str),
    Db(crate::error::DbCommandError),
}

impl fmt::Display for CommandError {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Generation(error) => error.fmt(formatter),
            Self::Process(error) => error.fmt(formatter),
            Self::Project(error) => error.fmt(formatter),
            Self::Script(error) => error.fmt(formatter),
            Self::Tool(error) => error.fmt(formatter),
            Self::Report(error) => write!(formatter, "cannot serialize health report: {error}"),
            Self::Contract(error) => write!(formatter, "Cross-Stack Linker failed: {error}"),
            Self::Metadata(error) => {
                write!(formatter, "application metadata inspection failed: {error}")
            }
            Self::Unhealthy(scope) => write!(formatter, "{scope} checks reported errors"),
            Self::Db(error) => error.fmt(formatter),
        }
    }
}

impl std::error::Error for CommandError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            Self::Generation(error) => Some(error),
            Self::Process(error) => Some(error),
            Self::Project(error) => Some(error),
            Self::Script(error) => Some(error),
            Self::Tool(error) => Some(error),
            Self::Report(error) => Some(error),
            Self::Contract(_) => None,
            Self::Metadata(_) => None,
            Self::Unhealthy(_) => None,
            Self::Db(error) => Some(error),
        }
    }
}

impl From<TemplateError> for CommandError {
    fn from(value: TemplateError) -> Self {
        Self::Generation(value)
    }
}
impl From<ProcessError> for CommandError {
    fn from(value: ProcessError) -> Self {
        Self::Process(value)
    }
}
impl From<ProjectError> for CommandError {
    fn from(value: ProjectError) -> Self {
        Self::Project(value)
    }
}
impl From<ScriptError> for CommandError {
    fn from(value: ScriptError) -> Self {
        Self::Script(value)
    }
}
impl From<ToolError> for CommandError {
    fn from(value: ToolError) -> Self {
        Self::Tool(value)
    }
}
impl From<serde_json::Error> for CommandError {
    fn from(value: serde_json::Error) -> Self {
        Self::Report(value)
    }
}
impl From<crate::error::DbCommandError> for CommandError {
    fn from(value: crate::error::DbCommandError) -> Self {
        Self::Db(value)
    }
}