#![allow(missing_docs)]
use crate::boundary::BoundaryError;
use soma_som_core::error::SomaError;
use soma_som_core::extension::GateRejection;
use soma_som_core::types::UnitId;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum RingEngineError {
#[error("Ring engine not initialized — run genesis first")]
NotInitialized,
#[error("Genesis already completed — ring is in standard operation")]
GenesisAlreadyComplete,
#[error("Unit {unit} processing failed: {reason}")]
ProcessorFailed { unit: UnitId, reason: String },
#[error("Unit {unit} is disabled — no processor registered")]
UnitDisabled { unit: UnitId },
#[error("Cycle rejected by BEFORE gate: {0}")]
GateRejected(#[from] GateRejection),
#[error("Boundary error: {0}")]
Boundary(#[from] BoundaryError),
#[error("Core error: {0}")]
Core(#[from] SomaError),
#[error("Cycle {cycle_index} failed: {reason}")]
CycleFailed { cycle_index: u64, reason: String },
}
pub type RingEngineResult<T> = Result<T, RingEngineError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn error_display_not_initialized() {
let e = RingEngineError::NotInitialized;
assert!(e.to_string().contains("not initialized"));
}
#[test]
fn error_display_processor_failed() {
let e = RingEngineError::ProcessorFailed {
unit: UnitId::FU,
reason: "timeout".into(),
};
assert!(e.to_string().contains("FU"));
assert!(e.to_string().contains("timeout"));
}
#[test]
fn error_display_unit_disabled() {
let e = RingEngineError::UnitDisabled { unit: UnitId::CU };
assert!(e.to_string().contains("CU"));
assert!(e.to_string().contains("disabled"));
}
#[test]
fn error_display_gate_rejected() {
let rejection = GateRejection {
source: "guard".into(),
reason: "rate limit".into(),
};
let e = RingEngineError::GateRejected(rejection);
assert!(e.to_string().contains("guard"));
}
#[test]
fn error_display_cycle_failed() {
let e = RingEngineError::CycleFailed {
cycle_index: 42,
reason: "integrity".into(),
};
assert!(e.to_string().contains("42"));
}
}