use thiserror::Error;
pub type DecisionResult<T> = Result<T, DecisionError>;
#[derive(Error, Debug, Clone, PartialEq)]
pub enum DecisionError {
#[error("Strategy not found: {0}")]
StrategyNotFound(String),
#[error("Invalid decision criteria: {0}")]
InvalidCriteria(String),
#[error("Decision validation failed: {0}")]
ValidationFailed(String),
#[error("Insufficient data: {0}")]
InsufficientData(String),
#[error("Constraint violation: {0}")]
ConstraintViolation(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Execution error: {0}")]
ExecutionError(String),
#[error("Rollback failed: {0}")]
RollbackFailed(String),
#[error("Strategy conflict: {0}")]
StrategyConflict(String),
#[error("Decision timeout after {0}ms")]
Timeout(u64),
#[error("Decision engine is not running")]
NotRunning,
#[error("Invalid state transition from {from:?} to {to:?}")]
InvalidStateTransition {
from: DecisionState,
to: DecisionState,
},
#[error("Internal error: {0}")]
Internal(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DecisionState {
Initialized,
Starting,
Running,
Draining,
Stopped,
Failed,
}
impl DecisionState {
pub fn can_process(&self) -> bool {
matches!(self, DecisionState::Running)
}
pub fn can_transition_to(&self, to: DecisionState) -> bool {
use DecisionState::*;
matches!(
(self, to),
(Initialized, Starting)
| (Starting, Running)
| (Starting, Failed)
| (Running, Draining)
| (Running, Failed)
| (Draining, Stopped)
| (Draining, Failed)
| (Failed, Initialized)
)
}
}